AudioPolicyService启动过程(二)

1. AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface*)

上篇博客中已经分析如何调用到AudioPolicyManager的构造函数,本篇博客就从AudioPolicyManager的构造函数开始谈起。

/frameworks/av/services/audiopolicy/managerdefault/AudioPolicyManager.cpp

AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface)
    :
    mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f),
    mA2dpSuspended(false),
    mAudioPortGeneration(1),
    mBeaconMuteRefCount(0),
    mBeaconPlayingRefCount(0),
    mBeaconMuted(false),
    mTtsOutputAvailable(false),
    mMasterMono(false),
    mMusicEffectOutput(AUDIO_IO_HANDLE_NONE),
    mHasComputedSoundTriggerSupportsConcurrentCapture(false)
{
    ......
    //保存AudioPolicyClient的对象,这个对象很重要,是获取AudioFlinger接口的一个对象
    mpClientInterface = clientInterface;

    //xml文件解析
#ifdef USE_XML_AUDIO_POLICY_CONF

    //如果使用xml来配置的话,则解析audio_policy_configuration.xml文件
    //初始化一个vector audio_stream_type_t类型的stream,用于保存解析到的xml中的stream信息
    mVolumeCurves = new VolumeCurvesCollection();
    AudioPolicyConfig config(mHwModules, mAvailableOutputDevices, mAvailableInputDevices,
                             mDefaultOutputDevice, speakerDrcEnabled,
                             static_cast<VolumeCurvesCollection *>(mVolumeCurves));

    //遍历解析/odm/etc, vendor/etc/audio, vendor/etc/, system/etc这几个目录,如果找到audio_policy_configuration.xml,并解析成功,则break退出
    if (deserializeAudioPolicyXmlConfig(config) != NO_ERROR) {
#else
    //conf文件的解析
    mVolumeCurves = new StreamDescriptorCollection(); 
    AudioPolicyConfig config(mHwModules, mAvailableOutputDevices, mAvailableInputDevices,
                             mDefaultOutputDevice, speakerDrcEnabled);
                             
    //加载并解析conf文件
    //#define AUDIO_POLICY_VENDOR_CONFIG_FILE   "/vendor/etc/audio_policy.conf"
    //#define AUDIO_POLICY_CONFIG_FILE "/system/etc/audio_policy.conf"
    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();
    }
    ........
    for (size_t i = 0; i < mHwModules.size(); i++) {
        //1.加载Moudle
        mHwModules[i]->mHandle = mpClientInterface->loadHwModule(mHwModules[i]->getName());
        .......
        //2.对output的处理
        for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++)
        {
            //获取每个module中的outProfile
            const sp<IOProfile> outProfile = mHwModules[i]->mOutputProfiles[j];

            ......
            //得到支持设备的类型
            audio_devices_t profileType = outProfile->getSupportedDevicesType();
            
            //将输出IOProfile封装为SwAudioOutputDescriptor对象
            //创建一个outputDesc对象,该对象中描述了音频的一些参数,如采样率、通道数以及格式
            sp<SwAudioOutputDescriptor> outputDesc = new SwAudioOutputDescriptor(outProfile,
                                                                                 mpClientInterface);
            ......

            outputDesc->mDevice = profileType;
            audio_config_t config = AUDIO_CONFIG_INITIALIZER;
            config.sample_rate = outputDesc->mSamplingRate;
            config.channel_mask = outputDesc->mChannelMask;
            config.format = outputDesc->mFormat;
            audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
            
            //将调用audioFlinger中的openOutput,打开output,在AudioFlinger中创建PlaybackTread线程,并返回线程的id
            status_t status = mpClientInterface->openOutput(outProfile->getModuleHandle(),
                                                            &output,
                                                            &config,
                                                            &outputDesc->mDevice,
                                                            address,
                                                            &outputDesc->mLatency,
                                                            outputDesc->mFlags);

                .......
                //将输出描述符对象SwAudioOutputDescriptor及创建的PlaybackTread线程id以键值对形式保存
                addOutput(output, outputDesc);
                setOutputDevice(outputDesc,
                                outputDesc->mDevice,
                                true,
                                0,
                                NULL,
                                address.string());
            }
        }
        // open input streams needed to access attached devices to validate
        // mAvailableInputDevices list
        //3.input的处理
        for (size_t j = 0; j < mHwModules[i]->mInputProfiles.size(); j++)
        {
            //获取每个module中的inProfile
            const sp<IOProfile> inProfile = mHwModules[i]->mInputProfiles[j];

            // chose first device present in profile's SupportedDevices also part of
            // inputDeviceTypes
            //获取所支持的设备
            audio_devices_t profileType = inProfile->getSupportedDeviceForType(inputDeviceTypes);

            //将输入IOProfile封装成AudioInputDescriptor对象
            sp<AudioInputDescriptor> inputDesc =
                    new AudioInputDescriptor(inProfile);

            inputDesc->mDevice = profileType;
            audio_config_t config = AUDIO_CONFIG_INITIALIZER;
            config.sample_rate = inputDesc->mSamplingRate;
            config.channel_mask = inputDesc->mChannelMask;
            config.format = inputDesc->mFormat;
            audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
            
            //将调用AudioFlinger中的openInput,在audioFlinger中创建recordThread线程,并返回其id
            status_t status = mpClientInterface->openInput(inProfile->getModuleHandle(),
                                                           &input,
                                                           &config,
                                                           &inputDesc->mDevice,
                                                           address,
                                                           AUDIO_SOURCE_MIC,
                                                           AUDIO_INPUT_FLAG_NONE);

            if (status == NO_ERROR) {
                const DeviceVector &supportedDevices = inProfile->getSupportedDevices();
                for (size_t k = 0; k  < supportedDevices.size(); k++) {
                    ssize_t index =  mAvailableInputDevices.indexOf(supportedDevices[k]);
                    // give a valid ID to an attached device once confirmed it is reachable
                    if (index >= 0) {
                        sp<DeviceDescriptor> devDesc = mAvailableInputDevices[index];
                        if (!devDesc->isAttached()) {
                            devDesc->attach(mHwModules[i]);
                            devDesc->importAudioPort(inProfile, true);
                        }
                    }
                }
                mpClientInterface->closeInput(input);
            } 
        }
    }
    .........

}

 2. mpClientInterface->函数(...)

