一、获取xml文件1.启动audioserviceframeworks/av/media/audioserver/main_audioserver.cpp //main函数中定义一个对象 const auto aps spAudioPolicyService::make();2.执行构造函数并mCreateAudioPolicyManager(createAudioPolicyManager)进行初始化frameworks/av/services/audiopolicy/service/AudioPolicyService.cpp AudioPolicyService::AudioPolicyService()3.调用void AudioPolicyService::onFirstRef()函数void AudioPolicyService::onFirstRef() { ...... mAudioPolicyManager mCreateAudioPolicyManager(mAudioPolicyClient); ...... }4.解析配置文件audio policy config xmlstatic AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface) { AudioPolicyManager *apm nullptr; media::AudioPolicyConfig apmConfig; if (status_t status clientInterface-getAudioPolicyConfig(apmConfig); status OK) { ...... } else { auto config AudioPolicyConfig::loadFromApmXmlConfigWithFallback(); // This cant fail.解析配置文件audio policy config xml ...... } }spconst AudioPolicyConfig AudioPolicyConfig::loadFromApmXmlConfigWithFallback( const std::string xmlFilePath) { const std::string filePath xmlFilePath.empty() ? audio_get_audio_policy_config_file() : xmlFilePath;//获取xml文件 auto config spAudioPolicyConfig::make(); if (status_t status config-loadFromXml(filePath, false /*forVts*/); status NO_ERROR) { return config; } return createDefault(); }static inline std::string audio_get_audio_policy_config_file() { static constexpr const char *apmXmlConfigFileName audio_policy_configuration.xml; static constexpr const char *apmA2dpOffloadDisabledXmlConfigFileName audio_policy_configuration_a2dp_offload_disabled.xml; static constexpr const char *apmLeOffloadDisabledXmlConfigFileName audio_policy_configuration_le_offload_disabled.xml; static constexpr const char *apmBluetoothLegacyHalXmlConfigFileName audio_policy_configuration_bluetooth_legacy_hal.xml; std::string audioPolicyXmlConfigFile; // First try alternative files if needed if (property_get_bool(ro.bluetooth.a2dp_offload.supported, false)) { if (property_get_bool(persist.bluetooth.bluetooth_audio_hal.disabled, false) property_get_bool(persist.bluetooth.a2dp_offload.disabled, false)) { // Both BluetoothAudio2.0 and BluetoothA2dp1.0 (Offload) are disabled, and uses // the legacy hardware module for A2DP and hearing aid. audioPolicyXmlConfigFile audio_find_readable_configuration_file( apmBluetoothLegacyHalXmlConfigFileName); } else if (property_get_bool(persist.bluetooth.a2dp_offload.disabled, false)) { // A2DP offload supported but disabled: try to use special XML file // assume that if a2dp offload is not supported, le offload is not supported as well audioPolicyXmlConfigFile audio_find_readable_configuration_file( apmA2dpOffloadDisabledXmlConfigFileName); } else if (!property_get_bool(ro.bluetooth.leaudio_offload.supported, false) || property_get_bool(persist.bluetooth.leaudio_offload.disabled, false)) { // A2DP offload supported but LE offload disabled: try to use special XML file audioPolicyXmlConfigFile audio_find_readable_configuration_file( apmLeOffloadDisabledXmlConfigFileName); } } else if (property_get_bool(persist.bluetooth.bluetooth_audio_hal.disabled, false)) { audioPolicyXmlConfigFile audio_find_readable_configuration_file( apmBluetoothLegacyHalXmlConfigFileName); } else { audioPolicyXmlConfigFile audio_find_readable_configuration_file( apmA2dpOffloadDisabledXmlConfigFileName); } return audioPolicyXmlConfigFile.empty() ? audio_find_readable_configuration_file(apmXmlConfigFileName) : audioPolicyXmlConfigFile; } }static inline std::string audio_find_readable_configuration_file(const char* fileName) { for (const auto path : audio_get_configuration_paths()) { std::string tryPath path / fileName; if (audio_is_readable_configuration_file(tryPath.c_str())) { return tryPath; } } return {}; }//最后加载vendor/etc/audio_policy_configuration.xml,具体是哪个路径根据代码而定5.回到createAudioPolicyManager函数apm new AudioPolicyManager(config, loadApmEngineLibraryAndCreateEngine(config-getEngineLibraryNameSuffix()), clientInterface);//最终加载/vendor/etc/audio_policy_engine_configuration.xml有的平台会客制化这部分二、解析xml1.入口deserializeAudioPolicyFile函数此时的filename为audio_policy_configuration.xml//frameworks/av/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp status_t deserializeAudioPolicyFile(const char *fileName, AudioPolicyConfig *config) { PolicySerializer serializer; status_t status serializer.deserialize(fileName, config); return status; }2.调用deserialize解析xml把xml的节点都解析出来auto doc make_xmlUnique(xmlParseFile(configFile));//解析 XML 文件 (libxml2)3. 获取xml根节点xmlNodePtr root xmlDocGetRootElement(doc.get());4.解析include xml文件xmlXIncludeProcess(doc.get())//比如xi:include hrefprimary_audio_policy_configuration.xml/5.验证根元素和版本xmlStrcmp(root-name, reinterpret_castconst xmlChar*(rootName));//rootname audioPolicyConfiguration std::string version getXmlAttribute(root, versionAttribute);//versionAttribute version6.开始解析modulesstatus_t status deserializeCollectionModuleTraits(root, modules, config);//传入的是modules7.看deserializeCollection函数for (cur cur-xmlChildrenNode; cur ! NULL; cur cur-next) {//遍历之前解析xml的节点比如modulesglobalConfiguration等 const xmlNode *child NULL; if (!xmlStrcmp(cur-name, reinterpret_castconst xmlChar*(Trait::collectionTag))) {//与collectionTag相比较判断是否是modules child cur-xmlChildrenNode; } else if (!xmlStrcmp(cur-name, reinterpret_castconst xmlChar*(Trait::tag))) { child cur; } for (; child ! NULL; child child-next) {//遍历modules下的节点 if (!xmlStrcmp(child-name, reinterpret_castconst xmlChar*(Trait::tag))) {//与tag相比较即判断是否是module如果是则继续往下走 auto maybeElement deserializeTrait(child, serializingContext); if (maybeElement.index() 1) { status_t status Trait::addElementToCollection( std::get1(maybeElement), collection); if (status ! NO_ERROR) { ALOGE(%s: could not add element to %s collection, __func__, Trait::collectionTag); return status; } } else if (mIgnoreVendorExtensions std::getstatus_t(maybeElement) NO_INIT) { // Skip a vendor extension element. } else { return BAD_VALUE; } } }8.继续看deserialize文件此时是module模块的则调用module模块的deserialize函数template std::variantstatus_t, ModuleTraits::Element PolicySerializer::deserializeModuleTraits( const xmlNode *cur, ModuleTraits::PtrSerializingCtx ctx) { using Attributes ModuleTraits::Attributes; auto tag ModuleTraits::tag; auto childAttachedDevicesTag ModuleTraits::childAttachedDevicesTag; auto childAttachedDeviceTag ModuleTraits::childAttachedDeviceTag; auto childDefaultOutputDeviceTag ModuleTraits::childDefaultOutputDeviceTag; std::string name getXmlAttribute(cur, Attributes::name);//获取属性name的值即为primary if (name.empty()) { ALOGE(%s: No %s found, __func__, Attributes::name); return BAD_VALUE; } uint32_t versionMajor 0, versionMinor 0; std::string versionLiteral getXmlAttribute(cur, Attributes::version);//获取属性halVersion的值即为2.0 if (!versionLiteral.empty()) { sscanf(versionLiteral.c_str(), %u.%u, versionMajor, versionMinor); ALOGV(%s: mHalVersion major %u minor %u, __func__, versionMajor, versionMajor); } ALOGD(%s: %s %s%s, __func__, ModuleTraits::tag, Attributes::name, name.c_str()); ModuleTraits::Element module new HwModule(name.c_str(), versionMajor, versionMinor); // Deserialize children: Audio Mix Port, Audio Device Ports (Source/Sink), Audio Routes MixPortTraits::Collection mixPorts; status_t status deserializeCollectionMixPortTraits(cur, mixPorts, NULL);//解析mixPorts参数 if (status ! NO_ERROR) { return status; } module-setProfiles(mixPorts); DevicePortTraits::Collection devicePorts; status deserializeCollectionDevicePortTraits(cur, devicePorts, NULL); if (status ! NO_ERROR) { return status; } module-setDeclaredDevices(devicePorts); RouteTraits::Collection routes; status deserializeCollectionRouteTraits(cur, routes, module.get()); if (status ! NO_ERROR) { return status; } module-setRoutes(routes); for (const xmlNode *children cur-xmlChildrenNode; children ! NULL; children children-next) { if (!xmlStrcmp(children-name, reinterpret_castconst xmlChar*(childAttachedDevicesTag))) { ALOGD(%s: %s %s found, __func__, tag, childAttachedDevicesTag); for (const xmlNode *child children-xmlChildrenNode; child ! NULL; child child-next) { if (!xmlStrcmp(child-name, reinterpret_castconst xmlChar*(childAttachedDeviceTag))) { //MIUI ADD: Audio_DecoupledMtk #ifdef XIAOMI_PLATFORM_MTK if (xmlNodeListGetString(child-doc, child-xmlChildrenNode, 1) nullptr) { //MTK_AUDIO ALOGW(%s: 1.Get Null string, __func__); continue; } #endif //END Audio_DecoupledMtk auto attachedDevice make_xmlUnique(xmlNodeListGetString( child-doc, child-xmlChildrenNode, 1)); if (attachedDevice ! nullptr) { ALOGD(%s: %s %s%s, __func__, tag, childAttachedDeviceTag, reinterpret_castconst char*(attachedDevice.get())); spDeviceDescriptor device module-getDeclaredDevices(). getDeviceFromTagName(std::string(reinterpret_castconst char*( attachedDevice.get()))); if (device NULL) { if (mIgnoreVendorExtensions) { ALOGD(%s: skipped attached device \%s\ because it likely uses a vendor extension type, __func__, reinterpret_castconst char*(attachedDevice.get())); } else { ALOGE(%s: got null device in %s, \%s\, __func__, child-name, reinterpret_castconst char*(attachedDevice.get())); } continue; } ctx-addDevice(device); } } } } if (!xmlStrcmp(children-name, reinterpret_castconst xmlChar*(childDefaultOutputDeviceTag))) { //MIUI ADD: Audio_DecoupledMtk #ifdef XIAOMI_PLATFORM_MTK if (xmlNodeListGetString(children-doc, children-xmlChildrenNode, 1) nullptr) { //MTK_AUDIO ALOGW(%s: 2.Get Null string, __func__); continue; } #endif //END Audio_DecoupledMtk auto defaultOutputDevice make_xmlUnique(xmlNodeListGetString( children-doc, children-xmlChildrenNode, 1)); if (defaultOutputDevice ! nullptr) { ALOGD(%s: %s %s%s, __func__, tag, childDefaultOutputDeviceTag, reinterpret_castconst char*(defaultOutputDevice.get())); spDeviceDescriptor device module-getDeclaredDevices().getDeviceFromTagName( std::string(reinterpret_castconst char*(defaultOutputDevice.get()))); if (device ! 0 ctx-getDefaultOutputDevice() 0) { ctx-setDefaultOutputDevice(device); ALOGD(%s: default is %08x, __func__, ctx-getDefaultOutputDevice()-type()); } } } } return module; }9.看deserializeCollection函数此时解析的是mixportsmixPorts mixPort nameprimary output rolesource flagsAUDIO_OUTPUT_FLAG_PRIMARY profile name formatAUDIO_FORMAT_PCM_16_BIT samplingRates48000 channelMasksAUDIO_CHANNEL_OUT_STEREO/ /mixPort mixPortsfor (cur cur-xmlChildrenNode; cur ! NULL; cur cur-next) {//遍历mixports const xmlNode *child NULL; if (!xmlStrcmp(cur-name, reinterpret_castconst xmlChar*(Trait::collectionTag))) {//与collectionTag相比较判断是否是mixports child cur-xmlChildrenNode; } else if (!xmlStrcmp(cur-name, reinterpret_castconst xmlChar*(Trait::tag))) { child cur; } for (; child ! NULL; child child-next) {//遍历mixports下的节点 if (!xmlStrcmp(child-name, reinterpret_castconst xmlChar*(Trait::tag))) {//与tag相比较即判断是否是mixport如果是则继续往下走 auto maybeElement deserializeTrait(child, serializingContext); if (maybeElement.index() 1) { status_t status Trait::addElementToCollection( std::get1(maybeElement), collection); if (status ! NO_ERROR) { ALOGE(%s: could not add element to %s collection, __func__, Trait::collectionTag); return status; } } else if (mIgnoreVendorExtensions std::getstatus_t(maybeElement) NO_INIT) { // Skip a vendor extension element. } else { return BAD_VALUE; } } }