前言

说audio_policy_configuration.xml的解析之前,先熟悉下audiopolicy的启动过程,开机时会通过init.rc启动audioservice,audioservice会启动AudioPolicyService,而AudiopolicyService会创建AudioPolicyManager,这样AudioPolicyManager就被初始化了。感兴趣的可看下这个博客有具体的讲解https://blog.csdn.net/Qidi_Hu...

正文

回到AudioPolicyService的onFirstRef()函数中有两句代码

 mAudioPolicyClient = new AudioPolicyClient(this); mAudioPolicyManager =createAudioPolicyManager(mAudioPolicyClient);    

在createAudioPolicyManager函数中会 new AudioPolicyManager(clientInterface)。此刻正式开始了AudioPolicyManager的初始化。
我们看下frameworks/av/services/audiopolicy/managerdefault/AudioPolicyManager.cpp 的源码

AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface): AudioPolicyManager(clientInterface, false /*forTesting*/){    loadConfig();    initialize();}
void AudioPolicyManager::loadConfig() {//Android7.0之后便使用此宏#ifdef USE_XML_AUDIO_POLICY_CONF    if (deserializeAudioPolicyXmlConfig(getConfig()) != NO_ERROR) {#else    if ((ConfigParsingUtils::loadConfig(AUDIO_POLICY_VENDOR_CONFIG_FILE, getConfig()) != NO_ERROR)           && (ConfigParsingUtils::loadConfig(AUDIO_POLICY_CONFIG_FILE, getConfig()) != NO_ERROR)) {#endif        ALOGE("could not load audio policy configuration file, setting defaults");        getConfig().setDefault();    }}

deserializeAudioPolicyXmlConfig函数的getConfig()即AudioPolicyConfig,函数声明在AudioPolicyManager.h文中中

AudioPolicyConfig& getConfig() { return mConfig; }
static status_t deserializeAudioPolicyXmlConfig(AudioPolicyConfig &config) {    char audioPolicyXmlConfigFile[AUDIO_POLICY_XML_CONFIG_FILE_PATH_MAX_LENGTH];    std::vector<const char*> fileNames;    status_t ret;    if (property_get_bool("ro.bluetooth.a2dp_offload.supported", false) &&        property_get_bool("persist.bluetooth.a2dp_offload.disabled", false)) {        // A2DP offload supported but disabled: try to use special XML file        fileNames.push_back(AUDIO_POLICY_A2DP_OFFLOAD_DISABLED_XML_CONFIG_FILE_NAME);    }    //文件名#define AUDIO_POLICY_XML_CONFIG_FILE_NAME "audio_policy_configuration.xml",位于frameworks/av/services/audiopolicy/config/目录下。        fileNames.push_back(AUDIO_POLICY_XML_CONFIG_FILE_NAME);    for (const char* fileName : fileNames) {        for (int i = 0; i < kConfigLocationListSize; i++) {            PolicySerializer serializer;            snprintf(audioPolicyXmlConfigFile, sizeof(audioPolicyXmlConfigFile),                     "%s/%s", kConfigLocationList[i], fileName);            ret = serializer.deserialize(audioPolicyXmlConfigFile, config);            if (ret == NO_ERROR) {                return ret;            }        }    }    return ret;}

今天要说的重点就是这个for循环了,serializer.deserialize(audioPolicyXmlConfigFile, config)

先看下PolicySerializer位于/frameworks/av/services/audiopolicy/common/managerdefinitions/include/目录下
以下举例的所有标签均来自audio_policy_configuration.x下对应的第一行标签

status_t PolicySerializer::deserialize(const char *configFile, AudioPolicyConfig &config){    xmlDocPtr doc;    doc = xmlParseFile(configFile);    if (doc == NULL) {        ALOGE("%s: Could not parse %s document.", __FUNCTION__, configFile);        return BAD_VALUE;    }    xmlNodePtr cur = xmlDocGetRootElement(doc);    if (cur == NULL) {        ALOGE("%s: Could not parse %s document: empty.", __FUNCTION__, configFile);        xmlFreeDoc(doc);        return BAD_VALUE;    }    if (xmlXIncludeProcess(doc) < 0) {         ALOGE("%s: libxml failed to resolve XIncludes on %s document.", __FUNCTION__, configFile);    }    if (xmlStrcmp(cur->name, (const xmlChar *) mRootElementName.c_str()))  {        ALOGE("%s: No %s root element found in xml data %s.", __FUNCTION__, mRootElementName.c_str(),              (const char *)cur->name);        xmlFreeDoc(doc);        return BAD_VALUE;    }    string version = getXmlAttribute(cur, versionAttribute);    if (version.empty()) {        ALOGE("%s: No version found in root node %s", __FUNCTION__, mRootElementName.c_str());        return BAD_VALUE;    }    if (version != mVersion) {        ALOGE("%s: Version does not match; expect %s got %s", __FUNCTION__, mVersion.c_str(),              version.c_str());        return BAD_VALUE;    }    //上面都是解析校验xml的一些属性标签啥的,此处开始才是正式加载,首先是module的加载    // Lets deserialize children    // Modules    ModuleTraits::Collection modules;    deserializeCollection<ModuleTraits>(doc, cur, modules, &config);    config.setHwModules(modules);    // deserialize volume section    VolumeTraits::Collection volumes;    deserializeCollection<VolumeTraits>(doc, cur, volumes, &config);    config.setVolumes(volumes);    // Global Configuration    GlobalConfigTraits::deserialize(cur, config);    xmlFreeDoc(doc);    return android::OK;}

其中这两行代码便开始了真正的解析

   deserializeCollection<ModuleTraits>(doc, cur, modules, &config);    config.setHwModules(modules);

deserializeCollection是个通用方法

template <class Trait>static status_t deserializeCollection(_xmlDoc *doc, const _xmlNode *cur,                                      typename Trait::Collection &collection,                                      typename Trait::PtrSerializingCtx serializingContext){    const xmlNode *root = cur->xmlChildrenNode;    while (root != NULL) {        if (xmlStrcmp(root->name, (const xmlChar *)Trait::collectionTag) &&                xmlStrcmp(root->name, (const xmlChar *)Trait::tag)) {            root = root->next;            continue;        }        const xmlNode *child = root;        if (!xmlStrcmp(child->name, (const xmlChar *)Trait::collectionTag)) {            child = child->xmlChildrenNode;        }        while (child != NULL) {            if (!xmlStrcmp(child->name, (const xmlChar *)Trait::tag)) {                typename Trait::PtrElement element;                status_t status = Trait::deserialize(doc, child, element, serializingContext);                if (status != NO_ERROR) {                    return status;                }                if (collection.add(element) < 0) {                    ALOGE("%s: could not add element to %s collection", __FUNCTION__,                          Trait::collectionTag);                }            }            child = child->next;        }        if (!xmlStrcmp(root->name, (const xmlChar *)Trait::tag)) {            return NO_ERROR;        }        root = root->next;    }    return NO_ERROR;}
const char *const ModuleTraits::childAttachedDevicesTag = "attachedDevices";const char *const ModuleTraits::childAttachedDeviceTag = "item";const char *const ModuleTraits::childDefaultOutputDeviceTag = "defaultOutputDevice";const char *const ModuleTraits::tag = "module";const char *const ModuleTraits::collectionTag = "modules";const char ModuleTraits::Attributes::name[] = "name";const char ModuleTraits::Attributes::version[] = "halVersion";status_t ModuleTraits::deserialize(xmlDocPtr doc, const xmlNode *root, PtrElement &module,                                   PtrSerializingCtx ctx){    //解析modules下的module标签,我们可以看下configuration.xml下module的name是primary,当我们如果需要修改时记得module标签里的name一定不能为空    string name = getXmlAttribute(root, Attributes::name);    if (name.empty()) {        ALOGE("%s: No %s found", __FUNCTION__, Attributes::name);        return BAD_VALUE;    }    uint32_t versionMajor = 0, versionMinor = 0;    string versionLiteral = getXmlAttribute(root, Attributes::version);    if (!versionLiteral.empty()) {        sscanf(versionLiteral.c_str(), "%u.%u", &versionMajor, &versionMinor);        ALOGV("%s: mHalVersion = major %u minor %u",  __FUNCTION__,              versionMajor, versionMajor);    }    ALOGV("%s: %s %s=%s", __FUNCTION__, tag, Attributes::name, name.c_str());    //可以看下Serializer.h里关于ModuleTraits的结构体定义 typedef HwModule Element;    //因此这new 了一个Hwmodule,我们先简单看一下Hwmodule的代码,位于frameworks/av/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp    HwModule::HwModule(const char *name, uint32_t halVersionMajor, uint32_t halVersionMinor)    : mName(String8(name)),      mHandle(AUDIO_MODULE_HANDLE_NONE)    {        setHalVersion(halVersionMajor, halVersionMinor);    }    //其实就是把<module name="primary" halVersion="3.0">里的name和halVersion解析并初始化给了HwModule    module = new Element(name.c_str(), versionMajor, versionMinor);    // Deserialize childrens: Audio Mix Port, Audio Device Ports (Source/Sink), Audio Routes    MixPortTraits::Collection mixPorts;    //我们可以看到module下有 <mixPorts> <devicePorts>  <routes>标签,其实也是按着这个顺序解析及的。到这里多少明白了一些audio_policy_configuration.xml的解析,那么解析完的数据又    //是如何初始化的呢,我继续往下看    //开始解析 <mixPorts>标签下东西    deserializeCollection<MixPortTraits>(doc, root, mixPorts, NULL);    //我们继续看下mixPoritraits    const char *const MixPortTraits::collectionTag = "mixPorts";    const char *const MixPortTraits::tag = "mixPort";    const char MixPortTraits::Attributes::name[] = "name";    const char MixPortTraits::Attributes::role[] = "role";    const char MixPortTraits::Attributes::flags[] = "flags";    const char MixPortTraits::Attributes::maxOpenCount[] = "maxOpenCount";    const char MixPortTraits::Attributes::maxActiveCount[] = "maxActiveCount";    status_t MixPortTraits::deserialize(_xmlDoc *doc, const _xmlNode *child, PtrElement &mixPort,                                    PtrSerializingCtx /*serializingContext*/)    {    string name = getXmlAttribute(child, Attributes::name);    if (name.empty()) {        ALOGE("%s: No %s found", __FUNCTION__, Attributes::name);        return BAD_VALUE;    }    ALOGV("%s: %s %s=%s", __FUNCTION__, tag, Attributes::name, name.c_str());    string role = getXmlAttribute(child, Attributes::role);    if (role.empty()) {        ALOGE("%s: No %s found", __FUNCTION__, Attributes::role);        return BAD_VALUE;    }    ALOGV("%s: Role=%s", __FUNCTION__, role.c_str());    //portRole 分为 sink和source sink可以理解为输入设备比如mic,source可以理解为输出设备比如speaker    audio_port_role_t portRole = role == "source" ? AUDIO_PORT_ROLE_SOURCE : AUDIO_PORT_ROLE_SINK;    //我们再去头文件里看下发现其实new是IOProfile typedef IOProfile Element;其实IOProfile继承AudioPort。    mixPort = new Element(String8(name.c_str()), portRole);    //简单看下IOProfile的初始化        IOProfile(const String8 &name, audio_port_role_t role)        : AudioPort(name, AUDIO_PORT_TYPE_MIX, role),          maxOpenCount((role == AUDIO_PORT_ROLE_SOURCE) ? 1 : 0),          curOpenCount(0),          maxActiveCount(1),          curActiveCount(0) {}      //以上把<mixPort name="primary output" role="source"中的name和role解析完并赋值给了IOProfile。然后继续    AudioProfileTraits::Collection profiles;    deserializeCollection<AudioProfileTraits>(doc, child, profiles, NULL);    //我们在看下AudioProfileTraits    const char *const AudioProfileTraits::collectionTag = "profiles";    const char *const AudioProfileTraits::tag = "profile";    const char AudioProfileTraits::Attributes::name[] = "name";    const char AudioProfileTraits::Attributes::samplingRates[] = "samplingRates";    const char AudioProfileTraits::Attributes::format[] = "format";    const char AudioProfileTraits::Attributes::channelMasks[] = "channelMasks";    //开始解析<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>标签下的samle format 和chanel    status_t AudioProfileTraits::deserialize(_xmlDoc */*doc*/, const _xmlNode *root, PtrElement &profile,                                         PtrSerializingCtx /*serializingContext*/){    string samplingRates = getXmlAttribute(root, Attributes::samplingRates);    string format = getXmlAttribute(root, Attributes::format);    string channels = getXmlAttribute(root, Attributes::channelMasks);    //再看下头文件的定义typedef AudioProfile Element发现new的是AudioProfile,顺便看下初始化做了什么    //我们明白了是把<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>标签下的samle format 和chanel    //全部赋值给AudioProfile。        AudioProfile(audio_format_t format,                 audio_channel_mask_t channelMasks,                 uint32_t samplingRate) :        mName(String8("")),        mFormat(format)    {        mChannelMasks.add(channelMasks);        mSamplingRates.add(samplingRate);    }    profile = new Element(formatFromString(format, gDynamicFormat),                          channelMasksFromString(channels, ","),                          samplingRatesFromString(samplingRates, ","));    //以下3个函数调用我们只简单分析一个,逻辑都是一样的    //void setDynamicFormat(bool dynamic) { mIsDynamicFormat = dynamic; }实际就是把foramte赋值给我AudioProfile下的mIsDynamicFormat     profile->setDynamicFormat(profile->getFormat() == gDynamicFormat);    profile->setDynamicChannels(profile->getChannels().isEmpty());    profile->setDynamicRate(profile->getSampleRates().isEmpty());    return NO_ERROR;}        //如果profiles是空也会初始化个默认的,也就是每个<mixPort>标签下一定要有个<profile>        if (profiles.isEmpty()) {        sp <AudioProfile> dynamicProfile = new AudioProfile(gDynamicFormat,                                                            ChannelsVector(), SampleRateVector());        dynamicProfile->setDynamicFormat(true);        dynamicProfile->setDynamicChannels(true);        dynamicProfile->setDynamicRate(true);        profiles.add(dynamicProfile);    }    //mixport即IOProfile,profiles即AudioProfiles,把AudioProfiles赋值给了IOProfile    mixPort->setAudioProfiles(profiles);    string flags = getXmlAttribute(child, Attributes::flags);    //如果flag标签存在,再设置下flag    if (!flags.empty()) {        // Source role        if (portRole == AUDIO_PORT_ROLE_SOURCE) {            mixPort->setFlags(OutputFlagConverter::maskFromString(flags));        } else {            // Sink role            mixPort->setFlags(InputFlagConverter::maskFromString(flags));        }    }    //下边这俩标签一般都不会使用,解析出来赋给mixport,一般在使用时如果没有特殊需求,一般使用的都是默认的    string maxOpenCount = getXmlAttribute(child, Attributes::maxOpenCount);    if (!maxOpenCount.empty()) {        convertTo(maxOpenCount, mixPort->maxOpenCount);    }    string maxActiveCount = getXmlAttribute(child, Attributes::maxActiveCount);    if (!maxActiveCount.empty()) {        convertTo(maxActiveCount, mixPort->maxActiveCount);    }    // Deserialize children    //解析<profile>下的<gain>这个在mixporit下通常也是没有的    AudioGainTraits::Collection gains;    deserializeCollection<AudioGainTraits>(doc, child, gains, NULL);    mixPort->setGains(gains);    return NO_ERROR;}    //moudle即HwModule,将解析的mixPorts(IOProfiles)存储给module的setProfiles,到此<MixPort>标签里的内容就全部解析完了    module->setProfiles(mixPorts);    //说下setProfiles这个函数    void HwModule::setProfiles(const IOProfileCollection &profiles){    for (size_t i = 0; i < profiles.size(); i++) {        addProfile(profiles[i]);    }}//调用了addprofilestatus_t HwModule::addProfile(const sp<IOProfile> &profile){    switch (profile->getRole()) {    case AUDIO_PORT_ROLE_SOURCE:        return addOutputProfile(profile);    case AUDIO_PORT_ROLE_SINK:        return addInputProfile(profile);    case AUDIO_PORT_ROLE_NONE:        return BAD_VALUE;    }    return BAD_VALUE;}//又调用了addOutputProfile和addInputProfile,其实这俩函数最终就是赋值mInputProfiles和mOutputProfiles这俩集合。mixport解析结束    //解析<devicePorts>标签,解析原理都相同就不再细说了,只说下每个标签解析完都做了什么。    DevicePortTraits::Collection devicePorts;    //解析的源码由于篇幅原因我就说下重要部分,这个函数会解析<devicePort tagName="Earpiece" type="AUDIO_DEVICE_OUT_EARPIECE" role="sink">标签下的各属性    deserializeCollection<DevicePortTraits>(doc, root, devicePorts, NULL);    //deserializeCollection<DevicePortTraits>函数中 会 new DeviceDescriptor 并将解析的tagName和type赋值下去,这里注意role这个属性只是在解析时做的容错,真正对判断这个device是sink    //还是source是通过audio_is_input_device(type)和audio_is_output_device(type)判断的    deviceDesc = new Element(type, String8(name.c_str()));    //DeviceDescriptor继承自AudioPort和AudioPortConfig简单看下DeviceDescriptor 的初始化    DeviceDescriptor::DeviceDescriptor(audio_devices_t type, const String8 &tagName) :    AudioPort(String8(""), AUDIO_PORT_TYPE_DEVICE,              audio_is_output_device(type) ? AUDIO_PORT_ROLE_SINK :                                             AUDIO_PORT_ROLE_SOURCE),    mAddress(""), mTagName(tagName), mDeviceType(type), mId(0){    if (type == AUDIO_DEVICE_IN_REMOTE_SUBMIX || type == AUDIO_DEVICE_OUT_REMOTE_SUBMIX ) {        mAddress = String8("0");    }}//最终解析完device标签,同样赋值给hwModule,    module->setDeclaredDevices(devicePorts);    //在这个set函数中将解析的devices分别赋值给了mDeclaredDevices和mPorts,其中mDeclaredDevices是DeviceDescriptor的集合mPorts是AudioPort的集合     void HwModule::setDeclaredDevices(const DeviceVector &devices){    mDeclaredDevices = devices;    for (size_t i = 0; i < devices.size(); i++) {        mPorts.add(devices[i]);    }}    //解析<routes>标签,要看到希望了哈,route很重要主要把source和sink连接起来    RouteTraits::Collection routes;    deserializeCollection<RouteTraits>(doc, root, routes, module.get());    //我们来看下解析的源码    const char *const RouteTraits::tag = "route";    const char *const RouteTraits::collectionTag = "routes";    const char RouteTraits::Attributes::type[] = "type";    const char RouteTraits::Attributes::typeMix[] = "mix";    const char RouteTraits::Attributes::sink[] = "sink";    const char RouteTraits::Attributes::sources[] = "sources";    status_t RouteTraits::deserialize(_xmlDoc */*doc*/, const _xmlNode *root, PtrElement &element,                                  PtrSerializingCtx ctx){    string type = getXmlAttribute(root, Attributes::type);    if (type.empty()) {        ALOGE("%s: No %s found", __FUNCTION__, Attributes::type);        return BAD_VALUE;    }    //首先看<route type="mix"下的type属性,一般都是mix    audio_route_type_t routeType = (type == Attributes::typeMix) ?                AUDIO_ROUTE_MIX : AUDIO_ROUTE_MUX;    ALOGV("%s: %s %s=%s", __FUNCTION__, tag, Attributes::type, type.c_str());    // new AudioRoute并将routeType传递下来    element = new Element(routeType);    string sinkAttr = getXmlAttribute(root, Attributes::sink);    if (sinkAttr.empty()) {        ALOGE("%s: No %s found", __FUNCTION__, Attributes::sink);        return BAD_VALUE;    }    // Convert Sink name to port pointer    //ctx就是解析的HwModule,findPortByTagName是找到module下的mixport(IOProfile),根据mixprot标签name找的    sp<AudioPort> sink = ctx->findPortByTagName(String8(sinkAttr.c_str()));    if (sink == NULL) {        ALOGE("%s: no sink found with name=%s", __FUNCTION__, sinkAttr.c_str());        return BAD_VALUE;    }    //找到sink属性,将sink值即Earpiece赋值给AudioRoute的setSink 标签<route type="mix" sink="Earpiece"    element->setSink(sink);    //解析sources属性<route type="mix" sink="Earpiece"sources="primary output,deep_buffer,BT SCO Headset Mic"/> 我们发现sources下有好多因此我们用循环来处理    string sourcesAttr = getXmlAttribute(root, Attributes::sources);    if (sourcesAttr.empty()) {        ALOGE("%s: No %s found", __FUNCTION__, Attributes::sources);        return BAD_VALUE;    }    // Tokenize and Convert Sources name to port pointer    AudioPortVector sources;    char *sourcesLiteral = strndup(sourcesAttr.c_str(), strlen(sourcesAttr.c_str()));    char *devTag = strtok(sourcesLiteral, ",");    while (devTag != NULL) {        if (strlen(devTag) != 0) {        //还记得之前解析的mixport实际是IOProfile,而IOProfile继承自AudioPort,因此这里找的便是之前的mixport。            sp<AudioPort> source = ctx->findPortByTagName(String8(devTag));            if (source == NULL) {                ALOGE("%s: no source found with name=%s", __FUNCTION__, devTag);                free(sourcesLiteral);                return BAD_VALUE;            }            sources.add(source);        }        devTag = strtok(NULL, ",");    }    free(sourcesLiteral);    //将audioroute赋值到audioport中    sink->addRoute(element);    for (size_t i = 0; i < sources.size(); i++) {        sp<AudioPort> source = sources.itemAt(i);        source->addRoute(element);    }    //audioroute的setSources    element->setSources(sources);    return NO_ERROR;}    //说下setRoutes这个函数    module->setRoutes(routes);    //我们看下HwModule.cpp中的实现    void HwModule::setRoutes(const AudioRouteVector &routes){    mRoutes = routes;    // Now updating the streams (aka IOProfile until now) supported devices    refreshSupportedDevices();}//继续看refreshSupportedDevices这个函数void HwModule::refreshSupportedDevices(){    // Now updating the streams (aka IOProfile until now) supported devices    //mInputProfiles就是我们解析mixport时setProfiles时赋值的,因此先遍历所有的mInputProfiles    for (const auto& stream : mInputProfiles) {        DeviceVector sourceDevices;        //解析route标签时sink->addRoute(element);已添加过,这里开始遍历这个mInputProfile下的所有route            for (const auto& route : stream->getRoutes()) {            //route->getSink()也是解析route标签时element->setSink(sink)下来的,判断这个sinkmInputProfiles中是否同一个,如果相等继续            sp<AudioPort> sink = route->getSink();            if (sink == 0 || stream != sink) {                ALOGE("%s: Invalid route attached to input stream", __FUNCTION__);                continue;            }            //先说下getRouteSourceDevices函数,找route下的source标签下的device,如果是source即输出设备,就存入sourceDevices集合            DeviceVector HwModule::getRouteSourceDevices(const sp<AudioRoute> &route) const            {            //DeviceVector : public SortedVector<sp<DeviceDescriptor> >                DeviceVector sourceDevices;                for (const auto& source : route->getSources()) {                    if (source->getType() == AUDIO_PORT_TYPE_DEVICE) {                        sourceDevices.add(mDeclaredDevices.getDeviceFromTagName(source->getTagName()));                    }                }                return sourceDevices;            }            //继续看sourceDevicesForRoute 我们知道是route标签source属性里所有输出device            DeviceVector sourceDevicesForRoute = getRouteSourceDevices(route);            if (sourceDevicesForRoute.isEmpty()) {                ALOGE("%s: invalid source devices for %s", __FUNCTION__, stream->getName().string());                continue;            }            sourceDevices.add(sourceDevicesForRoute);        }        if (sourceDevices.isEmpty()) {            ALOGE("%s: invalid source devices for %s", __FUNCTION__, stream->getName().string());            continue;        }        //将这些输出devices关联到inputProfile上,作为inputProfile的支持devices        stream->setSupportedDevices(sourceDevices);    }    //同理遍历mOutputProfiles,找到mOutputProfiles里和routes里匹配的mOutputProfile对应的route,将route里sink标签里是输入的devices,作为mOutputProfile支持的输入device        for (const auto& stream : mOutputProfiles) {        DeviceVector sinkDevices;        for (const auto& route : stream->getRoutes()) {            sp<AudioPort> source = route->getSources().findByTagName(stream->getTagName());            if (source == 0 || stream != source) {                ALOGE("%s: Invalid route attached to output stream", __FUNCTION__);                continue;            }            sp<DeviceDescriptor> sinkDevice = getRouteSinkDevice(route);            if (sinkDevice == 0) {                ALOGE("%s: invalid sink device for %s", __FUNCTION__, stream->getName().string());                continue;            }            sinkDevices.add(sinkDevice);        }        stream->setSupportedDevices(sinkDevices);    }}//到此还未结束,回到module标签的开始会发现<attachedDevices>和<defaultOutputDevice>标签还未解析,继续    const xmlNode *children = root->xmlChildrenNode;    while (children != NULL) {        if (!xmlStrcmp(children->name, (const xmlChar *)childAttachedDevicesTag)) {            ALOGV("%s: %s %s found", __FUNCTION__, tag, childAttachedDevicesTag);            const xmlNode *child = children->xmlChildrenNode;            while (child != NULL) {                if (!xmlStrcmp(child->name, (const xmlChar *)childAttachedDeviceTag)) {                    xmlChar *attachedDevice = xmlNodeListGetString(doc, child->xmlChildrenNode, 1);                    if (attachedDevice != NULL) {                        ALOGV("%s: %s %s=%s", __FUNCTION__, tag, childAttachedDeviceTag,                              (const char*)attachedDevice);                         //解析<attachedDevices>标签找到和device标签下name相同的DeviceDescriptor                             sp<DeviceDescriptor> device =                                module->getDeclaredDevices().getDeviceFromTagName(String8((const char*)attachedDevice));                         //ctx即audioPolicyConfig                        ctx->addAvailableDevice(device);                        //看下addAvailableDevice这个函数,将<attachedDevices>标签里的device分到mAvailableOutputDevices和mAvailableInputDevices中                        void addAvailableDevice(const sp<DeviceDescriptor> &availableDevice)                        {                            if (audio_is_output_device(availableDevice->type())) {                            mAvailableOutputDevices.add(availableDevice);                            } else if (audio_is_input_device(availableDevice->type())) {                                mAvailableInputDevices.add(availableDevice);                            }                        }                        xmlFree(attachedDevice);                    }                }                child = child->next;            }        }        //同理解析<defaultOutputDevice>后通过AudioPolicyConfig设置下默认的输出设备即mDefaultOutputDevices        if (!xmlStrcmp(children->name, (const xmlChar *)childDefaultOutputDeviceTag)) {            xmlChar *defaultOutputDevice = xmlNodeListGetString(doc, children->xmlChildrenNode, 1);;            if (defaultOutputDevice != NULL) {                ALOGV("%s: %s %s=%s", __FUNCTION__, tag, childDefaultOutputDeviceTag,                      (const char*)defaultOutputDevice);                sp<DeviceDescriptor> device =                        module->getDeclaredDevices().getDeviceFromTagName(String8((const char*)defaultOutputDevice));                if (device != 0 && ctx->getDefaultOutputDevice() == 0) {                    ctx->setDefaultOutputDevice(device);                    ALOGV("%s: default is %08x", __FUNCTION__, ctx->getDefaultOutputDevice()->type());                }                xmlFree(defaultOutputDevice);            }        }        children = children->next;    }    return NO_ERROR;}

最终解析完的所有module, config.setHwModules(modules)设置下去。到此基本就差不多了,剩下以下的的原理一样就不说了。

// deserialize volume section deserializeCollection<VolumeTraits>(doc, cur, volumes, &config);//// Global ConfigurationGlobalConfigTraits::deserialize(cur, config);

总结

整个xml文件就解析完成了,下一章结合具体的audio_policy_configuration.xml在说下解析过程,如果有任何问题欢迎沟通指正。