原
Android8.0 Audio系统之AudioPolicy
2018年08月14日 11:43:43 SherlockCharlie
阅读数:1184
</div><div class="operating"></div></div></div>
</div>
<article class="baidu_pl"><div id="article_content" class="article_content clearfix csdn-tracking-statistics" data-pid="blog" data-mod="popu_307" data-dsm="post"><div class="article-copyright"><svg class="icon" title="CSDN认证原创" aria-hidden="true" style="width:53px; height: 18px; vertical-align: -4px;"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#CSDN_Cert"></use></svg>版权声明:未经本人同意,不得转载 https://blog.csdn.net/u013928208/article/details/81660347 </div><link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/ck_htmledit_views-f57960eb32.css"><div id="content_views" class="markdown_views prism-atom-one-dark"><!-- flowchart 箭头图标 勿删 --><svg xmlns="http://www.w3.org/2000/svg" style="display: none;"><path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path></svg><p>上一篇我们跟踪分析了AudioFlinger,它是Audio系统的核心,但是AudioFlinger却不能脱离AudioPolicy工作。AudioPolicy模块承载着音频切换,音轨路由的重要工作,没有它,音频输出将乱套。在分析AudioFlinger的时候我们稍微涉及了AudioPolicyService,现在我们重新来看它。在Android7.0中Audio代理部分被组成独立的模块。<br>
void AudioPolicyService: : onFirstRef ( )
{
{
. . . . . . mAudioPolicyClient = new AudioPolicyClient ( this) ; mAudioPolicyManager = createAudioPolicyManager ( mAudioPolicyClient) ; }
}
头文件 AudioPolicyClientInterface 位于 AudioPolicyInterface.h文件中
extern "C" AudioPolicyInterface* createAudioPolicyManager ( AudioPolicyClientInterface * clientInterface)
{
return new AudioPolicyManager ( clientInterface) ;
}
extern “C” void destroyAudioPolicyManager ( AudioPolicyInterface * interface) {
delete interface; }
对于AudioPolicyClientImpl.cpp实现了 AudioPolicyClient,直接与AudioFlinger交互。对于AudioPolicyIntefaceImpl实现了AudioPolicyInterface直接与AudioPolicyManager交互,
AudioPolicyManager: : AudioPolicyManager ( AudioPolicyClientInterface * clientInterface) :
#ifdef AUDIO_POLICY_TEST Thread ( false) ,
#endif 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;
#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 ( ) ; } 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 ( . . . . . )
{
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) ;
}
具体的实现在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) ;
}
uint32_t AudioPolicyManager: : getStrategyForStream ( audio_stream_type_t stream) {
return ( uint32_t) getStrategy ( stream) ;
}
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) ;
}
在文件 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文件中被实现如下
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)
{
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: 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) ;
至此音频代理路由部分暂到这,目前所看到的只是一小部分,随着Android系统的日益复杂,Audio会变得越来越庞大; 不过万变不离其宗,只要大体架构上不做大改动,也是很容易分析的,下一篇我们来看Audio系统的硬件抽象层。
</div><link href="https://csdnimg.cn/release/phoenix/mdeditor/markdown_views-258a4616f7.css" rel="stylesheet"></div>
</article>
原
Android8.0 Audio系统之AudioPolicy
2018年08月14日 11:43:43 SherlockCharlie
阅读数:1184
</div><div class="operating"></div></div></div>
</div>
<article class="baidu_pl"><div id="article_content" class="article_content clearfix csdn-tracking-statistics" data-pid="blog" data-mod="popu_307" data-dsm="post"><div class="article-copyright"><svg class="icon" title="CSDN认证原创" aria-hidden="true" style="width:53px; height: 18px; vertical-align: -4px;"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#CSDN_Cert"></use></svg>版权声明:未经本人同意,不得转载 https://blog.csdn.net/u013928208/article/details/81660347 </div><link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/ck_htmledit_views-f57960eb32.css"><div id="content_views" class="markdown_views prism-atom-one-dark"><!-- flowchart 箭头图标 勿删 --><svg xmlns="http://www.w3.org/2000/svg" style="display: none;"><path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path></svg><p>上一篇我们跟踪分析了AudioFlinger,它是Audio系统的核心,但是AudioFlinger却不能脱离AudioPolicy工作。AudioPolicy模块承载着音频切换,音轨路由的重要工作,没有它,音频输出将乱套。在分析AudioFlinger的时候我们稍微涉及了AudioPolicyService,现在我们重新来看它。在Android7.0中Audio代理部分被组成独立的模块。<br>
void AudioPolicyService: : onFirstRef ( )
{
{
. . . . . . mAudioPolicyClient = new AudioPolicyClient ( this) ; mAudioPolicyManager = createAudioPolicyManager ( mAudioPolicyClient) ; }
}
头文件 AudioPolicyClientInterface 位于 AudioPolicyInterface.h文件中
extern "C" AudioPolicyInterface* createAudioPolicyManager ( AudioPolicyClientInterface * clientInterface)
{
return new AudioPolicyManager ( clientInterface) ;
}
extern “C” void destroyAudioPolicyManager ( AudioPolicyInterface * interface) {
delete interface; }
对于AudioPolicyClientImpl.cpp实现了 AudioPolicyClient,直接与AudioFlinger交互。对于AudioPolicyIntefaceImpl实现了AudioPolicyInterface直接与AudioPolicyManager交互,
AudioPolicyManager: : AudioPolicyManager ( AudioPolicyClientInterface * clientInterface) :
#ifdef AUDIO_POLICY_TEST Thread ( false) ,
#endif 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;
#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 ( ) ; } 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 ( . . . . . )
{
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) ;
}
具体的实现在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) ;
}
uint32_t AudioPolicyManager: : getStrategyForStream ( audio_stream_type_t stream) {
return ( uint32_t) getStrategy ( stream) ;
}
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) ;
}
在文件 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文件中被实现如下
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)
{
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: 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) ;
至此音频代理路由部分暂到这,目前所看到的只是一小部分,随着Android系统的日益复杂,Audio会变得越来越庞大; 不过万变不离其宗,只要大体架构上不做大改动,也是很容易分析的,下一篇我们来看Audio系统的硬件抽象层。
</div><link href="https://csdnimg.cn/release/phoenix/mdeditor/markdown_views-258a4616f7.css" rel="stylesheet"></div>
</article>
原
Android8.0 Audio系统之AudioPolicy
2018年08月14日 11:43:43 SherlockCharlie
阅读数:1184
</div><div class="operating"></div></div></div>
</div>
<article class="baidu_pl"><div id="article_content" class="article_content clearfix csdn-tracking-statistics" data-pid="blog" data-mod="popu_307" data-dsm="post"><div class="article-copyright"><svg class="icon" title="CSDN认证原创" aria-hidden="true" style="width:53px; height: 18px; vertical-align: -4px;"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#CSDN_Cert"></use></svg>版权声明:未经本人同意,不得转载 https://blog.csdn.net/u013928208/article/details/81660347 </div><link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/ck_htmledit_views-f57960eb32.css"><div id="content_views" class="markdown_views prism-atom-one-dark"><!-- flowchart 箭头图标 勿删 --><svg xmlns="http://www.w3.org/2000/svg" style="display: none;"><path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path></svg><p>上一篇我们跟踪分析了AudioFlinger,它是Audio系统的核心,但是AudioFlinger却不能脱离AudioPolicy工作。AudioPolicy模块承载着音频切换,音轨路由的重要工作,没有它,音频输出将乱套。在分析AudioFlinger的时候我们稍微涉及了AudioPolicyService,现在我们重新来看它。在Android7.0中Audio代理部分被组成独立的模块。<br>
void AudioPolicyService: : onFirstRef ( )
{
{
. . . . . . mAudioPolicyClient = new AudioPolicyClient ( this) ; mAudioPolicyManager = createAudioPolicyManager ( mAudioPolicyClient) ; }
}
头文件 AudioPolicyClientInterface 位于 AudioPolicyInterface.h文件中
extern "C" AudioPolicyInterface* createAudioPolicyManager ( AudioPolicyClientInterface * clientInterface)
{
return new AudioPolicyManager ( clientInterface) ;
}
extern “C” void destroyAudioPolicyManager ( AudioPolicyInterface * interface) {
delete interface; }
对于AudioPolicyClientImpl.cpp实现了 AudioPolicyClient,直接与AudioFlinger交互。对于AudioPolicyIntefaceImpl实现了AudioPolicyInterface直接与AudioPolicyManager交互,
AudioPolicyManager: : AudioPolicyManager ( AudioPolicyClientInterface * clientInterface) :
#ifdef AUDIO_POLICY_TEST Thread ( false) ,
#endif 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;
#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 ( ) ; } 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 ( . . . . . )
{
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) ;
}
具体的实现在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) ;
}
uint32_t AudioPolicyManager: : getStrategyForStream ( audio_stream_type_t stream) {
return ( uint32_t) getStrategy ( stream) ;
}
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) ;
}
在文件 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文件中被实现如下
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