Android audio_policy_configuration.xml加载流程_xmlxincludeprocess
目录
一、audio_policy_configuration.xml文件被加载流程
1、AudioPolicyService 创建阶段
2、createAudioPolicyManager 实现
3、AudioPolicyManager 构造
4、配置文件解析 loadConfig
5、核心解析逻辑 PolicySerializer::deserialize
二、AudioPolicyConfig类解析
1、AudioPolicyConfig 类定义
2、module标签
3、MixPort标签
4、DevicePort标签
5、route标签
一、audio_policy_configuration.xml文件被加载流程
1、AudioPolicyService 创建阶段
文件路径:frameworks/av/services/audiopolicy/service/AudioPolicyService.cpp
void AudioPolicyService::onFirstRef() { mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient);}
系统服务启动后,调用 createAudioPolicyManager
,创建 AudioPolicyManager
对象。
2、createAudioPolicyManager 实现
extern \"C\" AudioPolicyInterface* createAudioPolicyManager( AudioPolicyClientInterface *clientInterface) { AudioPolicyManager *apm = new AudioPolicyManager(clientInterface); status_t status = apm->initialize(); if (status != NO_ERROR) { delete apm; apm = nullptr; } return apm;}
作用:
-
创建
AudioPolicyManager
; -
立即调用
initialize()
初始化流程; -
如果失败,释放资源
3、AudioPolicyManager 构造
文件:
frameworks/av/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface) : AudioPolicyManager(clientInterface, false /*forTesting*/){ loadConfig();}void AudioPolicyManager::loadConfig() { if (deserializeAudioPolicyXmlConfig(getConfig()) != NO_ERROR) { ALOGE(\"could not load audio policy configuration file, setting defaults\"); getConfig().setDefault(); }}
构造时直接调用 loadConfig()
,开始读取音频配置文件。
4、配置文件解析 loadConfig
文件:
frameworks/av/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
status_t deserializeAudioPolicyFile(const char *fileName, AudioPolicyConfig *config) { PolicySerializer serializer; return serializer.deserialize(fileName, config);}
调用 PolicySerializer::deserialize
,使用 libxml2 解析音频 XML 配置文件。
5、核心解析逻辑 PolicySerializer::deserialize
status_t PolicySerializer::deserialize(const char *configFile, AudioPolicyConfig *config){ // 使用智能指针包装 libxml2 的解析接口,解析传入的 XML 文件 auto doc = make_xmlUnique(xmlParseFile(configFile)); if (doc == nullptr) { // 如果解析失败,打印错误并返回 BAD_VALUE ALOGE(\"%s: Could not parse %s document.\", __func__, configFile); return BAD_VALUE; } // 获取 XML 文档的根节点 xmlNodePtr root = xmlDocGetRootElement(doc.get()); if (root == NULL) { // 如果根节点为空,打印错误并返回 BAD_VALUE ALOGE(\"%s: Could not parse %s document: empty.\", __func__, configFile); return BAD_VALUE; } // 处理 XInclude(XML文件可以引用其他XML文件的机制) if (xmlXIncludeProcess(doc.get()) name, reinterpret_cast(rootName))) { ALOGE(\"%s: No %s root element found in xml data %s.\", __func__, rootName, reinterpret_cast(root->name)); return BAD_VALUE; } // 获取根节点的 version 属性 std::string version = getXmlAttribute(root, versionAttribute); if (version.empty()) { // 如果 version 属性不存在,返回错误 ALOGE(\"%s: No version found in root node %s\", __func__, rootName); return BAD_VALUE; } // 验证版本是否与期望版本一致 if (version != mVersion) { ALOGE(\"%s: Version does not match; expect %s got %s\", __func__, mVersion.c_str(), version.c_str()); return BAD_VALUE; } // 开始解析子节点 // Step 1: 解析 Module 列表 ModuleTraits::Collection modules; status_t status = deserializeCollection(root, &modules, config); if (status != NO_ERROR) { // 如果模块解析失败,直接返回错误状态 return status; } // 将解析到的模块设置到 config 对象中 config->setHwModules(modules); // Step 2: 解析全局配置 GlobalConfigTraits::deseria
功能拆解:
-
xmlParseFile
:加载并解析 XML 文件。 -
xmlDocGetRootElement
:获取根节点,确保结构有效。 -
xmlXIncludeProcess
:处理 XInclude,允许配置文件嵌套引用子文件。 -
验证 root 名称、版本号。
如果通过校验,进入内容解析:
deserializeCollection(root, &modules, config);config->setHwModules(modules);GlobalConfigTraits::deserialize(root, config);SurroundSoundTraits::deserialize(root, config);
经过以上代码之后,最终audio_policy_configuration.xml配置文件会转化为以下的C++类AudioPolicyConfig。
二、AudioPolicyConfig类解析
audio_policy_configuration.xml配置文件配置了Android Audio的设备、流以及设备和流之间的路由等相关信息。写明了Android Audio支持哪些设备、哪些流以及它们支持的编码格式、采样率等信息。文件大致内容如下。
1、AudioPolicyConfig
类定义
class AudioPolicyConfig { static const constexpr char* const kDefaultEngineLibraryNameSuffix = \"default\"; std::string mSource; //为config字符串目录,一般在odm/etc、/vendor/etc、/system/etc下的audio_policy_configuration.xml std::string mEngineLibraryNameSuffix; HwModuleCollection &mHwModules; //保存了配置文件中所有的所有module标签集合,每个module标签对应一个HwModule类 DeviceVector &mOutputDevices; //attchedDevices标签中,设备名称名字和devicePort标签的tagName相同,且type中有OUT字眼的DeviceDescriptor实体类集合 DeviceVector &mInputDevices; //attchedDevices标签中,设备名称名字和devicePort标签的tagName相同,且type中有in字眼的DeviceDescriptor实体类集合 sp &mDefaultOutputDevice; //保存defaultOutputDevice标签内名字和devicePort标签的tagName相同 // TODO: remove when legacy conf file is removed. true on devices that use DRC on the // DEVICE_CATEGORY_SPEAKER path to boost soft sounds, used to adjust volume curves accordingly. // Note: remove also speaker_drc_enabled from global configuration of XML config file. bool mIsSpeakerDrcEnabled; bool mIsCallScreenModeSupported; SurroundFormats mSurroundFormats;};
Speaker Built-In Mic Built-In Back Mic Speaker …… …… …… ……
2、module标签
每个module标签对应着相应的hal层实现,如primary、usb、a2dp等
Speaker Built-In Mic Built-In Back Mic …… ……
module标签对应C++实体类HWModule。
class HwModule { const String8 mName; // hal层模块对应的module名字(primary, a2dp ...) audio_module_handle_t mHandle; OutputProfileCollection mOutputProfiles; // mixport标签role为source类型,对应IOProfle实体类集合 InputProfileCollection mInputProfiles; // mixport标签role为sink的类型,对应IOProfle实体类集合 uint32_t mHalVersion; // hal层模块的版本信息 DeviceVector mDeclaredDevices; // 所有的deviceport标签,对应DeviceDescriptor实体类的集合 DeviceVector mDynamicDevices; /**< devices that can be added/removed at runtime (e.g. rsbumix)*/ AudioRouteVector mRoutes; // 所有的route PolicyAudioPortVector mPorts; // 所有的mixport,deviceport标签对应的实体类,因为IOProfle和DeviceDescriptor都继承了AudioPort,所以相当于这是一个AudioPort集合};
3、MixPort标签
mixport标签可以理解为stream流,配置了相应的格式、采样率以及mask,且分为输出、输入流。一个mixport标签可能有多个profile属性,也就是支持很多编码格式等属性。
一个mixport标签对应一个IOProfile实体类。
class IOProfile : public AudioPort, public PolicyAudioPort { // 可以同时打开的流的最大数量,默认为1。赋值为0时,表示无穷大。 uint32_t maxOpenCount; // 目前已打开的流的数量。 uint32_t curOpenCount; // 同时处于活跃状态的流的最大数量,默认为1。赋值为0时,表示无穷大。 uint32_t maxActiveCount; // 正处于活跃状态的流的数量。 针对于Hal层的流而言。 uint32_t curActiveCount; private: /** 当前流支持的设备集合; * 如果是sink输入流,查找规则如下: * 1. 遍历其父类的成员mRoutes,因为是输入流,所以遍历mRoute集合中sink为自己的route,也就是找有哪些源source设备把数据传给自己。 * 2. 找到route后,根据route中source保存的对象,且对象type是AUDIO_PORT_TYPE_DEVICE类型(就是devicesPort标签对应的实体类DeviceDescriptor) * 3. 把DeviceDescriptor保存在集合中,保存在以下mSupportedDevices中,作为其支持的设备; * 输出流,同理;最终的结果就是: * 作为输出流source,mSupportedDevices保存此流可以输出到对应的device,stream -> device * 作为输入流sink,mSupportedDevices保存了其他device能输出数据到此流, device -> stream **/ DeviceVector mSupportedDevices;}; class AudioPort : public virtual RefBase, public virtual Parcelable{ AudioGains mGains; // gain controllersprotected: std::string mName; // 对应mixport的name audio_port_type_t mType; // AUDIO_PORT_TYPE_MIX (此处固定) audio_port_role_t mRole; // AUDIO_PORT_ROLE_SOURCE/AUDIO_PORT_ROLE_SINK(由mixport的role决定) AudioProfileVector mProfiles; // AudioProfile的集合,对应mixport里面的多个profile // Audio capabilities that are defined by hardware descriptors when the format is unrecognized // by the platform, e.g. short audio descriptor in EDID for HDMI. std::vector mExtraAudioDescriptors;}; class PolicyAudioPort : public virtual RefBase, private HandleGenerator
mixport内部的Profile标签对应的C++类AudioProfile 如下。在解析以上标签至profile时,会单独创建AudioProfile。
class AudioProfile final : public RefBase, public Parcelable{ std::string mName; // profile的name // 以下三个变量对应配置文件中profile中的置,由初始化时进行赋值 audio_format_t mFormat; // The format for an audio profile should only be set when initialized. ChannelMaskSet mChannelMasks; SampleRateSet mSamplingRates; // 以下三个对应上面三位,如果三位都有值,则为false固定的,如果xml没有指定值,则为true表示是动态的值 bool mIsDynamicFormat = false; bool mIsDynamicChannels = false; bool mIsDynamicRate = false; audio_encapsulation_type_t mEncapsulationType = AUDIO_ENCAPSULATION_TYPE_NONE; AudioProfile() = default; AudioProfile& operator=(const AudioProfile& other);};
4、DevicePort标签
devicePort标签可以理解为一个device设备,设备也分output和input,以type中的关键字“IN”和“OUT”进行区分。
一个devicePort对应一个C++类DeviceDescriptor。
class DeviceDescriptor : public DeviceDescriptorBase, public PolicyAudioPort, public PolicyAudioPortConfig{ std::string mTagName; // 对应的tagName字段 FormatVector mEncodedFormats; // encodedFormats转换的枚举值 audio_format_t mCurrentEncodedFormat; bool mIsDynamic = false; const std::string mDeclaredAddress; // address字段对应的地址}; class DeviceDescriptorBase : public AudioPort, public AudioPortConfig{ AudioDeviceTypeAddr mDeviceTypeAddr; uint32_t mEncapsulationModes = 0; uint32_t mEncapsulationMetadataTypes = 0;}; class AudioPort : public virtual RefBase, public virtual Parcelable{ AudioGains mGains; // gain controllersprotected: std::string mName; // 对应devicePort的name audio_port_type_t mType; // AUDIO_PORT_TYPE_DEVICE(此处固定) audio_port_role_t mRole; // AUDIO_PORT_ROLE_SOURCE/AUDIO_PORT_ROLE_SINK(由mixport的role决定) AudioProfileVector mProfiles; // AudioProfile的集合,对应devicePort里面的多个profile // Audio capabilities that are defined by hardware descriptors when the format is unrecognized // by the platform, e.g. short audio descriptor in EDID for HDMI. std::vector mExtraAudioDescriptors;};
同MixPort一样,devicePort也会解析内部的profile标签,创建新的AudioProfile。
class AudioProfile final : public RefBase, public Parcelable{ std::string mName; // profile的name // 以下三个变量对应配置文件中profile中的置,由初始化时进行赋值 audio_format_t mFormat; // The format for an audio profile should only be set when initialized. ChannelMaskSet mChannelMasks; SampleRateSet mSamplingRates; // 以下三个对应上面三位,如果三位都有值,则为false固定的,如果xml没有指定值,则为true表示是动态的值 bool mIsDynamicFormat = false; bool mIsDynamicChannels = false; bool mIsDynamicRate = false; audio_encapsulation_type_t mEncapsulationType = AUDIO_ENCAPSULATION_TYPE_NONE; AudioProfile() = default; AudioProfile& operator=(const AudioProfile& other);};
5、route标签
route是把deviceport和mixport连接起来的路由,数据由一个stream输出到另一个device,或者从一个device输出到另一个stream。
route标签对应C++的AudioRoute类。
class AudioRoute : public virtual RefBase{ PolicyAudioPortVector mSources; //所有的deviceport、mixport标签转化的实体类都保存到HwModule的mPorts成员了,所以是用name去mPorts里面查找,只是source可能是多个,这里用集合保存 sp mSink; //同上 audio_route_type_t mType; //AUDIO_ROUTE_MIX/AUDIO_ROUTE_MUX:根据type而定是互斥还是可融合};
在Primary的module配置文件中通过如下语句去配置a2dp、usb的module。