国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專(zhuān)欄INFORMATION COLUMN

Android9.0AudioPolicy之a(chǎn)udio_policy_configuration.x

陸斌 / 1731人閱讀

摘要:前言說(shuō)的解析之前,先熟悉下的啟動(dòng)過(guò)程,開(kāi)機(jī)時(shí)會(huì)通過(guò)啟動(dòng),會(huì)啟動(dòng),而會(huì)創(chuàng)建,這樣就被初始化了。感興趣的可看下這個(gè)博客有具體的講解正文回到的函數(shù)中有兩句代碼在函數(shù)中會(huì)。此刻正式開(kāi)始了的初始化。

前言

說(shuō)audio_policy_configuration.xml的解析之前,先熟悉下audiopolicy的啟動(dòng)過(guò)程,開(kāi)機(jī)時(shí)會(huì)通過(guò)init.rc啟動(dòng)audioservice,audioservice會(huì)啟動(dòng)AudioPolicyService,而AudiopolicyService會(huì)創(chuàng)建AudioPolicyManager,這樣AudioPolicyManager就被初始化了。感興趣的可看下這個(gè)博客有具體的講解https://blog.csdn.net/Qidi_Hu...

正文

回到AudioPolicyService的onFirstRef()函數(shù)中有兩句代碼

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

在createAudioPolicyManager函數(shù)中會(huì) new AudioPolicyManager(clientInterface)。此刻正式開(kāi)始了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函數(shù)的getConfig()即AudioPolicyConfig,函數(shù)聲明在A(yíng)udioPolicyManager.h文中中

AudioPolicyConfig& getConfig() { return mConfig; }
static status_t deserializeAudioPolicyXmlConfig(AudioPolicyConfig &config) {
    char audioPolicyXmlConfigFile[AUDIO_POLICY_XML_CONFIG_FILE_PATH_MAX_LENGTH];
    std::vector 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;
}

今天要說(shuō)的重點(diǎn)就是這個(gè)for循環(huán)了,serializer.deserialize(audioPolicyXmlConfigFile, config)

先看下PolicySerializer位于/frameworks/av/services/audiopolicy/common/managerdefinitions/include/目錄下
以下舉例的所有標(biāo)簽均來(lái)自audio_policy_configuration.x下對(duì)應(yīng)的第一行標(biāo)簽

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;
    }
    //上面都是解析校驗(yàn)xml的一些屬性標(biāo)簽啥的,此處開(kāi)始才是正式加載,首先是module的加載
    // Lets deserialize children
    // Modules
    ModuleTraits::Collection modules;
    deserializeCollection(doc, cur, modules, &config);
    config.setHwModules(modules);

    // deserialize volume section
    VolumeTraits::Collection volumes;
    deserializeCollection(doc, cur, volumes, &config);
    config.setVolumes(volumes);

    // Global Configuration
    GlobalConfigTraits::deserialize(cur, config);

    xmlFreeDoc(doc);
    return android::OK;
}

其中這兩行代碼便開(kāi)始了真正的解析

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

deserializeCollection是個(gè)通用方法

