原 Android8.0 Audio系统之AudioPolicy

Android8.0 Audio系统之AudioPolicy

这里写图片描述

void AudioPolicyService::onFirstRef()
{
    {
        ......
        // class AudioPolicyClient : public AudioPolicyClientInterface
        mAudioPolicyClient = new AudioPolicyClient(this);
        mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient); //创建Audio管理
    }
}

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

头文件 AudioPolicyClientInterface 位于 AudioPolicyInterface.h文件中


extern "C" AudioPolicyInterface* createAudioPolicyManager(
        AudioPolicyClientInterface *clientInterface)
{
    return new AudioPolicyManager(clientInterface);
}

extern “C” void destroyAudioPolicyManager(AudioPolicyInterface *interface)
{
delete interface;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

对于AudioPolicyClientImpl.cpp实现了 AudioPolicyClient,直接与AudioFlinger交互。对于AudioPolicyIntefaceImpl实现了AudioPolicyInterface直接与AudioPolicyManager交互,

AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface)
    :
#ifdef AUDIO_POLICY_TEST
    Thread(false),
#endif //AUDIO_POLICY_TEST
    mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f),
    mA2dpSuspended(false),
    mAudioPortGeneration(1),
    mBeaconMuteRefCount(0),
    mBeaconPlayingRefCount(0),
    mBeaconMuted(false),
    mTtsOutputAvailable(false),
    mMasterMono(false),
    mMusicEffectOutput(AUDIO_IO_HANDLE_NONE)
{
    mpClientInterface = clientInterface;
    bool speakerDrcEnabled = false;
     //解析 xml Audio策略,路由
#ifdef USE_XML_AUDIO_POLICY_CONF
    mVolumeCurves = new VolumeCurvesCollection();
    AudioPolicyConfig config(mHwModules, mAvailableOutputDevices, mAvailableInputDevices,
                             mDefaultOutputDevice, speakerDrcEnabled,
                             static_cast<VolumeCurvesCollection *>(mVolumeCurves));
    if (deserializeAudioPolicyXmlConfig(config) != NO_ERROR) {
#else
    mVolumeCurves = new StreamDescriptorCollection();
    AudioPolicyConfig config(mHwModules, mAvailableOutputDevices, mAvailableInputDevices,
                             mDefaultOutputDevice, speakerDrcEnabled);
    if ((ConfigParsingUtils::loadConfig(AUDIO_POLICY_VENDOR_CONFIG_FILE, config) != NO_ERROR) &&
            (ConfigParsingUtils::loadConfig(AUDIO_POLICY_CONFIG_FILE, config) != NO_ERROR)) {
#endif
        ALOGE("could not load audio policy configuration file, setting defaults");
        config.setDefault();
    }
    // must be done after reading the policy (since conditionned by Speaker Drc Enabling)
    mVolumeCurves->initializeVolumeCurves(speakerDrcEnabled);
<span class="token comment">// Once policy config has been parsed, retrieve an instance of the engine and initialize it</span>
<span class="token comment">//代理引擎</span>
audio_policy<span class="token punctuation">:</span><span class="token punctuation">:</span>EngineInstance <span class="token operator">*</span>engineInstance <span class="token operator">=</span> audio_policy<span class="token punctuation">:</span><span class="token punctuation">:</span>EngineInstance<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">getInstance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>engineInstance<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token function">ALOGE</span><span class="token punctuation">(</span><span class="token string">"%s:  Could not get an instance of policy engine"</span><span class="token punctuation">,</span> __FUNCTION__<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">// Retrieve the Policy Manager Interface</span>
mEngine <span class="token operator">=</span> engineInstance<span class="token operator">-&gt;</span>queryInterface<span class="token operator">&lt;</span>AudioPolicyManagerInterface<span class="token operator">&gt;</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">-&gt;</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">-&gt;</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">&amp;</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">&lt;</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">-&gt;</span>mHandle <span class="token operator">=</span> mpClientInterface<span class="token operator">-&gt;</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">-&gt;</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">-&gt;</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">-&gt;</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">&lt;</span> mHwModules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-&gt;</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">&lt;</span>IOProfile<span class="token operator">&gt;</span> outProfile <span class="token operator">=</span> mHwModules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-&gt;</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">-&gt;</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">-&gt;</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">-&gt;</span><span class="token function">getFlags</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&amp;</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">-&gt;</span><span class="token function">getFlags</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&amp;</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">-&gt;</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">&amp;</span> mDefaultOutputDevice<span class="token operator">-&gt;</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">-&gt;</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">-&gt;</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">&amp;</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">&lt;</span>SwAudioOutputDescriptor<span class="token operator">&gt;</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">&amp;</span>supportedDevices <span class="token operator">=</span> outProfile<span class="token operator">-&gt;</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">&amp;</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">&gt;</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">-&gt;</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">-&gt;</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">-&gt;</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">-&gt;</span>mChannelMask<span class="token punctuation">;</span>
        config<span class="token punctuation">.</span>format <span class="token operator">=</span> outputDesc<span class="token operator">-&gt;</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">-&gt;</span><span class="token function">openOutput</span><span class="token punctuation">(</span>outProfile<span class="token operator">-&gt;</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">&amp;</span>output<span class="token punctuation">,</span>
                                                        <span class="token operator">&amp;</span>config<span class="token punctuation">,</span>
                                                        <span class="token operator">&amp;</span>outputDesc<span class="token operator">-&gt;</span>mDevice<span class="token punctuation">,</span>
                                                        address<span class="token punctuation">,</span>
                                                        <span class="token operator">&amp;</span>outputDesc<span class="token operator">-&gt;</span>mLatency<span class="token punctuation">,</span>
                                                        outputDesc<span class="token operator">-&gt;</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">-&gt;</span>mDevice<span class="token punctuation">,</span>
                  mHwModules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-&gt;</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">-&gt;</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">-&gt;</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">-&gt;</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">&lt;</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">&gt;=</span> <span class="token number">0</span> <span class="token operator">&amp;&amp;</span> <span class="token operator">!</span>mAvailableOutputDevices<span class="token punctuation">[</span>index<span class="token punctuation">]</span><span class="token operator">-&gt;</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">-&gt;</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">&amp;&amp;</span>
                    outProfile<span class="token operator">-&gt;</span><span class="token function">getFlags</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&amp;</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">-&gt;</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">&lt;</span> mHwModules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-&gt;</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">&lt;</span>IOProfile<span class="token operator">&gt;</span> inProfile <span class="token operator">=</span> mHwModules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-&gt;</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">-&gt;</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">-&gt;</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">-&gt;</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">&amp;</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">&lt;</span>AudioInputDescriptor<span class="token operator">&gt;</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">-&gt;</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">-&gt;</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">-&gt;</span>mChannelMask<span class="token punctuation">;</span>
        config<span class="token punctuation">.</span>format <span class="token operator">=</span> inputDesc<span class="token operator">-&gt;</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">-&gt;</span><span class="token function">openInput</span><span class="token punctuation">(</span>inProfile<span class="token operator">-&gt;</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">&amp;</span>input<span class="token punctuation">,</span>
                                                       <span class="token operator">&amp;</span>config<span class="token punctuation">,</span>
                                                       <span class="token operator">&amp;</span>inputDesc<span class="token operator">-&gt;</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">&amp;</span>supportedDevices <span class="token operator">=</span> inProfile<span class="token operator">-&gt;</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">&lt;</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">&gt;=</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
                    sp<span class="token operator">&lt;</span>DeviceDescriptor<span class="token operator">&gt;</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">-&gt;</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">-&gt;</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">-&gt;</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">-&gt;</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">&lt;</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">-&gt;</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">-&gt;</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">&lt;</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">-&gt;</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">-&gt;</span><span class="token function">setDeviceConnectionState</span><span class="token punctuation">(</span>mAvailableInputDevices<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">,</span>
                                      AUDIO_POLICY_DEVICE_STATE_AVAILABLE<span class="token punctuation">)</span><span class="token punctuation">;</span>
    i<span class="token operator">++</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token function">updateDevicesAndOutputs</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212

可以看到AudioPolicyManager通过解析Audio配置文件,加载各输入输出音频Module,然后遍历各输入输出设备,找出稳定的设备后,由路由引擎设置各设备的连接状态。在分析AudioFlinger的时候走过 mpClientInterface->openOutput()函数

sp<AudioFlinger::ThreadBase> AudioFlinger::openOutput_l(.....)
{
    //找到Device, 这个函数很重要,稍后分析
    AudioHwDevice *outHwDev = findSuitableHwDev_l(module, devices);
    //音频流输出到硬件设备
    AudioStreamOut *outputStream = NULL;
    status_t status = outHwDev->openOutputStream(
            &outputStream,
            *output,
            devices,
            flags,
            config,
            address.string());
mHardwareStatus <span class="token operator">=</span> AUDIO_HW_IDLE<span class="token punctuation">;</span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

在 createTrack_l()的时候,会去根据流类型来获取路由策略

    uint32_t strategy = AudioSystem::getStrategyForStream(streamType);
        for (size_t i = 0; i < mTracks.size(); ++i) {
            sp<Track> t = mTracks[i];
            if (t != 0 && t->isExternalTrack()) {
            //获取路由策略
                uint32_t actual = AudioSystem::getStrategyForStream(t->streamType());
                if (sessionId == t->sessionId() && strategy != actual) {
                    ALOGE("createTrack_l() mismatched strategy; expected %u but found %u",
                            strategy, actual);
                    lStatus = BAD_VALUE;
                    goto Exit;
                }
            }
        }

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

调用 Audio代理服务的 getStrategyForStream

uint32_t AudioSystem::getStrategyForStream(audio_stream_type_t stream)
{
    const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
    if (aps == 0) return 0;
    return aps->getStrategyForStream(stream);
}

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

具体的实现在AudioPolicyInterfaceImpl.cpp文件中
\frameworks\av\services\audiopolicy\service\AudioPolicyInterfaceImpl.cpp

uint32_t AudioPolicyService::getStrategyForStream(audio_stream_type_t stream)
{
    if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {
        return 0;
    }
    if (mAudioPolicyManager == NULL) {
        return 0;
    }
    return mAudioPolicyManager->getStrategyForStream(stream);
}

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
uint32_t AudioPolicyManager::getStrategyForStream(audio_stream_type_t stream) {
    return (uint32_t)getStrategy(stream);
}

 
 
  • 1
  • 2
  • 3
routing_strategy AudioPolicyManager::getStrategy(audio_stream_type_t stream) const
{
    ALOG_ASSERT(stream != AUDIO_STREAM_PATCH,"getStrategy() called for AUDIO_STREAM_PATCH");
    return mEngine->getStrategyForStream(stream);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

在文件 frameworks\av\services\audiopolicy\managerdefault\AudioPolicyManager.h 中 AudioPolicyManagerInterface *mEngine; 位于frameworks\av\services\audiopolicy\engine\interface\AudioPolicyManagerInterface.h,在frameworks\av\services\audiopolicy\enginedefault\src\Engine.h文件中被实现如下

  /// Interface members
    class ManagerInterfaceImpl : public AudioPolicyManagerInterface
    {
    public:
        explicit ManagerInterfaceImpl(Engine *policyEngine)
            : mPolicyEngine(policyEngine) {}
    <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
    virtual routing_strategy <span class="token function">getStrategyForStream</span><span class="token punctuation">(</span>audio_stream_type_t stream<span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        <span class="token keyword">return</span> mPolicyEngine<span class="token operator">-&gt;</span><span class="token function">getStrategyForStream</span><span class="token punctuation">(</span>stream<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
private<span class="token punctuation">:</span>
    Engine <span class="token operator">*</span>mPolicyEngine<span class="token punctuation">;</span>
<span class="token punctuation">}</span> mManagerInterface<span class="token punctuation">;</span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

最终将调用Engine.cpp的getStrategyForStream查询音频路由策略

routing_strategy Engine::getStrategyForStream(audio_stream_type_t stream)
{
    // stream to strategy mapping
    switch (stream) {
    case AUDIO_STREAM_VOICE_CALL:
    case AUDIO_STREAM_BLUETOOTH_SCO:
        return STRATEGY_PHONE;
    case AUDIO_STREAM_RING:
    case AUDIO_STREAM_ALARM:
        return STRATEGY_SONIFICATION;
    case AUDIO_STREAM_NOTIFICATION:
        return STRATEGY_SONIFICATION_RESPECTFUL;
    case AUDIO_STREAM_DTMF:
        return STRATEGY_DTMF;
    default:
        ALOGE("unknown stream type %d", stream);
    case AUDIO_STREAM_SYSTEM:
        // NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs
        // while key clicks are played produces a poor result
    case AUDIO_STREAM_MUSIC:
        return STRATEGY_MEDIA;
    case AUDIO_STREAM_ENFORCED_AUDIBLE:
        return STRATEGY_ENFORCED_AUDIBLE;
    case AUDIO_STREAM_TTS:
        return STRATEGY_TRANSMITTED_THROUGH_SPEAKER;
    case AUDIO_STREAM_ACCESSIBILITY:
        return STRATEGY_ACCESSIBILITY;
    case AUDIO_STREAM_REROUTING:
        return STRATEGY_REROUTING;
    }
}

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

在AudioPolicyService.h文件中定义了如下函数,用来处理设备改变时调整路由策略

virtual status_t handleDeviceConfigChange(audio_devices_t device,
                                              const char *device_address,
                                              const char *device_name);

 
 
  • 1
  • 2
  • 3

至此音频代理路由部分暂到这,目前所看到的只是一小部分,随着Android系统的日益复杂,Audio会变得越来越庞大;
不过万变不离其宗,只要大体架构上不做大改动,也是很容易分析的,下一篇我们来看Audio系统的硬件抽象层。

        </div>
					<link href="https://csdnimg.cn/release/phoenix/mdeditor/markdown_views-258a4616f7.css" rel="stylesheet">
                  </div>
</article>

Android8.0 Audio系统之AudioPolicy

这里写图片描述

void AudioPolicyService::onFirstRef()
{
    {
        ......
        // class AudioPolicyClient : public AudioPolicyClientInterface
        mAudioPolicyClient = new AudioPolicyClient(this);
        mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient); //创建Audio管理
    }
}

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

头文件 AudioPolicyClientInterface 位于 AudioPolicyInterface.h文件中


extern "C" AudioPolicyInterface* createAudioPolicyManager(
        AudioPolicyClientInterface *clientInterface)
{
    return new AudioPolicyManager(clientInterface);
}

extern “C” void destroyAudioPolicyManager(AudioPolicyInterface *interface)
{
delete interface;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

对于AudioPolicyClientImpl.cpp实现了 AudioPolicyClient,直接与AudioFlinger交互。对于AudioPolicyIntefaceImpl实现了AudioPolicyInterface直接与AudioPolicyManager交互,

AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface)
    :
#ifdef AUDIO_POLICY_TEST
    Thread(false),
#endif //AUDIO_POLICY_TEST
    mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f),
    mA2dpSuspended(false),
    mAudioPortGeneration(1),
    mBeaconMuteRefCount(0),
    mBeaconPlayingRefCount(0),
    mBeaconMuted(false),
    mTtsOutputAvailable(false),
    mMasterMono(false),
    mMusicEffectOutput(AUDIO_IO_HANDLE_NONE)
{
    mpClientInterface = clientInterface;
    bool speakerDrcEnabled = false;
     //解析 xml Audio策略,路由
#ifdef USE_XML_AUDIO_POLICY_CONF
    mVolumeCurves = new VolumeCurvesCollection();
    AudioPolicyConfig config(mHwModules, mAvailableOutputDevices, mAvailableInputDevices,
                             mDefaultOutputDevice, speakerDrcEnabled,
                             static_cast<VolumeCurvesCollection *>(mVolumeCurves));
    if (deserializeAudioPolicyXmlConfig(config) != NO_ERROR) {
#else
    mVolumeCurves = new StreamDescriptorCollection();
    AudioPolicyConfig config(mHwModules, mAvailableOutputDevices, mAvailableInputDevices,
                             mDefaultOutputDevice, speakerDrcEnabled);
    if ((ConfigParsingUtils::loadConfig(AUDIO_POLICY_VENDOR_CONFIG_FILE, config) != NO_ERROR) &&
            (ConfigParsingUtils::loadConfig(AUDIO_POLICY_CONFIG_FILE, config) != NO_ERROR)) {
#endif
        ALOGE("could not load audio policy configuration file, setting defaults");
        config.setDefault();
    }
    // must be done after reading the policy (since conditionned by Speaker Drc Enabling)
    mVolumeCurves->initializeVolumeCurves(speakerDrcEnabled);
<span class="token comment">// Once policy config has been parsed, retrieve an instance of the engine and initialize it</span>
<span class="token comment">//代理引擎</span>
audio_policy<span class="token punctuation">:</span><span class="token punctuation">:</span>EngineInstance <span class="token operator">*</span>engineInstance <span class="token operator">=</span> audio_policy<span class="token punctuation">:</span><span class="token punctuation">:</span>EngineInstance<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">getInstance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>engineInstance<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token function">ALOGE</span><span class="token punctuation">(</span><span class="token string">"%s:  Could not get an instance of policy engine"</span><span class="token punctuation">,</span> __FUNCTION__<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">// Retrieve the Policy Manager Interface</span>
mEngine <span class="token operator">=</span> engineInstance<span class="token operator">-&gt;</span>queryInterface<span class="token operator">&lt;</span>AudioPolicyManagerInterface<span class="token operator">&gt;</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">-&gt;</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">-&gt;</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">&amp;</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">&lt;</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">-&gt;</span>mHandle <span class="token operator">=</span> mpClientInterface<span class="token operator">-&gt;</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">-&gt;</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">-&gt;</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">-&gt;</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">&lt;</span> mHwModules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-&gt;</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">&lt;</span>IOProfile<span class="token operator">&gt;</span> outProfile <span class="token operator">=</span> mHwModules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-&gt;</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">-&gt;</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">-&gt;</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">-&gt;</span><span class="token function">getFlags</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&amp;</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">-&gt;</span><span class="token function">getFlags</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&amp;</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">-&gt;</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">&amp;</span> mDefaultOutputDevice<span class="token operator">-&gt;</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">-&gt;</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">-&gt;</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">&amp;</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">&lt;</span>SwAudioOutputDescriptor<span class="token operator">&gt;</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">&amp;</span>supportedDevices <span class="token operator">=</span> outProfile<span class="token operator">-&gt;</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">&amp;</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">&gt;</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">-&gt;</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">-&gt;</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">-&gt;</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">-&gt;</span>mChannelMask<span class="token punctuation">;</span>
        config<span class="token punctuation">.</span>format <span class="token operator">=</span> outputDesc<span class="token operator">-&gt;</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">-&gt;</span><span class="token function">openOutput</span><span class="token punctuation">(</span>outProfile<span class="token operator">-&gt;</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">&amp;</span>output<span class="token punctuation">,</span>
                                                        <span class="token operator">&amp;</span>config<span class="token punctuation">,</span>
                                                        <span class="token operator">&amp;</span>outputDesc<span class="token operator">-&gt;</span>mDevice<span class="token punctuation">,</span>
                                                        address<span class="token punctuation">,</span>
                                                        <span class="token operator">&amp;</span>outputDesc<span class="token operator">-&gt;</span>mLatency<span class="token punctuation">,</span>
                                                        outputDesc<span class="token operator">-&gt;</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">-&gt;</span>mDevice<span class="token punctuation">,</span>
                  mHwModules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-&gt;</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">-&gt;</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">-&gt;</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">-&gt;</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">&lt;</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">&gt;=</span> <span class="token number">0</span> <span class="token operator">&amp;&amp;</span> <span class="token operator">!</span>mAvailableOutputDevices<span class="token punctuation">[</span>index<span class="token punctuation">]</span><span class="token operator">-&gt;</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">-&gt;</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">&amp;&amp;</span>
                    outProfile<span class="token operator">-&gt;</span><span class="token function">getFlags</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&amp;</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">-&gt;</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">&lt;</span> mHwModules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-&gt;</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">&lt;</span>IOProfile<span class="token operator">&gt;</span> inProfile <span class="token operator">=</span> mHwModules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-&gt;</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">-&gt;</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">-&gt;</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">-&gt;</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">&amp;</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">&lt;</span>AudioInputDescriptor<span class="token operator">&gt;</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">-&gt;</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">-&gt;</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">-&gt;</span>mChannelMask<span class="token punctuation">;</span>
        config<span class="token punctuation">.</span>format <span class="token operator">=</span> inputDesc<span class="token operator">-&gt;</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">-&gt;</span><span class="token function">openInput</span><span class="token punctuation">(</span>inProfile<span class="token operator">-&gt;</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">&amp;</span>input<span class="token punctuation">,</span>
                                                       <span class="token operator">&amp;</span>config<span class="token punctuation">,</span>
                                                       <span class="token operator">&amp;</span>inputDesc<span class="token operator">-&gt;</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">&amp;</span>supportedDevices <span class="token operator">=</span> inProfile<span class="token operator">-&gt;</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">&lt;</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">&gt;=</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
                    sp<span class="token operator">&lt;</span>DeviceDescriptor<span class="token operator">&gt;</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">-&gt;</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">-&gt;</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">-&gt;</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">-&gt;</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">&lt;</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">-&gt;</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">-&gt;</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">&lt;</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">-&gt;</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">-&gt;</span><span class="token function">setDeviceConnectionState</span><span class="token punctuation">(</span>mAvailableInputDevices<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">,</span>
                                      AUDIO_POLICY_DEVICE_STATE_AVAILABLE<span class="token punctuation">)</span><span class="token punctuation">;</span>
    i<span class="token operator">++</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token function">updateDevicesAndOutputs</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212

可以看到AudioPolicyManager通过解析Audio配置文件,加载各输入输出音频Module,然后遍历各输入输出设备,找出稳定的设备后,由路由引擎设置各设备的连接状态。在分析AudioFlinger的时候走过 mpClientInterface->openOutput()函数

sp<AudioFlinger::ThreadBase> AudioFlinger::openOutput_l(.....)
{
    //找到Device, 这个函数很重要,稍后分析
    AudioHwDevice *outHwDev = findSuitableHwDev_l(module, devices);
    //音频流输出到硬件设备
    AudioStreamOut *outputStream = NULL;
    status_t status = outHwDev->openOutputStream(
            &outputStream,
            *output,
            devices,
            flags,
            config,
            address.string());
mHardwareStatus <span class="token operator">=</span> AUDIO_HW_IDLE<span class="token punctuation">;</span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

在 createTrack_l()的时候,会去根据流类型来获取路由策略

    uint32_t strategy = AudioSystem::getStrategyForStream(streamType);
        for (size_t i = 0; i < mTracks.size(); ++i) {
            sp<Track> t = mTracks[i];
            if (t != 0 && t->isExternalTrack()) {
            //获取路由策略
                uint32_t actual = AudioSystem::getStrategyForStream(t->streamType());
                if (sessionId == t->sessionId() && strategy != actual) {
                    ALOGE("createTrack_l() mismatched strategy; expected %u but found %u",
                            strategy, actual);
                    lStatus = BAD_VALUE;
                    goto Exit;
                }
            }
        }

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

调用 Audio代理服务的 getStrategyForStream

uint32_t AudioSystem::getStrategyForStream(audio_stream_type_t stream)
{
    const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
    if (aps == 0) return 0;
    return aps->getStrategyForStream(stream);
}

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

具体的实现在AudioPolicyInterfaceImpl.cpp文件中
\frameworks\av\services\audiopolicy\service\AudioPolicyInterfaceImpl.cpp

uint32_t AudioPolicyService::getStrategyForStream(audio_stream_type_t stream)
{
    if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {
        return 0;
    }
    if (mAudioPolicyManager == NULL) {
        return 0;
    }
    return mAudioPolicyManager->getStrategyForStream(stream);
}

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
uint32_t AudioPolicyManager::getStrategyForStream(audio_stream_type_t stream) {
    return (uint32_t)getStrategy(stream);
}

 
 
  • 1
  • 2
  • 3
routing_strategy AudioPolicyManager::getStrategy(audio_stream_type_t stream) const
{
    ALOG_ASSERT(stream != AUDIO_STREAM_PATCH,"getStrategy() called for AUDIO_STREAM_PATCH");
    return mEngine->getStrategyForStream(stream);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

在文件 frameworks\av\services\audiopolicy\managerdefault\AudioPolicyManager.h 中 AudioPolicyManagerInterface *mEngine; 位于frameworks\av\services\audiopolicy\engine\interface\AudioPolicyManagerInterface.h,在frameworks\av\services\audiopolicy\enginedefault\src\Engine.h文件中被实现如下

  /// Interface members
    class ManagerInterfaceImpl : public AudioPolicyManagerInterface
    {
    public:
        explicit ManagerInterfaceImpl(Engine *policyEngine)
            : mPolicyEngine(policyEngine) {}
    <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
    virtual routing_strategy <span class="token function">getStrategyForStream</span><span class="token punctuation">(</span>audio_stream_type_t stream<span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        <span class="token keyword">return</span> mPolicyEngine<span class="token operator">-&gt;</span><span class="token function">getStrategyForStream</span><span class="token punctuation">(</span>stream<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
private<span class="token punctuation">:</span>
    Engine <span class="token operator">*</span>mPolicyEngine<span class="token punctuation">;</span>
<span class="token punctuation">}</span> mManagerInterface<span class="token punctuation">;</span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

最终将调用Engine.cpp的getStrategyForStream查询音频路由策略

routing_strategy Engine::getStrategyForStream(audio_stream_type_t stream)
{
    // stream to strategy mapping
    switch (stream) {
    case AUDIO_STREAM_VOICE_CALL:
    case AUDIO_STREAM_BLUETOOTH_SCO:
        return STRATEGY_PHONE;
    case AUDIO_STREAM_RING:
    case AUDIO_STREAM_ALARM:
        return STRATEGY_SONIFICATION;
    case AUDIO_STREAM_NOTIFICATION:
        return STRATEGY_SONIFICATION_RESPECTFUL;
    case AUDIO_STREAM_DTMF:
        return STRATEGY_DTMF;
    default:
        ALOGE("unknown stream type %d", stream);
    case AUDIO_STREAM_SYSTEM:
        // NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs
        // while key clicks are played produces a poor result
    case AUDIO_STREAM_MUSIC:
        return STRATEGY_MEDIA;
    case AUDIO_STREAM_ENFORCED_AUDIBLE:
        return STRATEGY_ENFORCED_AUDIBLE;
    case AUDIO_STREAM_TTS:
        return STRATEGY_TRANSMITTED_THROUGH_SPEAKER;
    case AUDIO_STREAM_ACCESSIBILITY:
        return STRATEGY_ACCESSIBILITY;
    case AUDIO_STREAM_REROUTING:
        return STRATEGY_REROUTING;
    }
}

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

在AudioPolicyService.h文件中定义了如下函数,用来处理设备改变时调整路由策略

virtual status_t handleDeviceConfigChange(audio_devices_t device,
                                              const char *device_address,
                                              const char *device_name);

 
 
  • 1
  • 2
  • 3

至此音频代理路由部分暂到这,目前所看到的只是一小部分,随着Android系统的日益复杂,Audio会变得越来越庞大;
不过万变不离其宗,只要大体架构上不做大改动,也是很容易分析的,下一篇我们来看Audio系统的硬件抽象层。

        </div>
					<link href="https://csdnimg.cn/release/phoenix/mdeditor/markdown_views-258a4616f7.css" rel="stylesheet">
                  </div>
</article>

Android8.0 Audio系统之AudioPolicy

这里写图片描述

void AudioPolicyService::onFirstRef()
{
    {
        ......
        // class AudioPolicyClient : public AudioPolicyClientInterface
        mAudioPolicyClient = new AudioPolicyClient(this);
        mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient); //创建Audio管理
    }
}

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

头文件 AudioPolicyClientInterface 位于 AudioPolicyInterface.h文件中


extern "C" AudioPolicyInterface* createAudioPolicyManager(
        AudioPolicyClientInterface *clientInterface)
{
    return new AudioPolicyManager(clientInterface);
}

extern “C” void destroyAudioPolicyManager(AudioPolicyInterface *interface)
{
delete interface;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

对于AudioPolicyClientImpl.cpp实现了 AudioPolicyClient,直接与AudioFlinger交互。对于AudioPolicyIntefaceImpl实现了AudioPolicyInterface直接与AudioPolicyManager交互,

AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface)
    :
#ifdef AUDIO_POLICY_TEST
    Thread(false),
#endif //AUDIO_POLICY_TEST
    mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f),
    mA2dpSuspended(false),
    mAudioPortGeneration(1),
    mBeaconMuteRefCount(0),
    mBeaconPlayingRefCount(0),
    mBeaconMuted(false),
    mTtsOutputAvailable(false),
    mMasterMono(false),
    mMusicEffectOutput(AUDIO_IO_HANDLE_NONE)
{
    mpClientInterface = clientInterface;
    bool speakerDrcEnabled = false;
     //解析 xml Audio策略,路由
#ifdef USE_XML_AUDIO_POLICY_CONF
    mVolumeCurves = new VolumeCurvesCollection();
    AudioPolicyConfig config(mHwModules, mAvailableOutputDevices, mAvailableInputDevices,
                             mDefaultOutputDevice, speakerDrcEnabled,
                             static_cast<VolumeCurvesCollection *>(mVolumeCurves));
    if (deserializeAudioPolicyXmlConfig(config) != NO_ERROR) {
#else
    mVolumeCurves = new StreamDescriptorCollection();
    AudioPolicyConfig config(mHwModules, mAvailableOutputDevices, mAvailableInputDevices,
                             mDefaultOutputDevice, speakerDrcEnabled);
    if ((ConfigParsingUtils::loadConfig(AUDIO_POLICY_VENDOR_CONFIG_FILE, config) != NO_ERROR) &&
            (ConfigParsingUtils::loadConfig(AUDIO_POLICY_CONFIG_FILE, config) != NO_ERROR)) {
#endif
        ALOGE("could not load audio policy configuration file, setting defaults");
        config.setDefault();
    }
    // must be done after reading the policy (since conditionned by Speaker Drc Enabling)
    mVolumeCurves->initializeVolumeCurves(speakerDrcEnabled);
<span class="token comment">// Once policy config has been parsed, retrieve an instance of the engine and initialize it</span>
<span class="token comment">//代理引擎</span>
audio_policy<span class="token punctuation">:</span><span class="token punctuation">:</span>EngineInstance <span class="token operator">*</span>engineInstance <span class="token operator">=</span> audio_policy<span class="token punctuation">:</span><span class="token punctuation">:</span>EngineInstance<span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token function">getInstance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>engineInstance<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token function">ALOGE</span><span class="token punctuation">(</span><span class="token string">"%s:  Could not get an instance of policy engine"</span><span class="token punctuation">,</span> __FUNCTION__<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">// Retrieve the Policy Manager Interface</span>
mEngine <span class="token operator">=</span> engineInstance<span class="token operator">-&gt;</span>queryInterface<span class="token operator">&lt;</span>AudioPolicyManagerInterface<span class="token operator">&gt;</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">-&gt;</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">-&gt;</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">&amp;</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">&lt;</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">-&gt;</span>mHandle <span class="token operator">=</span> mpClientInterface<span class="token operator">-&gt;</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">-&gt;</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">-&gt;</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">-&gt;</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">&lt;</span> mHwModules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-&gt;</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">&lt;</span>IOProfile<span class="token operator">&gt;</span> outProfile <span class="token operator">=</span> mHwModules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-&gt;</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">-&gt;</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">-&gt;</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">-&gt;</span><span class="token function">getFlags</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&amp;</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">-&gt;</span><span class="token function">getFlags</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&amp;</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">-&gt;</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">&amp;</span> mDefaultOutputDevice<span class="token operator">-&gt;</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">-&gt;</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">-&gt;</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">&amp;</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">&lt;</span>SwAudioOutputDescriptor<span class="token operator">&gt;</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">&amp;</span>supportedDevices <span class="token operator">=</span> outProfile<span class="token operator">-&gt;</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">&amp;</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">&gt;</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">-&gt;</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">-&gt;</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">-&gt;</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">-&gt;</span>mChannelMask<span class="token punctuation">;</span>
        config<span class="token punctuation">.</span>format <span class="token operator">=</span> outputDesc<span class="token operator">-&gt;</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">-&gt;</span><span class="token function">openOutput</span><span class="token punctuation">(</span>outProfile<span class="token operator">-&gt;</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">&amp;</span>output<span class="token punctuation">,</span>
                                                        <span class="token operator">&amp;</span>config<span class="token punctuation">,</span>
                                                        <span class="token operator">&amp;</span>outputDesc<span class="token operator">-&gt;</span>mDevice<span class="token punctuation">,</span>
                                                        address<span class="token punctuation">,</span>
                                                        <span class="token operator">&amp;</span>outputDesc<span class="token operator">-&gt;</span>mLatency<span class="token punctuation">,</span>
                                                        outputDesc<span class="token operator">-&gt;</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">-&gt;</span>mDevice<span class="token punctuation">,</span>
                  mHwModules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-&gt;</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">-&gt;</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">-&gt;</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">-&gt;</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">&lt;</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">&gt;=</span> <span class="token number">0</span> <span class="token operator">&amp;&amp;</span> <span class="token operator">!</span>mAvailableOutputDevices<span class="token punctuation">[</span>index<span class="token punctuation">]</span><span class="token operator">-&gt;</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">-&gt;</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">&amp;&amp;</span>
                    outProfile<span class="token operator">-&gt;</span><span class="token function">getFlags</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&amp;</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">-&gt;</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">&lt;</span> mHwModules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-&gt;</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">&lt;</span>IOProfile<span class="token operator">&gt;</span> inProfile <span class="token operator">=</span> mHwModules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">-&gt;</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">-&gt;</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">-&gt;</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">-&gt;</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">&amp;</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">&lt;</span>AudioInputDescriptor<span class="token operator">&gt;</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">-&gt;</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">-&gt;</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">-&gt;</span>mChannelMask<span class="token punctuation">;</span>
        config<span class="token punctuation">.</span>format <span class="token operator">=</span> inputDesc<span class="token operator">-&gt;</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">-&gt;</span><span class="token function">openInput</span><span class="token punctuation">(</span>inProfile<span class="token operator">-&gt;</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">&amp;</span>input<span class="token punctuation">,</span>
                                                       <span class="token operator">&amp;</span>config<span class="token punctuation">,</span>
                                                       <span class="token operator">&amp;</span>inputDesc<span class="token operator">-&gt;</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">&amp;</span>supportedDevices <span class="token operator">=</span> inProfile<span class="token operator">-&gt;</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">&lt;</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">&gt;=</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
                    sp<span class="token operator">&lt;</span>DeviceDescriptor<span class="token operator">&gt;</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">-&gt;</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">-&gt;</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">-&gt;</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">-&gt;</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">&lt;</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">-&gt;</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">-&gt;</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">&lt;</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">-&gt;</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">-&gt;</span><span class="token function">setDeviceConnectionState</span><span class="token punctuation">(</span>mAvailableInputDevices<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">,</span>
                                      AUDIO_POLICY_DEVICE_STATE_AVAILABLE<span class="token punctuation">)</span><span class="token punctuation">;</span>
    i<span class="token operator">++</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token function">updateDevicesAndOutputs</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212

可以看到AudioPolicyManager通过解析Audio配置文件,加载各输入输出音频Module,然后遍历各输入输出设备,找出稳定的设备后,由路由引擎设置各设备的连接状态。在分析AudioFlinger的时候走过 mpClientInterface->openOutput()函数

sp<AudioFlinger::ThreadBase> AudioFlinger::openOutput_l(.....)
{
    //找到Device, 这个函数很重要,稍后分析
    AudioHwDevice *outHwDev = findSuitableHwDev_l(module, devices);
    //音频流输出到硬件设备
    AudioStreamOut *outputStream = NULL;
    status_t status = outHwDev->openOutputStream(
            &outputStream,
            *output,
            devices,
            flags,
            config,
            address.string());
mHardwareStatus <span class="token operator">=</span> AUDIO_HW_IDLE<span class="token punctuation">;</span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

在 createTrack_l()的时候,会去根据流类型来获取路由策略

    uint32_t strategy = AudioSystem::getStrategyForStream(streamType);
        for (size_t i = 0; i < mTracks.size(); ++i) {
            sp<Track> t = mTracks[i];
            if (t != 0 && t->isExternalTrack()) {
            //获取路由策略
                uint32_t actual = AudioSystem::getStrategyForStream(t->streamType());
                if (sessionId == t->sessionId() && strategy != actual) {
                    ALOGE("createTrack_l() mismatched strategy; expected %u but found %u",
                            strategy, actual);
                    lStatus = BAD_VALUE;
                    goto Exit;
                }
            }
        }

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

调用 Audio代理服务的 getStrategyForStream

uint32_t AudioSystem::getStrategyForStream(audio_stream_type_t stream)
{
    const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
    if (aps == 0) return 0;
    return aps->getStrategyForStream(stream);
}

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

具体的实现在AudioPolicyInterfaceImpl.cpp文件中
\frameworks\av\services\audiopolicy\service\AudioPolicyInterfaceImpl.cpp

uint32_t AudioPolicyService::getStrategyForStream(audio_stream_type_t stream)
{
    if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {
        return 0;
    }
    if (mAudioPolicyManager == NULL) {
        return 0;
    }
    return mAudioPolicyManager->getStrategyForStream(stream);
}

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
uint32_t AudioPolicyManager::getStrategyForStream(audio_stream_type_t stream) {
    return (uint32_t)getStrategy(stream);
}

 
 
  • 1
  • 2
  • 3
routing_strategy AudioPolicyManager::getStrategy(audio_stream_type_t stream) const
{
    ALOG_ASSERT(stream != AUDIO_STREAM_PATCH,"getStrategy() called for AUDIO_STREAM_PATCH");
    return mEngine->getStrategyForStream(stream);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

在文件 frameworks\av\services\audiopolicy\managerdefault\AudioPolicyManager.h 中 AudioPolicyManagerInterface *mEngine; 位于frameworks\av\services\audiopolicy\engine\interface\AudioPolicyManagerInterface.h,在frameworks\av\services\audiopolicy\enginedefault\src\Engine.h文件中被实现如下

  /// Interface members
    class ManagerInterfaceImpl : public AudioPolicyManagerInterface
    {
    public:
        explicit ManagerInterfaceImpl(Engine *policyEngine)
            : mPolicyEngine(policyEngine) {}
    <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
    virtual routing_strategy <span class="token function">getStrategyForStream</span><span class="token punctuation">(</span>audio_stream_type_t stream<span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        <span class="token keyword">return</span> mPolicyEngine<span class="token operator">-&gt;</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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值