Android8.0 Audio系统之AudioPolicy
void AudioPolicyService::onFirstRef()
{
{
......
// class AudioPolicyClient : public AudioPolicyClientInterface
mAudioPolicyClient = new AudioPolicyClient(this);
mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient); //创建Audio管理
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
头文件 AudioPolicyClientInterface 位于 AudioPolicyInterface.h文件中
extern "C" AudioPolicyInterface* createAudioPolicyManager(
AudioPolicyClientInterface *clientInterface)
{
return new AudioPolicyManager(clientInterface);
}
extern “C” void destroyAudioPolicyManager(AudioPolicyInterface *interface)
{
delete interface;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
对于AudioPolicyClientImpl.cpp实现了 AudioPolicyClient,直接与AudioFlinger交互。对于AudioPolicyIntefaceImpl实现了AudioPolicyInterface直接与AudioPolicyManager交互,
AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface) : #ifdef AUDIO_POLICY_TEST Thread(false), #endif //AUDIO_POLICY_TEST mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f), mA2dpSuspended(false), mAudioPortGeneration(1), mBeaconMuteRefCount(0), mBeaconPlayingRefCount(0), mBeaconMuted(false), mTtsOutputAvailable(false), mMasterMono(false), mMusicEffectOutput(AUDIO_IO_HANDLE_NONE) { mpClientInterface = clientInterface; bool speakerDrcEnabled = false; //解析 xml Audio策略,路由 #ifdef USE_XML_AUDIO_POLICY_CONF mVolumeCurves = new VolumeCurvesCollection(); AudioPolicyConfig config(mHwModules, mAvailableOutputDevices, mAvailableInputDevices, mDefaultOutputDevice, speakerDrcEnabled, static_cast<VolumeCurvesCollection *>(mVolumeCurves)); if (deserializeAudioPolicyXmlConfig(config) != NO_ERROR) { #else mVolumeCurves = new StreamDescriptorCollection(); AudioPolicyConfig config(mHwModules, mAvailableOutputDevices, mAvailableInputDevices, mDefaultOutputDevice, speakerDrcEnabled); if ((ConfigParsingUtils::loadConfig(AUDIO_POLICY_VENDOR_CONFIG_FILE, config) != NO_ERROR) && (ConfigParsingUtils::loadConfig(AUDIO_POLICY_CONFIG_FILE, config) != NO_ERROR)) { #endif ALOGE("could not load audio policy configuration file, setting defaults"); config.setDefault(); } // must be done after reading the policy (since conditionned by Speaker Drc Enabling) mVolumeCurves->initializeVolumeCurves(speakerDrcEnabled);
<span class="token comment">// Once policy config has been parsed, retrieve an instance of the engine and initialize it</span> <span class="token comment">//代理引擎</span> audio_policy<span class="token punctuation">:</span><span class="token punctuation">:</span>EngineInstance <span class="token operator">*</span>engineInstance <span class="token operator">=</span> audio_policy<span class="token punctuation">:</span><span class="token punctuation">:</span>EngineInstance<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">getInstance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>engineInstance<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">ALOGE</span><span class="token punctuation">(</span><span class="token string">"%s: Could not get an instance of policy engine"</span><span class="token punctuation">,</span> __FUNCTION__<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Retrieve the Policy Manager Interface</span> mEngine <span class="token operator">=</span> engineInstance<span class="token operator">-></span>queryInterface<span class="token operator"><</span>AudioPolicyManagerInterface<span class="token operator">></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//获取引擎</span> mEngine<span class="token operator">-></span><span class="token function">setObserver</span><span class="token punctuation">(</span>this<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//设为观察者</span> status_t status <span class="token operator">=</span> mEngine<span class="token operator">-></span><span class="token function">initCheck</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//初始</span> <span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span> status<span class="token punctuation">;</span> <span class="token comment">// mAvailableOutputDevices and mAvailableInputDevices now contain all attached devices</span> <span class="token comment">// open all output streams needed to access attached devices</span> audio_devices_t outputDeviceTypes <span class="token operator">=</span> mAvailableOutputDevices<span class="token punctuation">.</span><span class="token function">types</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> audio_devices_t inputDeviceTypes <span class="token operator">=</span> mAvailableInputDevices<span class="token punctuation">.</span><span class="token function">types</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&</span> <span class="token operator">~</span>AUDIO_DEVICE_BIT_IN<span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span>size_t i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> mHwModules<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">//调用ClientInterface加载Audio模块,ClientInterface将调用AudioFlinger的loadHwModule</span> mHwModules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-></span>mHandle <span class="token operator">=</span> mpClientInterface<span class="token operator">-></span><span class="token function">loadHwModule</span><span class="token punctuation">(</span>mHwModules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-></span><span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>mHwModules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-></span>mHandle <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">ALOGW</span><span class="token punctuation">(</span><span class="token string">"could not open HW module %s"</span><span class="token punctuation">,</span> mHwModules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-></span><span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">continue</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">//查找输出模块设备</span> <span class="token keyword">for</span> <span class="token punctuation">(</span>size_t j <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> j <span class="token operator"><</span> mHwModules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-></span>mOutputProfiles<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> j<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> sp<span class="token operator"><</span>IOProfile<span class="token operator">></span> outProfile <span class="token operator">=</span> mHwModules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-></span>mOutputProfiles<span class="token punctuation">[</span>j<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>outProfile<span class="token operator">-></span><span class="token function">hasSupportedDevices</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">ALOGW</span><span class="token punctuation">(</span><span class="token string">"Output profile contains no device on module %s"</span><span class="token punctuation">,</span> mHwModules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-></span><span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">continue</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>outProfile<span class="token operator">-></span><span class="token function">getFlags</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&</span> AUDIO_OUTPUT_FLAG_TTS<span class="token punctuation">)</span> <span class="token operator">!=</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> mTtsOutputAvailable <span class="token operator">=</span> true<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>outProfile<span class="token operator">-></span><span class="token function">getFlags</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&</span> AUDIO_OUTPUT_FLAG_DIRECT<span class="token punctuation">)</span> <span class="token operator">!=</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">continue</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> audio_devices_t profileType <span class="token operator">=</span> outProfile<span class="token operator">-></span><span class="token function">getSupportedDevicesType</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>profileType <span class="token operator">&</span> mDefaultOutputDevice<span class="token operator">-></span><span class="token function">type</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">!=</span> AUDIO_DEVICE_NONE<span class="token punctuation">)</span> <span class="token punctuation">{</span> profileType <span class="token operator">=</span> mDefaultOutputDevice<span class="token operator">-></span><span class="token function">type</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> profileType <span class="token operator">=</span> outProfile<span class="token operator">-></span><span class="token function">getSupportedDeviceForType</span><span class="token punctuation">(</span>outputDeviceTypes<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>profileType <span class="token operator">&</span> outputDeviceTypes<span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">continue</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> sp<span class="token operator"><</span>SwAudioOutputDescriptor<span class="token operator">></span> outputDesc <span class="token operator">=</span> new <span class="token function">SwAudioOutputDescriptor</span><span class="token punctuation">(</span>outProfile<span class="token punctuation">,</span> mpClientInterface<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> DeviceVector <span class="token operator">&</span>supportedDevices <span class="token operator">=</span> outProfile<span class="token operator">-></span><span class="token function">getSupportedDevices</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> DeviceVector <span class="token operator">&</span>devicesForType <span class="token operator">=</span> supportedDevices<span class="token punctuation">.</span><span class="token function">getDevicesFromType</span><span class="token punctuation">(</span>profileType<span class="token punctuation">)</span><span class="token punctuation">;</span> String8 address <span class="token operator">=</span> devicesForType<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">></span> <span class="token number">0</span> <span class="token operator">?</span> devicesForType<span class="token punctuation">.</span><span class="token function">itemAt</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token operator">-></span>mAddress <span class="token punctuation">:</span> <span class="token function">String8</span><span class="token punctuation">(</span><span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">;</span> outputDesc<span class="token operator">-></span>mDevice <span class="token operator">=</span> profileType<span class="token punctuation">;</span> audio_config_t config <span class="token operator">=</span> AUDIO_CONFIG_INITIALIZER<span class="token punctuation">;</span> config<span class="token punctuation">.</span>sample_rate <span class="token operator">=</span> outputDesc<span class="token operator">-></span>mSamplingRate<span class="token punctuation">;</span> config<span class="token punctuation">.</span>channel_mask <span class="token operator">=</span> outputDesc<span class="token operator">-></span>mChannelMask<span class="token punctuation">;</span> config<span class="token punctuation">.</span>format <span class="token operator">=</span> outputDesc<span class="token operator">-></span>mFormat<span class="token punctuation">;</span> audio_io_handle_t output <span class="token operator">=</span> AUDIO_IO_HANDLE_NONE<span class="token punctuation">;</span> <span class="token comment">//熟悉的openOutput</span> status_t status <span class="token operator">=</span> mpClientInterface<span class="token operator">-></span><span class="token function">openOutput</span><span class="token punctuation">(</span>outProfile<span class="token operator">-></span><span class="token function">getModuleHandle</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token operator">&</span>output<span class="token punctuation">,</span> <span class="token operator">&</span>config<span class="token punctuation">,</span> <span class="token operator">&</span>outputDesc<span class="token operator">-></span>mDevice<span class="token punctuation">,</span> address<span class="token punctuation">,</span> <span class="token operator">&</span>outputDesc<span class="token operator">-></span>mLatency<span class="token punctuation">,</span> outputDesc<span class="token operator">-></span>mFlags<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>status <span class="token operator">!=</span> NO_ERROR<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">ALOGW</span><span class="token punctuation">(</span><span class="token string">"Cannot open output stream for device %08x on hw module %s"</span><span class="token punctuation">,</span> outputDesc<span class="token operator">-></span>mDevice<span class="token punctuation">,</span> mHwModules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-></span><span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> outputDesc<span class="token operator">-></span>mSamplingRate <span class="token operator">=</span> config<span class="token punctuation">.</span>sample_rate<span class="token punctuation">;</span> outputDesc<span class="token operator">-></span>mChannelMask <span class="token operator">=</span> config<span class="token punctuation">.</span>channel_mask<span class="token punctuation">;</span> outputDesc<span class="token operator">-></span>mFormat <span class="token operator">=</span> config<span class="token punctuation">.</span>format<span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span>size_t k <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> k <span class="token operator"><</span> supportedDevices<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> k<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> ssize_t index <span class="token operator">=</span> mAvailableOutputDevices<span class="token punctuation">.</span><span class="token function">indexOf</span><span class="token punctuation">(</span>supportedDevices<span class="token punctuation">[</span>k<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// give a valid ID to an attached device once confirmed it is reachable</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>index <span class="token operator">>=</span> <span class="token number">0</span> <span class="token operator">&&</span> <span class="token operator">!</span>mAvailableOutputDevices<span class="token punctuation">[</span>index<span class="token punctuation">]</span><span class="token operator">-></span><span class="token function">isAttached</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> mAvailableOutputDevices<span class="token punctuation">[</span>index<span class="token punctuation">]</span><span class="token operator">-></span><span class="token function">attach</span><span class="token punctuation">(</span>mHwModules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>mPrimaryOutput <span class="token operator">==</span> <span class="token number">0</span> <span class="token operator">&&</span> outProfile<span class="token operator">-></span><span class="token function">getFlags</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&</span> AUDIO_OUTPUT_FLAG_PRIMARY<span class="token punctuation">)</span> <span class="token punctuation">{</span> mPrimaryOutput <span class="token operator">=</span> outputDesc<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">addOutput</span><span class="token punctuation">(</span>output<span class="token punctuation">,</span> outputDesc<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">setOutputDevice</span><span class="token punctuation">(</span>outputDesc<span class="token punctuation">,</span> outputDesc<span class="token operator">-></span>mDevice<span class="token punctuation">,</span> true<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">,</span> address<span class="token punctuation">.</span><span class="token function">string</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">//遍历输入Audio设备</span> <span class="token keyword">for</span> <span class="token punctuation">(</span>size_t j <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> j <span class="token operator"><</span> mHwModules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-></span>mInputProfiles<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> j<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> sp<span class="token operator"><</span>IOProfile<span class="token operator">></span> inProfile <span class="token operator">=</span> mHwModules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-></span>mInputProfiles<span class="token punctuation">[</span>j<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>inProfile<span class="token operator">-></span><span class="token function">hasSupportedDevices</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">ALOGW</span><span class="token punctuation">(</span><span class="token string">"Input profile contains no device on module %s"</span><span class="token punctuation">,</span> mHwModules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-></span><span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">continue</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// chose first device present in profile's SupportedDevices also part of</span> <span class="token comment">// inputDeviceTypes</span> audio_devices_t profileType <span class="token operator">=</span> inProfile<span class="token operator">-></span><span class="token function">getSupportedDeviceForType</span><span class="token punctuation">(</span>inputDeviceTypes<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>profileType <span class="token operator">&</span> inputDeviceTypes<span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">continue</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> sp<span class="token operator"><</span>AudioInputDescriptor<span class="token operator">></span> inputDesc <span class="token operator">=</span> new <span class="token function">AudioInputDescriptor</span><span class="token punctuation">(</span>inProfile<span class="token punctuation">)</span><span class="token punctuation">;</span> inputDesc<span class="token operator">-></span>mDevice <span class="token operator">=</span> profileType<span class="token punctuation">;</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> audio_config_t config <span class="token operator">=</span> AUDIO_CONFIG_INITIALIZER<span class="token punctuation">;</span> config<span class="token punctuation">.</span>sample_rate <span class="token operator">=</span> inputDesc<span class="token operator">-></span>mSamplingRate<span class="token punctuation">;</span> config<span class="token punctuation">.</span>channel_mask <span class="token operator">=</span> inputDesc<span class="token operator">-></span>mChannelMask<span class="token punctuation">;</span> config<span class="token punctuation">.</span>format <span class="token operator">=</span> inputDesc<span class="token operator">-></span>mFormat<span class="token punctuation">;</span> audio_io_handle_t input <span class="token operator">=</span> AUDIO_IO_HANDLE_NONE<span class="token punctuation">;</span> status_t status <span class="token operator">=</span> mpClientInterface<span class="token operator">-></span><span class="token function">openInput</span><span class="token punctuation">(</span>inProfile<span class="token operator">-></span><span class="token function">getModuleHandle</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token operator">&</span>input<span class="token punctuation">,</span> <span class="token operator">&</span>config<span class="token punctuation">,</span> <span class="token operator">&</span>inputDesc<span class="token operator">-></span>mDevice<span class="token punctuation">,</span> address<span class="token punctuation">,</span> AUDIO_SOURCE_MIC<span class="token punctuation">,</span> AUDIO_INPUT_FLAG_NONE<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>status <span class="token operator">==</span> NO_ERROR<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> DeviceVector <span class="token operator">&</span>supportedDevices <span class="token operator">=</span> inProfile<span class="token operator">-></span><span class="token function">getSupportedDevices</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span>size_t k <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> k <span class="token operator"><</span> supportedDevices<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> k<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> ssize_t index <span class="token operator">=</span> mAvailableInputDevices<span class="token punctuation">.</span><span class="token function">indexOf</span><span class="token punctuation">(</span>supportedDevices<span class="token punctuation">[</span>k<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// give a valid ID to an attached device once confirmed it is reachable</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>index <span class="token operator">>=</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> sp<span class="token operator"><</span>DeviceDescriptor<span class="token operator">></span> devDesc <span class="token operator">=</span> mAvailableInputDevices<span class="token punctuation">[</span>index<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>devDesc<span class="token operator">-></span><span class="token function">isAttached</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> devDesc<span class="token operator">-></span><span class="token function">attach</span><span class="token punctuation">(</span>mHwModules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> devDesc<span class="token operator">-></span><span class="token function">importAudioPort</span><span class="token punctuation">(</span>inProfile<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> mpClientInterface<span class="token operator">-></span><span class="token function">closeInput</span><span class="token punctuation">(</span>input<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">// make sure all attached devices have been allocated a unique ID</span> <span class="token comment">//遍历输入输出设备,由路由引擎设置各设备的连接状态</span> <span class="token keyword">for</span> <span class="token punctuation">(</span>size_t i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> mAvailableOutputDevices<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>mAvailableOutputDevices<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-></span><span class="token function">isAttached</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> mAvailableOutputDevices<span class="token punctuation">.</span><span class="token function">remove</span><span class="token punctuation">(</span>mAvailableOutputDevices<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">continue</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// The device is now validated and can be appended to the available devices of the engine</span> mEngine<span class="token operator">-></span><span class="token function">setDeviceConnectionState</span><span class="token punctuation">(</span>mAvailableOutputDevices<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">,</span> AUDIO_POLICY_DEVICE_STATE_AVAILABLE<span class="token punctuation">)</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">for</span> <span class="token punctuation">(</span>size_t i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> mAvailableInputDevices<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>mAvailableInputDevices<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-></span><span class="token function">isAttached</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">;</span> mAvailableInputDevices<span class="token punctuation">.</span><span class="token function">remove</span><span class="token punctuation">(</span>mAvailableInputDevices<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">continue</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// The device is now validated and can be appended to the available devices of the engine</span> mEngine<span class="token operator">-></span><span class="token function">setDeviceConnectionState</span><span class="token punctuation">(</span>mAvailableInputDevices<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">,</span> AUDIO_POLICY_DEVICE_STATE_AVAILABLE<span class="token punctuation">)</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">updateDevicesAndOutputs</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
可以看到AudioPolicyManager通过解析Audio配置文件,加载各输入输出音频Module,然后遍历各输入输出设备,找出稳定的设备后,由路由引擎设置各设备的连接状态。在分析AudioFlinger的时候走过 mpClientInterface->openOutput()函数
sp<AudioFlinger::ThreadBase> AudioFlinger::openOutput_l(.....) { //找到Device, 这个函数很重要,稍后分析 AudioHwDevice *outHwDev = findSuitableHwDev_l(module, devices); //音频流输出到硬件设备 AudioStreamOut *outputStream = NULL; status_t status = outHwDev->openOutputStream( &outputStream, *output, devices, flags, config, address.string());
mHardwareStatus <span class="token operator">=</span> AUDIO_HW_IDLE<span class="token punctuation">;</span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
在 createTrack_l()的时候,会去根据流类型来获取路由策略
uint32_t strategy = AudioSystem::getStrategyForStream(streamType);
for (size_t i = 0; i < mTracks.size(); ++i) {
sp<Track> t = mTracks[i];
if (t != 0 && t->isExternalTrack()) {
//获取路由策略
uint32_t actual = AudioSystem::getStrategyForStream(t->streamType());
if (sessionId == t->sessionId() && strategy != actual) {
ALOGE("createTrack_l() mismatched strategy; expected %u but found %u",
strategy, actual);
lStatus = BAD_VALUE;
goto Exit;
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
调用 Audio代理服务的 getStrategyForStream
uint32_t AudioSystem::getStrategyForStream(audio_stream_type_t stream)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return 0;
return aps->getStrategyForStream(stream);
}
- 1
- 2
- 3
- 4
- 5
- 6
具体的实现在AudioPolicyInterfaceImpl.cpp文件中
\frameworks\av\services\audiopolicy\service\AudioPolicyInterfaceImpl.cpp
uint32_t AudioPolicyService::getStrategyForStream(audio_stream_type_t stream)
{
if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {
return 0;
}
if (mAudioPolicyManager == NULL) {
return 0;
}
return mAudioPolicyManager->getStrategyForStream(stream);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
uint32_t AudioPolicyManager::getStrategyForStream(audio_stream_type_t stream) {
return (uint32_t)getStrategy(stream);
}
- 1
- 2
- 3
routing_strategy AudioPolicyManager::getStrategy(audio_stream_type_t stream) const
{
ALOG_ASSERT(stream != AUDIO_STREAM_PATCH,"getStrategy() called for AUDIO_STREAM_PATCH");
return mEngine->getStrategyForStream(stream);
}
- 1
- 2
- 3
- 4
- 5
- 6
在文件 frameworks\av\services\audiopolicy\managerdefault\AudioPolicyManager.h 中 AudioPolicyManagerInterface *mEngine; 位于frameworks\av\services\audiopolicy\engine\interface\AudioPolicyManagerInterface.h,在frameworks\av\services\audiopolicy\enginedefault\src\Engine.h文件中被实现如下
/// Interface members class ManagerInterfaceImpl : public AudioPolicyManagerInterface { public: explicit ManagerInterfaceImpl(Engine *policyEngine) : mPolicyEngine(policyEngine) {}
<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> virtual routing_strategy <span class="token function">getStrategyForStream</span><span class="token punctuation">(</span>audio_stream_type_t stream<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> mPolicyEngine<span class="token operator">-></span><span class="token function">getStrategyForStream</span><span class="token punctuation">(</span>stream<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> private<span class="token punctuation">:</span> Engine <span class="token operator">*</span>mPolicyEngine<span class="token punctuation">;</span> <span class="token punctuation">}</span> mManagerInterface<span class="token punctuation">;</span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
最终将调用Engine.cpp的getStrategyForStream查询音频路由策略
routing_strategy Engine::getStrategyForStream(audio_stream_type_t stream)
{
// stream to strategy mapping
switch (stream) {
case AUDIO_STREAM_VOICE_CALL:
case AUDIO_STREAM_BLUETOOTH_SCO:
return STRATEGY_PHONE;
case AUDIO_STREAM_RING:
case AUDIO_STREAM_ALARM:
return STRATEGY_SONIFICATION;
case AUDIO_STREAM_NOTIFICATION:
return STRATEGY_SONIFICATION_RESPECTFUL;
case AUDIO_STREAM_DTMF:
return STRATEGY_DTMF;
default:
ALOGE("unknown stream type %d", stream);
case AUDIO_STREAM_SYSTEM:
// NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs
// while key clicks are played produces a poor result
case AUDIO_STREAM_MUSIC:
return STRATEGY_MEDIA;
case AUDIO_STREAM_ENFORCED_AUDIBLE:
return STRATEGY_ENFORCED_AUDIBLE;
case AUDIO_STREAM_TTS:
return STRATEGY_TRANSMITTED_THROUGH_SPEAKER;
case AUDIO_STREAM_ACCESSIBILITY:
return STRATEGY_ACCESSIBILITY;
case AUDIO_STREAM_REROUTING:
return STRATEGY_REROUTING;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
在AudioPolicyService.h文件中定义了如下函数,用来处理设备改变时调整路由策略
virtual status_t handleDeviceConfigChange(audio_devices_t device,
const char *device_address,
const char *device_name);
- 1
- 2
- 3
至此音频代理路由部分暂到这,目前所看到的只是一小部分,随着Android系统的日益复杂,Audio会变得越来越庞大;
不过万变不离其宗,只要大体架构上不做大改动,也是很容易分析的,下一篇我们来看Audio系统的硬件抽象层。
</div>
<link href="https://csdnimg.cn/release/phoenix/mdeditor/markdown_views-258a4616f7.css" rel="stylesheet">
</div>
</article>
Android8.0 Audio系统之AudioPolicy
void AudioPolicyService::onFirstRef()
{
{
......
// class AudioPolicyClient : public AudioPolicyClientInterface
mAudioPolicyClient = new AudioPolicyClient(this);
mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient); //创建Audio管理
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
头文件 AudioPolicyClientInterface 位于 AudioPolicyInterface.h文件中
extern "C" AudioPolicyInterface* createAudioPolicyManager(
AudioPolicyClientInterface *clientInterface)
{
return new AudioPolicyManager(clientInterface);
}
extern “C” void destroyAudioPolicyManager(AudioPolicyInterface *interface)
{
delete interface;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
对于AudioPolicyClientImpl.cpp实现了 AudioPolicyClient,直接与AudioFlinger交互。对于AudioPolicyIntefaceImpl实现了AudioPolicyInterface直接与AudioPolicyManager交互,
AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface) : #ifdef AUDIO_POLICY_TEST Thread(false), #endif //AUDIO_POLICY_TEST mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f), mA2dpSuspended(false), mAudioPortGeneration(1), mBeaconMuteRefCount(0), mBeaconPlayingRefCount(0), mBeaconMuted(false), mTtsOutputAvailable(false), mMasterMono(false), mMusicEffectOutput(AUDIO_IO_HANDLE_NONE) { mpClientInterface = clientInterface; bool speakerDrcEnabled = false; //解析 xml Audio策略,路由 #ifdef USE_XML_AUDIO_POLICY_CONF mVolumeCurves = new VolumeCurvesCollection(); AudioPolicyConfig config(mHwModules, mAvailableOutputDevices, mAvailableInputDevices, mDefaultOutputDevice, speakerDrcEnabled, static_cast<VolumeCurvesCollection *>(mVolumeCurves)); if (deserializeAudioPolicyXmlConfig(config) != NO_ERROR) { #else mVolumeCurves = new StreamDescriptorCollection(); AudioPolicyConfig config(mHwModules, mAvailableOutputDevices, mAvailableInputDevices, mDefaultOutputDevice, speakerDrcEnabled); if ((ConfigParsingUtils::loadConfig(AUDIO_POLICY_VENDOR_CONFIG_FILE, config) != NO_ERROR) && (ConfigParsingUtils::loadConfig(AUDIO_POLICY_CONFIG_FILE, config) != NO_ERROR)) { #endif ALOGE("could not load audio policy configuration file, setting defaults"); config.setDefault(); } // must be done after reading the policy (since conditionned by Speaker Drc Enabling) mVolumeCurves->initializeVolumeCurves(speakerDrcEnabled);
<span class="token comment">// Once policy config has been parsed, retrieve an instance of the engine and initialize it</span> <span class="token comment">//代理引擎</span> audio_policy<span class="token punctuation">:</span><span class="token punctuation">:</span>EngineInstance <span class="token operator">*</span>engineInstance <span class="token operator">=</span> audio_policy<span class="token punctuation">:</span><span class="token punctuation">:</span>EngineInstance<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">getInstance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>engineInstance<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">ALOGE</span><span class="token punctuation">(</span><span class="token string">"%s: Could not get an instance of policy engine"</span><span class="token punctuation">,</span> __FUNCTION__<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Retrieve the Policy Manager Interface</span> mEngine <span class="token operator">=</span> engineInstance<span class="token operator">-></span>queryInterface<span class="token operator"><</span>AudioPolicyManagerInterface<span class="token operator">></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//获取引擎</span> mEngine<span class="token operator">-></span><span class="token function">setObserver</span><span class="token punctuation">(</span>this<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//设为观察者</span> status_t status <span class="token operator">=</span> mEngine<span class="token operator">-></span><span class="token function">initCheck</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//初始</span> <span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span> status<span class="token punctuation">;</span> <span class="token comment">// mAvailableOutputDevices and mAvailableInputDevices now contain all attached devices</span> <span class="token comment">// open all output streams needed to access attached devices</span> audio_devices_t outputDeviceTypes <span class="token operator">=</span> mAvailableOutputDevices<span class="token punctuation">.</span><span class="token function">types</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> audio_devices_t inputDeviceTypes <span class="token operator">=</span> mAvailableInputDevices<span class="token punctuation">.</span><span class="token function">types</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&</span> <span class="token operator">~</span>AUDIO_DEVICE_BIT_IN<span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span>size_t i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> mHwModules<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">//调用ClientInterface加载Audio模块,ClientInterface将调用AudioFlinger的loadHwModule</span> mHwModules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-></span>mHandle <span class="token operator">=</span> mpClientInterface<span class="token operator">-></span><span class="token function">loadHwModule</span><span class="token punctuation">(</span>mHwModules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-></span><span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>mHwModules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-></span>mHandle <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">ALOGW</span><span class="token punctuation">(</span><span class="token string">"could not open HW module %s"</span><span class="token punctuation">,</span> mHwModules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-></span><span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">continue</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">//查找输出模块设备</span> <span class="token keyword">for</span> <span class="token punctuation">(</span>size_t j <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> j <span class="token operator"><</span> mHwModules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-></span>mOutputProfiles<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> j<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> sp<span class="token operator"><</span>IOProfile<span class="token operator">></span> outProfile <span class="token operator">=</span> mHwModules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-></span>mOutputProfiles<span class="token punctuation">[</span>j<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>outProfile<span class="token operator">-></span><span class="token function">hasSupportedDevices</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">ALOGW</span><span class="token punctuation">(</span><span class="token string">"Output profile contains no device on module %s"</span><span class="token punctuation">,</span> mHwModules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-></span><span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">continue</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>outProfile<span class="token operator">-></span><span class="token function">getFlags</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&</span> AUDIO_OUTPUT_FLAG_TTS<span class="token punctuation">)</span> <span class="token operator">!=</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> mTtsOutputAvailable <span class="token operator">=</span> true<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>outProfile<span class="token operator">-></span><span class="token function">getFlags</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&</span> AUDIO_OUTPUT_FLAG_DIRECT<span class="token punctuation">)</span> <span class="token operator">!=</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">continue</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> audio_devices_t profileType <span class="token operator">=</span> outProfile<span class="token operator">-></span><span class="token function">getSupportedDevicesType</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>profileType <span class="token operator">&</span> mDefaultOutputDevice<span class="token operator">-></span><span class="token function">type</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">!=</span> AUDIO_DEVICE_NONE<span class="token punctuation">)</span> <span class="token punctuation">{</span> profileType <span class="token operator">=</span> mDefaultOutputDevice<span class="token operator">-></span><span class="token function">type</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> profileType <span class="token operator">=</span> outProfile<span class="token operator">-></span><span class="token function">getSupportedDeviceForType</span><span class="token punctuation">(</span>outputDeviceTypes<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>profileType <span class="token operator">&</span> outputDeviceTypes<span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">continue</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> sp<span class="token operator"><</span>SwAudioOutputDescriptor<span class="token operator">></span> outputDesc <span class="token operator">=</span> new <span class="token function">SwAudioOutputDescriptor</span><span class="token punctuation">(</span>outProfile<span class="token punctuation">,</span> mpClientInterface<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> DeviceVector <span class="token operator">&</span>supportedDevices <span class="token operator">=</span> outProfile<span class="token operator">-></span><span class="token function">getSupportedDevices</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> DeviceVector <span class="token operator">&</span>devicesForType <span class="token operator">=</span> supportedDevices<span class="token punctuation">.</span><span class="token function">getDevicesFromType</span><span class="token punctuation">(</span>profileType<span class="token punctuation">)</span><span class="token punctuation">;</span> String8 address <span class="token operator">=</span> devicesForType<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">></span> <span class="token number">0</span> <span class="token operator">?</span> devicesForType<span class="token punctuation">.</span><span class="token function">itemAt</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token operator">-></span>mAddress <span class="token punctuation">:</span> <span class="token function">String8</span><span class="token punctuation">(</span><span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">;</span> outputDesc<span class="token operator">-></span>mDevice <span class="token operator">=</span> profileType<span class="token punctuation">;</span> audio_config_t config <span class="token operator">=</span> AUDIO_CONFIG_INITIALIZER<span class="token punctuation">;</span> config<span class="token punctuation">.</span>sample_rate <span class="token operator">=</span> outputDesc<span class="token operator">-></span>mSamplingRate<span class="token punctuation">;</span> config<span class="token punctuation">.</span>channel_mask <span class="token operator">=</span> outputDesc<span class="token operator">-></span>mChannelMask<span class="token punctuation">;</span> config<span class="token punctuation">.</span>format <span class="token operator">=</span> outputDesc<span class="token operator">-></span>mFormat<span class="token punctuation">;</span> audio_io_handle_t output <span class="token operator">=</span> AUDIO_IO_HANDLE_NONE<span class="token punctuation">;</span> <span class="token comment">//熟悉的openOutput</span> status_t status <span class="token operator">=</span> mpClientInterface<span class="token operator">-></span><span class="token function">openOutput</span><span class="token punctuation">(</span>outProfile<span class="token operator">-></span><span class="token function">getModuleHandle</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token operator">&</span>output<span class="token punctuation">,</span> <span class="token operator">&</span>config<span class="token punctuation">,</span> <span class="token operator">&</span>outputDesc<span class="token operator">-></span>mDevice<span class="token punctuation">,</span> address<span class="token punctuation">,</span> <span class="token operator">&</span>outputDesc<span class="token operator">-></span>mLatency<span class="token punctuation">,</span> outputDesc<span class="token operator">-></span>mFlags<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>status <span class="token operator">!=</span> NO_ERROR<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">ALOGW</span><span class="token punctuation">(</span><span class="token string">"Cannot open output stream for device %08x on hw module %s"</span><span class="token punctuation">,</span> outputDesc<span class="token operator">-></span>mDevice<span class="token punctuation">,</span> mHwModules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-></span><span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> outputDesc<span class="token operator">-></span>mSamplingRate <span class="token operator">=</span> config<span class="token punctuation">.</span>sample_rate<span class="token punctuation">;</span> outputDesc<span class="token operator">-></span>mChannelMask <span class="token operator">=</span> config<span class="token punctuation">.</span>channel_mask<span class="token punctuation">;</span> outputDesc<span class="token operator">-></span>mFormat <span class="token operator">=</span> config<span class="token punctuation">.</span>format<span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span>size_t k <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> k <span class="token operator"><</span> supportedDevices<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> k<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> ssize_t index <span class="token operator">=</span> mAvailableOutputDevices<span class="token punctuation">.</span><span class="token function">indexOf</span><span class="token punctuation">(</span>supportedDevices<span class="token punctuation">[</span>k<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// give a valid ID to an attached device once confirmed it is reachable</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>index <span class="token operator">>=</span> <span class="token number">0</span> <span class="token operator">&&</span> <span class="token operator">!</span>mAvailableOutputDevices<span class="token punctuation">[</span>index<span class="token punctuation">]</span><span class="token operator">-></span><span class="token function">isAttached</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> mAvailableOutputDevices<span class="token punctuation">[</span>index<span class="token punctuation">]</span><span class="token operator">-></span><span class="token function">attach</span><span class="token punctuation">(</span>mHwModules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>mPrimaryOutput <span class="token operator">==</span> <span class="token number">0</span> <span class="token operator">&&</span> outProfile<span class="token operator">-></span><span class="token function">getFlags</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&</span> AUDIO_OUTPUT_FLAG_PRIMARY<span class="token punctuation">)</span> <span class="token punctuation">{</span> mPrimaryOutput <span class="token operator">=</span> outputDesc<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">addOutput</span><span class="token punctuation">(</span>output<span class="token punctuation">,</span> outputDesc<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">setOutputDevice</span><span class="token punctuation">(</span>outputDesc<span class="token punctuation">,</span> outputDesc<span class="token operator">-></span>mDevice<span class="token punctuation">,</span> true<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">,</span> address<span class="token punctuation">.</span><span class="token function">string</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">//遍历输入Audio设备</span> <span class="token keyword">for</span> <span class="token punctuation">(</span>size_t j <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> j <span class="token operator"><</span> mHwModules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-></span>mInputProfiles<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> j<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> sp<span class="token operator"><</span>IOProfile<span class="token operator">></span> inProfile <span class="token operator">=</span> mHwModules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-></span>mInputProfiles<span class="token punctuation">[</span>j<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>inProfile<span class="token operator">-></span><span class="token function">hasSupportedDevices</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">ALOGW</span><span class="token punctuation">(</span><span class="token string">"Input profile contains no device on module %s"</span><span class="token punctuation">,</span> mHwModules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-></span><span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">continue</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// chose first device present in profile's SupportedDevices also part of</span> <span class="token comment">// inputDeviceTypes</span> audio_devices_t profileType <span class="token operator">=</span> inProfile<span class="token operator">-></span><span class="token function">getSupportedDeviceForType</span><span class="token punctuation">(</span>inputDeviceTypes<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>profileType <span class="token operator">&</span> inputDeviceTypes<span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">continue</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> sp<span class="token operator"><</span>AudioInputDescriptor<span class="token operator">></span> inputDesc <span class="token operator">=</span> new <span class="token function">AudioInputDescriptor</span><span class="token punctuation">(</span>inProfile<span class="token punctuation">)</span><span class="token punctuation">;</span> inputDesc<span class="token operator">-></span>mDevice <span class="token operator">=</span> profileType<span class="token punctuation">;</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> audio_config_t config <span class="token operator">=</span> AUDIO_CONFIG_INITIALIZER<span class="token punctuation">;</span> config<span class="token punctuation">.</span>sample_rate <span class="token operator">=</span> inputDesc<span class="token operator">-></span>mSamplingRate<span class="token punctuation">;</span> config<span class="token punctuation">.</span>channel_mask <span class="token operator">=</span> inputDesc<span class="token operator">-></span>mChannelMask<span class="token punctuation">;</span> config<span class="token punctuation">.</span>format <span class="token operator">=</span> inputDesc<span class="token operator">-></span>mFormat<span class="token punctuation">;</span> audio_io_handle_t input <span class="token operator">=</span> AUDIO_IO_HANDLE_NONE<span class="token punctuation">;</span> status_t status <span class="token operator">=</span> mpClientInterface<span class="token operator">-></span><span class="token function">openInput</span><span class="token punctuation">(</span>inProfile<span class="token operator">-></span><span class="token function">getModuleHandle</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token operator">&</span>input<span class="token punctuation">,</span> <span class="token operator">&</span>config<span class="token punctuation">,</span> <span class="token operator">&</span>inputDesc<span class="token operator">-></span>mDevice<span class="token punctuation">,</span> address<span class="token punctuation">,</span> AUDIO_SOURCE_MIC<span class="token punctuation">,</span> AUDIO_INPUT_FLAG_NONE<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>status <span class="token operator">==</span> NO_ERROR<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> DeviceVector <span class="token operator">&</span>supportedDevices <span class="token operator">=</span> inProfile<span class="token operator">-></span><span class="token function">getSupportedDevices</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span>size_t k <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> k <span class="token operator"><</span> supportedDevices<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> k<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> ssize_t index <span class="token operator">=</span> mAvailableInputDevices<span class="token punctuation">.</span><span class="token function">indexOf</span><span class="token punctuation">(</span>supportedDevices<span class="token punctuation">[</span>k<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// give a valid ID to an attached device once confirmed it is reachable</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>index <span class="token operator">>=</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> sp<span class="token operator"><</span>DeviceDescriptor<span class="token operator">></span> devDesc <span class="token operator">=</span> mAvailableInputDevices<span class="token punctuation">[</span>index<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>devDesc<span class="token operator">-></span><span class="token function">isAttached</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> devDesc<span class="token operator">-></span><span class="token function">attach</span><span class="token punctuation">(</span>mHwModules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> devDesc<span class="token operator">-></span><span class="token function">importAudioPort</span><span class="token punctuation">(</span>inProfile<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> mpClientInterface<span class="token operator">-></span><span class="token function">closeInput</span><span class="token punctuation">(</span>input<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">// make sure all attached devices have been allocated a unique ID</span> <span class="token comment">//遍历输入输出设备,由路由引擎设置各设备的连接状态</span> <span class="token keyword">for</span> <span class="token punctuation">(</span>size_t i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> mAvailableOutputDevices<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>mAvailableOutputDevices<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-></span><span class="token function">isAttached</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> mAvailableOutputDevices<span class="token punctuation">.</span><span class="token function">remove</span><span class="token punctuation">(</span>mAvailableOutputDevices<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">continue</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// The device is now validated and can be appended to the available devices of the engine</span> mEngine<span class="token operator">-></span><span class="token function">setDeviceConnectionState</span><span class="token punctuation">(</span>mAvailableOutputDevices<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">,</span> AUDIO_POLICY_DEVICE_STATE_AVAILABLE<span class="token punctuation">)</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">for</span> <span class="token punctuation">(</span>size_t i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> mAvailableInputDevices<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>mAvailableInputDevices<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-></span><span class="token function">isAttached</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">;</span> mAvailableInputDevices<span class="token punctuation">.</span><span class="token function">remove</span><span class="token punctuation">(</span>mAvailableInputDevices<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">continue</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// The device is now validated and can be appended to the available devices of the engine</span> mEngine<span class="token operator">-></span><span class="token function">setDeviceConnectionState</span><span class="token punctuation">(</span>mAvailableInputDevices<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">,</span> AUDIO_POLICY_DEVICE_STATE_AVAILABLE<span class="token punctuation">)</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">updateDevicesAndOutputs</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
可以看到AudioPolicyManager通过解析Audio配置文件,加载各输入输出音频Module,然后遍历各输入输出设备,找出稳定的设备后,由路由引擎设置各设备的连接状态。在分析AudioFlinger的时候走过 mpClientInterface->openOutput()函数
sp<AudioFlinger::ThreadBase> AudioFlinger::openOutput_l(.....) { //找到Device, 这个函数很重要,稍后分析 AudioHwDevice *outHwDev = findSuitableHwDev_l(module, devices); //音频流输出到硬件设备 AudioStreamOut *outputStream = NULL; status_t status = outHwDev->openOutputStream( &outputStream, *output, devices, flags, config, address.string());
mHardwareStatus <span class="token operator">=</span> AUDIO_HW_IDLE<span class="token punctuation">;</span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
在 createTrack_l()的时候,会去根据流类型来获取路由策略
uint32_t strategy = AudioSystem::getStrategyForStream(streamType);
for (size_t i = 0; i < mTracks.size(); ++i) {
sp<Track> t = mTracks[i];
if (t != 0 && t->isExternalTrack()) {
//获取路由策略
uint32_t actual = AudioSystem::getStrategyForStream(t->streamType());
if (sessionId == t->sessionId() && strategy != actual) {
ALOGE("createTrack_l() mismatched strategy; expected %u but found %u",
strategy, actual);
lStatus = BAD_VALUE;
goto Exit;
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
调用 Audio代理服务的 getStrategyForStream
uint32_t AudioSystem::getStrategyForStream(audio_stream_type_t stream)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return 0;
return aps->getStrategyForStream(stream);
}
- 1
- 2
- 3
- 4
- 5
- 6
具体的实现在AudioPolicyInterfaceImpl.cpp文件中
\frameworks\av\services\audiopolicy\service\AudioPolicyInterfaceImpl.cpp
uint32_t AudioPolicyService::getStrategyForStream(audio_stream_type_t stream)
{
if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {
return 0;
}
if (mAudioPolicyManager == NULL) {
return 0;
}
return mAudioPolicyManager->getStrategyForStream(stream);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
uint32_t AudioPolicyManager::getStrategyForStream(audio_stream_type_t stream) {
return (uint32_t)getStrategy(stream);
}
- 1
- 2
- 3
routing_strategy AudioPolicyManager::getStrategy(audio_stream_type_t stream) const
{
ALOG_ASSERT(stream != AUDIO_STREAM_PATCH,"getStrategy() called for AUDIO_STREAM_PATCH");
return mEngine->getStrategyForStream(stream);
}
- 1
- 2
- 3
- 4
- 5
- 6
在文件 frameworks\av\services\audiopolicy\managerdefault\AudioPolicyManager.h 中 AudioPolicyManagerInterface *mEngine; 位于frameworks\av\services\audiopolicy\engine\interface\AudioPolicyManagerInterface.h,在frameworks\av\services\audiopolicy\enginedefault\src\Engine.h文件中被实现如下
/// Interface members class ManagerInterfaceImpl : public AudioPolicyManagerInterface { public: explicit ManagerInterfaceImpl(Engine *policyEngine) : mPolicyEngine(policyEngine) {}
<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> virtual routing_strategy <span class="token function">getStrategyForStream</span><span class="token punctuation">(</span>audio_stream_type_t stream<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> mPolicyEngine<span class="token operator">-></span><span class="token function">getStrategyForStream</span><span class="token punctuation">(</span>stream<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> private<span class="token punctuation">:</span> Engine <span class="token operator">*</span>mPolicyEngine<span class="token punctuation">;</span> <span class="token punctuation">}</span> mManagerInterface<span class="token punctuation">;</span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
最终将调用Engine.cpp的getStrategyForStream查询音频路由策略
routing_strategy Engine::getStrategyForStream(audio_stream_type_t stream)
{
// stream to strategy mapping
switch (stream) {
case AUDIO_STREAM_VOICE_CALL:
case AUDIO_STREAM_BLUETOOTH_SCO:
return STRATEGY_PHONE;
case AUDIO_STREAM_RING:
case AUDIO_STREAM_ALARM:
return STRATEGY_SONIFICATION;
case AUDIO_STREAM_NOTIFICATION:
return STRATEGY_SONIFICATION_RESPECTFUL;
case AUDIO_STREAM_DTMF:
return STRATEGY_DTMF;
default:
ALOGE("unknown stream type %d", stream);
case AUDIO_STREAM_SYSTEM:
// NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs
// while key clicks are played produces a poor result
case AUDIO_STREAM_MUSIC:
return STRATEGY_MEDIA;
case AUDIO_STREAM_ENFORCED_AUDIBLE:
return STRATEGY_ENFORCED_AUDIBLE;
case AUDIO_STREAM_TTS:
return STRATEGY_TRANSMITTED_THROUGH_SPEAKER;
case AUDIO_STREAM_ACCESSIBILITY:
return STRATEGY_ACCESSIBILITY;
case AUDIO_STREAM_REROUTING:
return STRATEGY_REROUTING;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
在AudioPolicyService.h文件中定义了如下函数,用来处理设备改变时调整路由策略
virtual status_t handleDeviceConfigChange(audio_devices_t device,
const char *device_address,
const char *device_name);
- 1
- 2
- 3
至此音频代理路由部分暂到这,目前所看到的只是一小部分,随着Android系统的日益复杂,Audio会变得越来越庞大;
不过万变不离其宗,只要大体架构上不做大改动,也是很容易分析的,下一篇我们来看Audio系统的硬件抽象层。
</div>
<link href="https://csdnimg.cn/release/phoenix/mdeditor/markdown_views-258a4616f7.css" rel="stylesheet">
</div>
</article>
Android8.0 Audio系统之AudioPolicy
void AudioPolicyService::onFirstRef()
{
{
......
// class AudioPolicyClient : public AudioPolicyClientInterface
mAudioPolicyClient = new AudioPolicyClient(this);
mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient); //创建Audio管理
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
头文件 AudioPolicyClientInterface 位于 AudioPolicyInterface.h文件中
extern "C" AudioPolicyInterface* createAudioPolicyManager(
AudioPolicyClientInterface *clientInterface)
{
return new AudioPolicyManager(clientInterface);
}
extern “C” void destroyAudioPolicyManager(AudioPolicyInterface *interface)
{
delete interface;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
对于AudioPolicyClientImpl.cpp实现了 AudioPolicyClient,直接与AudioFlinger交互。对于AudioPolicyIntefaceImpl实现了AudioPolicyInterface直接与AudioPolicyManager交互,
AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface) : #ifdef AUDIO_POLICY_TEST Thread(false), #endif //AUDIO_POLICY_TEST mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f), mA2dpSuspended(false), mAudioPortGeneration(1), mBeaconMuteRefCount(0), mBeaconPlayingRefCount(0), mBeaconMuted(false), mTtsOutputAvailable(false), mMasterMono(false), mMusicEffectOutput(AUDIO_IO_HANDLE_NONE) { mpClientInterface = clientInterface; bool speakerDrcEnabled = false; //解析 xml Audio策略,路由 #ifdef USE_XML_AUDIO_POLICY_CONF mVolumeCurves = new VolumeCurvesCollection(); AudioPolicyConfig config(mHwModules, mAvailableOutputDevices, mAvailableInputDevices, mDefaultOutputDevice, speakerDrcEnabled, static_cast<VolumeCurvesCollection *>(mVolumeCurves)); if (deserializeAudioPolicyXmlConfig(config) != NO_ERROR) { #else mVolumeCurves = new StreamDescriptorCollection(); AudioPolicyConfig config(mHwModules, mAvailableOutputDevices, mAvailableInputDevices, mDefaultOutputDevice, speakerDrcEnabled); if ((ConfigParsingUtils::loadConfig(AUDIO_POLICY_VENDOR_CONFIG_FILE, config) != NO_ERROR) && (ConfigParsingUtils::loadConfig(AUDIO_POLICY_CONFIG_FILE, config) != NO_ERROR)) { #endif ALOGE("could not load audio policy configuration file, setting defaults"); config.setDefault(); } // must be done after reading the policy (since conditionned by Speaker Drc Enabling) mVolumeCurves->initializeVolumeCurves(speakerDrcEnabled);
<span class="token comment">// Once policy config has been parsed, retrieve an instance of the engine and initialize it</span> <span class="token comment">//代理引擎</span> audio_policy<span class="token punctuation">:</span><span class="token punctuation">:</span>EngineInstance <span class="token operator">*</span>engineInstance <span class="token operator">=</span> audio_policy<span class="token punctuation">:</span><span class="token punctuation">:</span>EngineInstance<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">getInstance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>engineInstance<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">ALOGE</span><span class="token punctuation">(</span><span class="token string">"%s: Could not get an instance of policy engine"</span><span class="token punctuation">,</span> __FUNCTION__<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Retrieve the Policy Manager Interface</span> mEngine <span class="token operator">=</span> engineInstance<span class="token operator">-></span>queryInterface<span class="token operator"><</span>AudioPolicyManagerInterface<span class="token operator">></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//获取引擎</span> mEngine<span class="token operator">-></span><span class="token function">setObserver</span><span class="token punctuation">(</span>this<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//设为观察者</span> status_t status <span class="token operator">=</span> mEngine<span class="token operator">-></span><span class="token function">initCheck</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//初始</span> <span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span> status<span class="token punctuation">;</span> <span class="token comment">// mAvailableOutputDevices and mAvailableInputDevices now contain all attached devices</span> <span class="token comment">// open all output streams needed to access attached devices</span> audio_devices_t outputDeviceTypes <span class="token operator">=</span> mAvailableOutputDevices<span class="token punctuation">.</span><span class="token function">types</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> audio_devices_t inputDeviceTypes <span class="token operator">=</span> mAvailableInputDevices<span class="token punctuation">.</span><span class="token function">types</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&</span> <span class="token operator">~</span>AUDIO_DEVICE_BIT_IN<span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span>size_t i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> mHwModules<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">//调用ClientInterface加载Audio模块,ClientInterface将调用AudioFlinger的loadHwModule</span> mHwModules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-></span>mHandle <span class="token operator">=</span> mpClientInterface<span class="token operator">-></span><span class="token function">loadHwModule</span><span class="token punctuation">(</span>mHwModules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-></span><span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>mHwModules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-></span>mHandle <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">ALOGW</span><span class="token punctuation">(</span><span class="token string">"could not open HW module %s"</span><span class="token punctuation">,</span> mHwModules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-></span><span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">continue</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">//查找输出模块设备</span> <span class="token keyword">for</span> <span class="token punctuation">(</span>size_t j <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> j <span class="token operator"><</span> mHwModules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-></span>mOutputProfiles<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> j<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> sp<span class="token operator"><</span>IOProfile<span class="token operator">></span> outProfile <span class="token operator">=</span> mHwModules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-></span>mOutputProfiles<span class="token punctuation">[</span>j<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>outProfile<span class="token operator">-></span><span class="token function">hasSupportedDevices</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">ALOGW</span><span class="token punctuation">(</span><span class="token string">"Output profile contains no device on module %s"</span><span class="token punctuation">,</span> mHwModules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-></span><span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">continue</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>outProfile<span class="token operator">-></span><span class="token function">getFlags</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&</span> AUDIO_OUTPUT_FLAG_TTS<span class="token punctuation">)</span> <span class="token operator">!=</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> mTtsOutputAvailable <span class="token operator">=</span> true<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>outProfile<span class="token operator">-></span><span class="token function">getFlags</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&</span> AUDIO_OUTPUT_FLAG_DIRECT<span class="token punctuation">)</span> <span class="token operator">!=</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">continue</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> audio_devices_t profileType <span class="token operator">=</span> outProfile<span class="token operator">-></span><span class="token function">getSupportedDevicesType</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>profileType <span class="token operator">&</span> mDefaultOutputDevice<span class="token operator">-></span><span class="token function">type</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">!=</span> AUDIO_DEVICE_NONE<span class="token punctuation">)</span> <span class="token punctuation">{</span> profileType <span class="token operator">=</span> mDefaultOutputDevice<span class="token operator">-></span><span class="token function">type</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> profileType <span class="token operator">=</span> outProfile<span class="token operator">-></span><span class="token function">getSupportedDeviceForType</span><span class="token punctuation">(</span>outputDeviceTypes<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>profileType <span class="token operator">&</span> outputDeviceTypes<span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">continue</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> sp<span class="token operator"><</span>SwAudioOutputDescriptor<span class="token operator">></span> outputDesc <span class="token operator">=</span> new <span class="token function">SwAudioOutputDescriptor</span><span class="token punctuation">(</span>outProfile<span class="token punctuation">,</span> mpClientInterface<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> DeviceVector <span class="token operator">&</span>supportedDevices <span class="token operator">=</span> outProfile<span class="token operator">-></span><span class="token function">getSupportedDevices</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> DeviceVector <span class="token operator">&</span>devicesForType <span class="token operator">=</span> supportedDevices<span class="token punctuation">.</span><span class="token function">getDevicesFromType</span><span class="token punctuation">(</span>profileType<span class="token punctuation">)</span><span class="token punctuation">;</span> String8 address <span class="token operator">=</span> devicesForType<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">></span> <span class="token number">0</span> <span class="token operator">?</span> devicesForType<span class="token punctuation">.</span><span class="token function">itemAt</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token operator">-></span>mAddress <span class="token punctuation">:</span> <span class="token function">String8</span><span class="token punctuation">(</span><span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">;</span> outputDesc<span class="token operator">-></span>mDevice <span class="token operator">=</span> profileType<span class="token punctuation">;</span> audio_config_t config <span class="token operator">=</span> AUDIO_CONFIG_INITIALIZER<span class="token punctuation">;</span> config<span class="token punctuation">.</span>sample_rate <span class="token operator">=</span> outputDesc<span class="token operator">-></span>mSamplingRate<span class="token punctuation">;</span> config<span class="token punctuation">.</span>channel_mask <span class="token operator">=</span> outputDesc<span class="token operator">-></span>mChannelMask<span class="token punctuation">;</span> config<span class="token punctuation">.</span>format <span class="token operator">=</span> outputDesc<span class="token operator">-></span>mFormat<span class="token punctuation">;</span> audio_io_handle_t output <span class="token operator">=</span> AUDIO_IO_HANDLE_NONE<span class="token punctuation">;</span> <span class="token comment">//熟悉的openOutput</span> status_t status <span class="token operator">=</span> mpClientInterface<span class="token operator">-></span><span class="token function">openOutput</span><span class="token punctuation">(</span>outProfile<span class="token operator">-></span><span class="token function">getModuleHandle</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token operator">&</span>output<span class="token punctuation">,</span> <span class="token operator">&</span>config<span class="token punctuation">,</span> <span class="token operator">&</span>outputDesc<span class="token operator">-></span>mDevice<span class="token punctuation">,</span> address<span class="token punctuation">,</span> <span class="token operator">&</span>outputDesc<span class="token operator">-></span>mLatency<span class="token punctuation">,</span> outputDesc<span class="token operator">-></span>mFlags<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>status <span class="token operator">!=</span> NO_ERROR<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">ALOGW</span><span class="token punctuation">(</span><span class="token string">"Cannot open output stream for device %08x on hw module %s"</span><span class="token punctuation">,</span> outputDesc<span class="token operator">-></span>mDevice<span class="token punctuation">,</span> mHwModules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-></span><span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> outputDesc<span class="token operator">-></span>mSamplingRate <span class="token operator">=</span> config<span class="token punctuation">.</span>sample_rate<span class="token punctuation">;</span> outputDesc<span class="token operator">-></span>mChannelMask <span class="token operator">=</span> config<span class="token punctuation">.</span>channel_mask<span class="token punctuation">;</span> outputDesc<span class="token operator">-></span>mFormat <span class="token operator">=</span> config<span class="token punctuation">.</span>format<span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span>size_t k <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> k <span class="token operator"><</span> supportedDevices<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> k<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> ssize_t index <span class="token operator">=</span> mAvailableOutputDevices<span class="token punctuation">.</span><span class="token function">indexOf</span><span class="token punctuation">(</span>supportedDevices<span class="token punctuation">[</span>k<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// give a valid ID to an attached device once confirmed it is reachable</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>index <span class="token operator">>=</span> <span class="token number">0</span> <span class="token operator">&&</span> <span class="token operator">!</span>mAvailableOutputDevices<span class="token punctuation">[</span>index<span class="token punctuation">]</span><span class="token operator">-></span><span class="token function">isAttached</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> mAvailableOutputDevices<span class="token punctuation">[</span>index<span class="token punctuation">]</span><span class="token operator">-></span><span class="token function">attach</span><span class="token punctuation">(</span>mHwModules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>mPrimaryOutput <span class="token operator">==</span> <span class="token number">0</span> <span class="token operator">&&</span> outProfile<span class="token operator">-></span><span class="token function">getFlags</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&</span> AUDIO_OUTPUT_FLAG_PRIMARY<span class="token punctuation">)</span> <span class="token punctuation">{</span> mPrimaryOutput <span class="token operator">=</span> outputDesc<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">addOutput</span><span class="token punctuation">(</span>output<span class="token punctuation">,</span> outputDesc<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">setOutputDevice</span><span class="token punctuation">(</span>outputDesc<span class="token punctuation">,</span> outputDesc<span class="token operator">-></span>mDevice<span class="token punctuation">,</span> true<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token constant">NULL</span><span class="token punctuation">,</span> address<span class="token punctuation">.</span><span class="token function">string</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">//遍历输入Audio设备</span> <span class="token keyword">for</span> <span class="token punctuation">(</span>size_t j <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> j <span class="token operator"><</span> mHwModules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-></span>mInputProfiles<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> j<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> sp<span class="token operator"><</span>IOProfile<span class="token operator">></span> inProfile <span class="token operator">=</span> mHwModules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-></span>mInputProfiles<span class="token punctuation">[</span>j<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>inProfile<span class="token operator">-></span><span class="token function">hasSupportedDevices</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">ALOGW</span><span class="token punctuation">(</span><span class="token string">"Input profile contains no device on module %s"</span><span class="token punctuation">,</span> mHwModules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-></span><span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">continue</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// chose first device present in profile's SupportedDevices also part of</span> <span class="token comment">// inputDeviceTypes</span> audio_devices_t profileType <span class="token operator">=</span> inProfile<span class="token operator">-></span><span class="token function">getSupportedDeviceForType</span><span class="token punctuation">(</span>inputDeviceTypes<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>profileType <span class="token operator">&</span> inputDeviceTypes<span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">continue</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> sp<span class="token operator"><</span>AudioInputDescriptor<span class="token operator">></span> inputDesc <span class="token operator">=</span> new <span class="token function">AudioInputDescriptor</span><span class="token punctuation">(</span>inProfile<span class="token punctuation">)</span><span class="token punctuation">;</span> inputDesc<span class="token operator">-></span>mDevice <span class="token operator">=</span> profileType<span class="token punctuation">;</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> audio_config_t config <span class="token operator">=</span> AUDIO_CONFIG_INITIALIZER<span class="token punctuation">;</span> config<span class="token punctuation">.</span>sample_rate <span class="token operator">=</span> inputDesc<span class="token operator">-></span>mSamplingRate<span class="token punctuation">;</span> config<span class="token punctuation">.</span>channel_mask <span class="token operator">=</span> inputDesc<span class="token operator">-></span>mChannelMask<span class="token punctuation">;</span> config<span class="token punctuation">.</span>format <span class="token operator">=</span> inputDesc<span class="token operator">-></span>mFormat<span class="token punctuation">;</span> audio_io_handle_t input <span class="token operator">=</span> AUDIO_IO_HANDLE_NONE<span class="token punctuation">;</span> status_t status <span class="token operator">=</span> mpClientInterface<span class="token operator">-></span><span class="token function">openInput</span><span class="token punctuation">(</span>inProfile<span class="token operator">-></span><span class="token function">getModuleHandle</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token operator">&</span>input<span class="token punctuation">,</span> <span class="token operator">&</span>config<span class="token punctuation">,</span> <span class="token operator">&</span>inputDesc<span class="token operator">-></span>mDevice<span class="token punctuation">,</span> address<span class="token punctuation">,</span> AUDIO_SOURCE_MIC<span class="token punctuation">,</span> AUDIO_INPUT_FLAG_NONE<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>status <span class="token operator">==</span> NO_ERROR<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> DeviceVector <span class="token operator">&</span>supportedDevices <span class="token operator">=</span> inProfile<span class="token operator">-></span><span class="token function">getSupportedDevices</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span>size_t k <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> k <span class="token operator"><</span> supportedDevices<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> k<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> ssize_t index <span class="token operator">=</span> mAvailableInputDevices<span class="token punctuation">.</span><span class="token function">indexOf</span><span class="token punctuation">(</span>supportedDevices<span class="token punctuation">[</span>k<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// give a valid ID to an attached device once confirmed it is reachable</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>index <span class="token operator">>=</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> sp<span class="token operator"><</span>DeviceDescriptor<span class="token operator">></span> devDesc <span class="token operator">=</span> mAvailableInputDevices<span class="token punctuation">[</span>index<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>devDesc<span class="token operator">-></span><span class="token function">isAttached</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> devDesc<span class="token operator">-></span><span class="token function">attach</span><span class="token punctuation">(</span>mHwModules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> devDesc<span class="token operator">-></span><span class="token function">importAudioPort</span><span class="token punctuation">(</span>inProfile<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> mpClientInterface<span class="token operator">-></span><span class="token function">closeInput</span><span class="token punctuation">(</span>input<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">// make sure all attached devices have been allocated a unique ID</span> <span class="token comment">//遍历输入输出设备,由路由引擎设置各设备的连接状态</span> <span class="token keyword">for</span> <span class="token punctuation">(</span>size_t i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> mAvailableOutputDevices<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>mAvailableOutputDevices<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-></span><span class="token function">isAttached</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> mAvailableOutputDevices<span class="token punctuation">.</span><span class="token function">remove</span><span class="token punctuation">(</span>mAvailableOutputDevices<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">continue</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// The device is now validated and can be appended to the available devices of the engine</span> mEngine<span class="token operator">-></span><span class="token function">setDeviceConnectionState</span><span class="token punctuation">(</span>mAvailableOutputDevices<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">,</span> AUDIO_POLICY_DEVICE_STATE_AVAILABLE<span class="token punctuation">)</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">for</span> <span class="token punctuation">(</span>size_t i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> mAvailableInputDevices<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>mAvailableInputDevices<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-></span><span class="token function">isAttached</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">;</span> mAvailableInputDevices<span class="token punctuation">.</span><span class="token function">remove</span><span class="token punctuation">(</span>mAvailableInputDevices<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">continue</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// The device is now validated and can be appended to the available devices of the engine</span> mEngine<span class="token operator">-></span><span class="token function">setDeviceConnectionState</span><span class="token punctuation">(</span>mAvailableInputDevices<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">,</span> AUDIO_POLICY_DEVICE_STATE_AVAILABLE<span class="token punctuation">)</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">updateDevicesAndOutputs</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
可以看到AudioPolicyManager通过解析Audio配置文件,加载各输入输出音频Module,然后遍历各输入输出设备,找出稳定的设备后,由路由引擎设置各设备的连接状态。在分析AudioFlinger的时候走过 mpClientInterface->openOutput()函数
sp<AudioFlinger::ThreadBase> AudioFlinger::openOutput_l(.....) { //找到Device, 这个函数很重要,稍后分析 AudioHwDevice *outHwDev = findSuitableHwDev_l(module, devices); //音频流输出到硬件设备 AudioStreamOut *outputStream = NULL; status_t status = outHwDev->openOutputStream( &outputStream, *output, devices, flags, config, address.string());
mHardwareStatus <span class="token operator">=</span> AUDIO_HW_IDLE<span class="token punctuation">;</span>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
在 createTrack_l()的时候,会去根据流类型来获取路由策略
uint32_t strategy = AudioSystem::getStrategyForStream(streamType);
for (size_t i = 0; i < mTracks.size(); ++i) {
sp<Track> t = mTracks[i];
if (t != 0 && t->isExternalTrack()) {
//获取路由策略
uint32_t actual = AudioSystem::getStrategyForStream(t->streamType());
if (sessionId == t->sessionId() && strategy != actual) {
ALOGE("createTrack_l() mismatched strategy; expected %u but found %u",
strategy, actual);
lStatus = BAD_VALUE;
goto Exit;
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
调用 Audio代理服务的 getStrategyForStream
uint32_t AudioSystem::getStrategyForStream(audio_stream_type_t stream)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return 0;
return aps->getStrategyForStream(stream);
}
- 1
- 2
- 3
- 4
- 5
- 6
具体的实现在AudioPolicyInterfaceImpl.cpp文件中
\frameworks\av\services\audiopolicy\service\AudioPolicyInterfaceImpl.cpp
uint32_t AudioPolicyService::getStrategyForStream(audio_stream_type_t stream)
{
if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {
return 0;
}
if (mAudioPolicyManager == NULL) {
return 0;
}
return mAudioPolicyManager->getStrategyForStream(stream);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
uint32_t AudioPolicyManager::getStrategyForStream(audio_stream_type_t stream) {
return (uint32_t)getStrategy(stream);
}
- 1
- 2
- 3
routing_strategy AudioPolicyManager::getStrategy(audio_stream_type_t stream) const
{
ALOG_ASSERT(stream != AUDIO_STREAM_PATCH,"getStrategy() called for AUDIO_STREAM_PATCH");
return mEngine->getStrategyForStream(stream);
}
- 1
- 2
- 3
- 4
- 5
- 6
在文件 frameworks\av\services\audiopolicy\managerdefault\AudioPolicyManager.h 中 AudioPolicyManagerInterface *mEngine; 位于frameworks\av\services\audiopolicy\engine\interface\AudioPolicyManagerInterface.h,在frameworks\av\services\audiopolicy\enginedefault\src\Engine.h文件中被实现如下
/// Interface members class ManagerInterfaceImpl : public AudioPolicyManagerInterface { public: explicit ManagerInterfaceImpl(Engine *policyEngine) : mPolicyEngine(policyEngine) {}
<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> virtual routing_strategy <span class="token function">getStrategyForStream</span><span class="token punctuation">(</span>audio_stream_type_t stream<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> mPolicyEngine<span class="token operator">-></span><span class="token function">getStrategyForStream</span><span class="token punctuation">(</span>stream<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> private<span class="token punctuation">:</span> Engine <span clas