2.1 mpClientInterface->loadHwModule(...)

这个地方会调用到AudioFlinger中的loadHwModule函数,为什么?

mpClientInterface是由clientInterface赋值的。

看一下函数的调用流程:

mAudioPolicyClient = new AudioPolicyClient(this)------->createAudioPolicyManager(mAudioPolicyClient)-------->new AudioPolicyManager(clientInterface),因此mpClientInterface->loadHwModule实际上是调用了AudioPolicyClient类中的成员函数。

/frameworks/av/services/audiopolicy/service/AudioPolicyClientImpl.cpp

audio_module_handle_t AudioPolicyService::AudioPolicyClient::loadHwModule(const char *name)
{
    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
    ......
    return af->loadHwModule(name);
}

从上面的代码可以看出,最终调用了AudioFlinger中的loadHwModule函数。在AudioFlinger的博客中再重点分析此函数。

2.2 mpClientInterface->openOutput(...)

/frameworks/av/services/audiopolicy/service/AudioPolicyClientImpl.cpp

status_t AudioPolicyService::AudioPolicyClient::openOutput(audio_module_handle_t module,
                                                           audio_io_handle_t *output,
                                                           audio_config_t *config,
                                                           audio_devices_t *devices,
                                                           const String8& address,
                                                           uint32_t *latencyMs,
                                                           audio_output_flags_t flags)
{
    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
    ......
    return af->openOutput(module, output, config, devices, address, latencyMs, flags);
}

最终调用到了AudioFlinger中的openOutput函数

2.3 mpClientInterface->openInput(...)

status_t AudioPolicyService::AudioPolicyClient::openInput(audio_module_handle_t module,
                                                          audio_io_handle_t *input,
                                                          audio_config_t *config,
                                                          audio_devices_t *device,
                                                          const String8& address,
                                                          audio_source_t source,
                                                          audio_input_flags_t flags)
{
    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
    ......
    return af->openInput(module, input, config, device, address, source, flags);
}

最终调用到AudioFlinger中的openInput函数。

3. XML配置文件解析

deserializeAudioPolicyXmlConfig函数用于解析xml文件,在该函数中,会依次解析/odm/etc/, /vendor/etc/audio/, /vendor/etc/, /system/etc这几个目录,如果找到audio_policy_configuration.xml文件,并解析成功,则break退出。

在android中,该文件的默认存放路径如下:

/frameworks/av/services/audiopolicy/config/audio_policy_configuration.xml

但是我们一般不会使用android自带的xml文件,而是使用厂家提供的。我们以SDM429W平台为例,厂家提供的xml文件路径如下:

/hardware/qcom/audio/configs/msm8937/audio_policy_configuration.xml

经编译后,被放到了目录:

/vendor/etc/audio/audio_policy_configuration.xml

/vendor/etc/audio_policy_configuraiton.xml

 在代码中,通过宏USE_XML_AUDIO_POLICY_CONF来决定使用audio_policy.conf文件还是audio_policy_configuraiton.xml文件。该宏定义在:

/hardware/qcom/audio/configs/msm8937/msm8937.mk中

USE_XML_AUDIO_POLICY_CONF := 1

此时言归正传,回到函数 deserializeAudioPolicyXmlConfig

/frameworks/av/services/audiopolicy/managerdefault/AudioPolicyManager.cpp

#define AUDIO_POLICY_XML_CONFIG_FILE_PATH_MAX_LENGTH 128
#define AUDIO_POLICY_XML_CONFIG_FILE_NAME "audio_policy_configuration.xml"


#ifdef USE_XML_AUDIO_POLICY_CONF
// Treblized audio policy xml config will be located in /odm/etc or /vendor/etc.
static const char *kConfigLocationList[] =
        {"/odm/etc", "/vendor/audio/etc","/vendor/etc", "/system/etc"};
static const int kConfigLocationListSize =
        (sizeof(kConfigLocationList) / sizeof(kConfigLocationList[0]));

static status_t deserializeAudioPolicyXmlConfig(AudioPolicyConfig &config) {
    char audioPolicyXmlConfigFile[AUDIO_POLICY_XML_CONFIG_FILE_PATH_MAX_LENGTH];
    status_t ret;

    for (int i = 0; i < kConfigLocationListSize; i++) {
        PolicySerializer serializer;
        snprintf(audioPolicyXmlConfigFile,
                 sizeof(audioPolicyXmlConfigFile),
                 "%s/%s",
                 kConfigLocationList[i],
                 AUDIO_POLICY_XML_CONFIG_FILE_NAME);
        ret = serializer.deserialize(audioPolicyXmlConfigFile, config);
        if (ret == NO_ERROR) {
            break;
        }
    }
    return ret;
}
#endif
deserialize函数是解析XML的关键,不过这个函数非常复杂。对于这个函数的解析过程,可参考https://blog.csdn.net/qq_33750826/article/details/97757590
posted @ 2021-01-09 23:33  一代枭雄  阅读(843)  评论(0编辑  收藏  举报