template 
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標(biāo)簽,我們可以看下configuration.xml下module的name是primary,當(dāng)我們?nèi)绻枰薷臅r(shí)記得module標(biāo)簽里的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里關(guān)于ModuleTraits的結(jié)構(gòu)體定義 typedef HwModule Element;
    //因此這new 了一個(gè)Hwmodule,我們先簡(jiǎn)單看一下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);
    }
    //其實(shí)就是把里的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下有    標(biāo)簽,其實(shí)也是按著這個(gè)順序解析及的。到這里多少明白了一些audio_policy_configuration.xml的解析,那么解析完的數(shù)據(jù)又
    //是如何初始化的呢,我繼續(xù)往下看
    //開(kāi)始解析 標(biāo)簽下東西
    deserializeCollection(doc, root, mixPorts, NULL);
    //我們繼續(xù)看下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可以理解為輸入設(shè)備比如mic,source可以理解為輸出設(shè)備比如speaker
    audio_port_role_t portRole = role == "source" ? AUDIO_PORT_ROLE_SOURCE : AUDIO_PORT_ROLE_SINK;
    //我們?cè)偃ヮ^文件里看下發(fā)現(xiàn)其實(shí)new是IOProfile typedef IOProfile Element;其實(shí)IOProfile繼承AudioPort。

    mixPort = new Element(String8(name.c_str()), portRole);
    //簡(jiǎn)單看下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) {}
      //以上把(doc, child, profiles, NULL);
    //我們?cè)诳聪翧udioProfileTraits
    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";
    //開(kāi)始解析標(biāo)簽下的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發(fā)現(xiàn)new的是AudioProfile,順便看下初始化做了什么
    //我們明白了是把標(biāo)簽下的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個(gè)函數(shù)調(diào)用我們只簡(jiǎn)單分析一個(gè),邏輯都是一樣的
    //void setDynamicFormat(bool dynamic) { mIsDynamicFormat = dynamic; }實(shí)際就是把foramte賦值給我AudioProfile下的mIsDynamicFormat 
    profile->setDynamicFormat(profile->getFormat() == gDynamicFormat);
    profile->setDynamicChannels(profile->getChannels().isEmpty());
    profile->setDynamicRate(profile->getSampleRates().isEmpty());

    return NO_ERROR;
}
        //如果profiles是空也會(huì)初始化個(gè)默認(rèn)的,也就是每個(gè)標(biāo)簽下一定要有個(gè)
        if (profiles.isEmpty()) {
        sp  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標(biāo)簽存在,再設(shè)置下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));
        }
    }
    //下邊這倆標(biāo)簽一般都不會(huì)使用,解析出來(lái)賦給mixport,一般在使用時(shí)如果沒(méi)有特殊需求,一般使用的都是默認(rèn)的
    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
    //解析下的這個(gè)在mixporit下通常也是沒(méi)有的
    AudioGainTraits::Collection gains;
    deserializeCollection(doc, child, gains, NULL);
    mixPort->setGains(gains);

    return NO_ERROR;
}
    //moudle即HwModule,將解析的mixPorts(IOProfiles)存儲(chǔ)給module的setProfiles,到此標(biāo)簽里的內(nèi)容就全部解析完了
    module->setProfiles(mixPorts);
    //說(shuō)下setProfiles這個(gè)函數(shù)
    void HwModule::setProfiles(const IOProfileCollection &profiles)
{
    for (size_t i = 0; i < profiles.size(); i++) {
        addProfile(profiles[i]);
    }
}
//調(diào)用了addprofile
status_t HwModule::addProfile(const sp &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;
}
//又調(diào)用了addOutputProfile和addInputProfile,其實(shí)這倆函數(shù)最終就是賦值mInputProfiles和mOutputProfiles這倆集合。mixport解析結(jié)束
    //解析標(biāo)簽,解析原理都相同就不再細(xì)說(shuō)了,只說(shuō)下每個(gè)標(biāo)簽解析完都做了什么。
    DevicePortTraits::Collection devicePorts;
    //解析的源碼由于篇幅原因我就說(shuō)下重要部分,這個(gè)函數(shù)會(huì)解析標(biāo)簽下的各屬性
    deserializeCollection(doc, root, devicePorts, NULL);
    //deserializeCollection函數(shù)中 會(huì) new DeviceDescriptor 并將解析的tagName和type賦值下去,這里注意role這個(gè)屬性只是在解析時(shí)做的容錯(cuò),真正對(duì)判斷這個(gè)device是sink
    //還是source是通過(guò)audio_is_input_device(type)和audio_is_output_device(type)判斷的
    deviceDesc = new Element(type, String8(name.c_str()));
    //DeviceDescriptor繼承自AudioPort和AudioPortConfig簡(jiǎn)單看下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標(biāo)簽,同樣賦值給hwModule,
    module->setDeclaredDevices(devicePorts);
    //在這個(gè)set函數(shù)中將解析的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]);
    }
}
    //解析標(biāo)簽,要看到希望了哈,route很重要主要把source和sink連接起來(lái)
    RouteTraits::Collection routes;
    deserializeCollection(doc, root, routes, module.get());
    //我們來(lái)看下解析的源碼
    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;
    }
    //首先看 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 標(biāo)簽setSink(sink);
    //解析sources屬性 我們發(fā)現(xiàn)sources下有好多因此我們用循環(huán)來(lái)處理
    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實(shí)際是IOProfile,而IOProfile繼承自AudioPort,因此這里找的便是之前的mixport。
            sp 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 source = sources.itemAt(i);
        source->addRoute(element);
    }
    //audioroute的setSources
    element->setSources(sources);
    return NO_ERROR;
}
    //說(shuō)下setRoutes這個(gè)函數(shù)
    module->setRoutes(routes);
    //我們看下HwModule.cpp中的實(shí)現(xiàn)
    void HwModule::setRoutes(const AudioRouteVector &routes)
{
    mRoutes = routes;
    // Now updating the streams (aka IOProfile until now) supported devices
    refreshSupportedDevices();
}
//繼續(xù)看refreshSupportedDevices這個(gè)函數(shù)
void HwModule::refreshSupportedDevices()
{
    // Now updating the streams (aka IOProfile until now) supported devices
    //mInputProfiles就是我們解析mixport時(shí)setProfiles時(shí)賦值的,因此先遍歷所有的mInputProfiles
    for (const auto& stream : mInputProfiles) {
        DeviceVector sourceDevices;
        //解析route標(biāo)簽時(shí)sink->addRoute(element);已添加過(guò),這里開(kāi)始遍歷這個(gè)mInputProfile下的所有route
            for (const auto& route : stream->getRoutes()) {
            //route->getSink()也是解析route標(biāo)簽時(shí)element->setSink(sink)下來(lái)的,判斷這個(gè)sinkmInputProfiles中是否同一個(gè),如果相等繼續(xù)
            sp sink = route->getSink();
            if (sink == 0 || stream != sink) {
                ALOGE("%s: Invalid route attached to input stream", __FUNCTION__);
                continue;
            }
            //先說(shuō)下getRouteSourceDevices函數(shù),找route下的source標(biāo)簽下的device,如果是source即輸出設(shè)備,就存入sourceDevices集合
            DeviceVector HwModule::getRouteSourceDevices(const sp &route) const
            {
            //DeviceVector : public SortedVector >
                DeviceVector sourceDevices;
                for (const auto& source : route->getSources()) {
                    if (source->getType() == AUDIO_PORT_TYPE_DEVICE) {
                        sourceDevices.add(mDeclaredDevices.getDeviceFromTagName(source->getTagName()));
                    }
                }
                return sourceDevices;
            }
            //繼續(xù)看sourceDevicesForRoute 我們知道是route標(biāo)簽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關(guān)聯(lián)到inputProfile上,作為inputProfile的支持devices
        stream->setSupportedDevices(sourceDevices);
    }
    //同理遍歷mOutputProfiles,找到mOutputProfiles里和routes里匹配的mOutputProfile對(duì)應(yīng)的route,將route里sink標(biāo)簽里是輸入的devices,作為mOutputProfile支持的輸入device
        for (const auto& stream : mOutputProfiles) {
        DeviceVector sinkDevices;
        for (const auto& route : stream->getRoutes()) {
            sp source = route->getSources().findByTagName(stream->getTagName());
            if (source == 0 || stream != source) {
                ALOGE("%s: Invalid route attached to output stream", __FUNCTION__);
                continue;
            }
            sp sinkDevice = getRouteSinkDevice(route);
            if (sinkDevice == 0) {
                ALOGE("%s: invalid sink device for %s", __FUNCTION__, stream->getName().string());
                continue;
            }
            sinkDevices.add(sinkDevice);
        }
        stream->setSupportedDevices(sinkDevices);
    }
}
//到此還未結(jié)束,回到module標(biāo)簽的開(kāi)始會(huì)發(fā)現(xiàn)標(biāo)簽還未解析,繼續(xù)
    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);
                         //解析標(biāo)簽找到和device標(biāo)簽下name相同的DeviceDescriptor     
                        sp device =
                                module->getDeclaredDevices().getDeviceFromTagName(String8((const char*)attachedDevice));
                         //ctx即audioPolicyConfig
                        ctx->addAvailableDevice(device);
                        //看下addAvailableDevice這個(gè)函數(shù),將標(biāo)簽里的device分到mAvailableOutputDevices和mAvailableInputDevices中
                        void addAvailableDevice(const sp &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;
            }
        }
        //同理解析后通過(guò)AudioPolicyConfig設(shè)置下默認(rèn)的輸出設(shè)備即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 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)設(shè)置下去。到此基本就差不多了,剩下以下的的原理一樣就不說(shuō)了。

