admin管理员组

文章数量:1130349

在启动AudioPolicyService时,通过EngineBase的loadAudioPolicyEngineConfig函数去解析strategy配置。其调用流程如下


接下来就对loadAudioPolicyEngineConfig展开分析
1,解析volume标签

engineConfig::ParsingResult EngineBase::loadAudioPolicyEngineConfig()
{
   
   
	//省略
	auto result = engineConfig::parse();//1
    if (result.parsedConfig == nullptr) {
   
   
        engineConfig::Config config = gDefaultEngineConfig;//2
        android::status_t ret = engineConfig::parseLegacyVolumes(config.volumeGroups);//3
        result = {
   
   std::make_unique<engineConfig::Config>(config),
                  static_cast<size_t>(ret == NO_ERROR ? 0 : 1)};
    } else {
   
   
       //省略
    }
	//省略
}

注释1处,parse函数会去解析/vendor/etc/audio_policy_engine_configuration.xml 文件,我的Android 11 源码环境没有这个文件,所以会进入if分支。注释2处设置默认配置为gDefaultEngineConfig。注释3处调用parseLegacyVolumes去解析audio_policy_configuration.xml文件下的volume标签。

parseLegacyVolumes找到audio_policy_configuration.xml文件后,调用到deserializeLegacyVolumeCollection函数继续解析

//frameworks/av/services/audiopolicy/engine/config/src/EngineConfig.cpp
static status_t deserializeLegacyVolumeCollection(_xmlDoc *doc, const _xmlNode *cur,
                                                  VolumeGroups &volumeGroups,
                                                  size_t &nbSkippedElement)
{
   
   
    std::map<std::string, VolumeCurves> legacyVolumeMap;
    for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) {
   
   
        if (xmlStrcmp(cur->name, (const xmlChar *)legacyVolumecollectionTag)) {
   
   //legacyVolumecollectionTag:volumes
            continue;
        }
        const xmlNode *child = cur->xmlChildrenNode;
        for (; child != NULL; child = child->next) {
   
   
            if (!xmlStrcmp(child->name, (const xmlChar *)legacyVolumeTag)) {
   
   //legacyVolumeTag:volume

                status_t status = deserializeLegacyVolume(doc, child, legacyVolumeMap);//1
                if (status != NO_ERROR) {
   
   
                    nbSkippedElement += 1;
                }
            }
        }
    }
    for (const auto &volumeMapIter : legacyVolumeMap) {
   
   
     	//省略
        int indexMin = streamType >= AUDIO_STREAM_PUBLIC_CNT ? 0 : -1;
        int indexMax = streamType >= AUDIO_STREAM_PUBLIC_CNT ? 100 : -1;
        volumeGroups.push_back({
   
    volumeMapIter.first, indexMin, indexMax, volumeMapIter.second }

在启动AudioPolicyService时,通过EngineBase的loadAudioPolicyEngineConfig函数去解析strategy配置。其调用流程如下


接下来就对loadAudioPolicyEngineConfig展开分析
1,解析volume标签

engineConfig::ParsingResult EngineBase::loadAudioPolicyEngineConfig()
{
   
   
	//省略
	auto result = engineConfig::parse();//1
    if (result.parsedConfig == nullptr) {
   
   
        engineConfig::Config config = gDefaultEngineConfig;//2
        android::status_t ret = engineConfig::parseLegacyVolumes(config.volumeGroups);//3
        result = {
   
   std::make_unique<engineConfig::Config>(config),
                  static_cast<size_t>(ret == NO_ERROR ? 0 : 1)};
    } else {
   
   
       //省略
    }
	//省略
}

注释1处,parse函数会去解析/vendor/etc/audio_policy_engine_configuration.xml 文件,我的Android 11 源码环境没有这个文件,所以会进入if分支。注释2处设置默认配置为gDefaultEngineConfig。注释3处调用parseLegacyVolumes去解析audio_policy_configuration.xml文件下的volume标签。

parseLegacyVolumes找到audio_policy_configuration.xml文件后,调用到deserializeLegacyVolumeCollection函数继续解析

//frameworks/av/services/audiopolicy/engine/config/src/EngineConfig.cpp
static status_t deserializeLegacyVolumeCollection(_xmlDoc *doc, const _xmlNode *cur,
                                                  VolumeGroups &volumeGroups,
                                                  size_t &nbSkippedElement)
{
   
   
    std::map<std::string, VolumeCurves> legacyVolumeMap;
    for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) {
   
   
        if (xmlStrcmp(cur->name, (const xmlChar *)legacyVolumecollectionTag)) {
   
   //legacyVolumecollectionTag:volumes
            continue;
        }
        const xmlNode *child = cur->xmlChildrenNode;
        for (; child != NULL; child = child->next) {
   
   
            if (!xmlStrcmp(child->name, (const xmlChar *)legacyVolumeTag)) {
   
   //legacyVolumeTag:volume

                status_t status = deserializeLegacyVolume(doc, child, legacyVolumeMap);//1
                if (status != NO_ERROR) {
   
   
                    nbSkippedElement += 1;
                }
            }
        }
    }
    for (const auto &volumeMapIter : legacyVolumeMap) {
   
   
     	//省略
        int indexMin = streamType >= AUDIO_STREAM_PUBLIC_CNT ? 0 : -1;
        int indexMax = streamType >= AUDIO_STREAM_PUBLIC_CNT ? 100 : -1;
        volumeGroups.push_back({
   
    volumeMapIter.first, indexMin, indexMax, volumeMapIter.second }

本文标签: AndroidStrategyAudio