// deserialize volume section
 deserializeCollection(doc, cur, volumes, &config);
//// Global Configuration
GlobalConfigTraits::deserialize(cur, config);
總結(jié)

整個(gè)xml文件就解析完成了,下一章結(jié)合具體的audio_policy_configuration.xml在說(shuō)下解析過(guò)程,如果有任何問(wèn)題歡迎溝通指正。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/76291.html

相關(guān)文章

  • Android9.0AudioPolicyaudio_policy_configuration.x

    摘要:有點(diǎn)需要注意這里有個(gè)其實(shí)在解析時(shí)這些的文件也會(huì)放到一起解析的,下一張分享下解析完后又做了什么,如有任何問(wèn)題,歡迎指正 前言 之前通過(guò)代碼說(shuō)了audio_policy_configuration的解析過(guò)程,代碼確實(shí)需要一定耐心來(lái)看,那么今天結(jié)合具體xml再來(lái)說(shuō)明下audio_policy_configuration的解析過(guò)程 正文 audio_policy_configuration.x...

    wemall 評(píng)論0 收藏0
  • Android9.0AudioPolicyaudio_policy_configuration.x

    摘要:前言說(shuō)的解析之前,先熟悉下的啟動(dòng)過(guò)程,開(kāi)機(jī)時(shí)會(huì)通過(guò)啟動(dòng),會(huì)啟動(dòng),而會(huì)創(chuàng)建,這樣就被初始化了。感興趣的可看下這個(gè)博客有具體的講解正文回到的函數(shù)中有兩句代碼在函數(shù)中會(huì)。此刻正式開(kāi)始了的初始化。 前言 說(shuō)audio_policy_configuration.xml的解析之前,先熟悉下audiopolicy的啟動(dòng)過(guò)程,開(kāi)機(jī)時(shí)會(huì)通過(guò)init.rc啟動(dòng)audioservice,audioserv...

    Charlie_Jade 評(píng)論0 收藏0
  • Java多線(xiàn)程進(jìn)階(一)—— J.U.C并發(fā)包概述

    摘要:整個(gè)包,按照功能可以大致劃分如下鎖框架原子類(lèi)框架同步器框架集合框架執(zhí)行器框架本系列將按上述順序分析,分析所基于的源碼為。后,根據(jù)一系列常見(jiàn)的多線(xiàn)程設(shè)計(jì)模式,設(shè)計(jì)了并發(fā)包,其中包下提供了一系列基礎(chǔ)的鎖工具,用以對(duì)等進(jìn)行補(bǔ)充增強(qiáng)。 showImg(https://segmentfault.com/img/remote/1460000016012623); 本文首發(fā)于一世流云專(zhuān)欄:https...

    anonymoussf 評(píng)論0 收藏0
  • 讀Zepto源碼Stack模塊

    摘要:讀源碼系列文章已經(jīng)放到了上,歡迎源碼版本本文閱讀的源碼為改寫(xiě)原有的方法模塊改寫(xiě)了以上這些方法,這些方法在調(diào)用的時(shí)候,會(huì)為返回的結(jié)果添加的屬性,用來(lái)保存原來(lái)的集合。方法的分析可以看讀源碼之模塊。 Stack 模塊為 Zepto 添加了 addSelf 和 end 方法。 讀 Zepto 源碼系列文章已經(jīng)放到了github上,歡迎star: reading-zepto 源碼版本 本文閱讀的...

    crossea 評(píng)論0 收藏0
  • 讀Zepto源碼Gesture模塊

    摘要:模塊基于上的事件的封裝,利用屬性,封裝出系列事件。這個(gè)判斷需要引入設(shè)備偵測(cè)模塊。然后是監(jiān)測(cè)事件,根據(jù)這三個(gè)事件,可以組合出和事件。其中變量對(duì)象和模塊中的對(duì)象的作用差不多,可以先看看讀源碼之模塊對(duì)模塊的分析。 Gesture 模塊基于 IOS 上的 Gesture 事件的封裝,利用 scale 屬性,封裝出 pinch 系列事件。 讀 Zepto 源碼系列文章已經(jīng)放到了github上,歡...

    coolpail 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

陸斌

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<