1f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie/* 2f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie * Copyright (C) 2015 The Android Open Source Project 3f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie * 4f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie * Licensed under the Apache License, Version 2.0 (the "License"); 5f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie * you may not use this file except in compliance with the License. 6f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie * You may obtain a copy of the License at 7f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie * 8f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie * http://www.apache.org/licenses/LICENSE-2.0 9f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie * 10f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie * Unless required by applicable law or agreed to in writing, software 11f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie * distributed under the License is distributed on an "AS IS" BASIS, 12f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie * See the License for the specific language governing permissions and 14f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie * limitations under the License. 15f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie */ 16f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 17f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie#define LOG_TAG "APM::Serializer" 18f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie//#define LOG_NDEBUG 0 19f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 20f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie#include "Serializer.h" 21913d06c099bd689375483a839e11057ccf284d1cMikhail Naganov#include <media/convert.h> 22f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie#include "TypeConverter.h" 23f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie#include <libxml/parser.h> 24f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie#include <libxml/xinclude.h> 25f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie#include <string> 26f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie#include <sstream> 27f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie#include <istream> 28f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 29f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieusing std::string; 30f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 31f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffienamespace android { 32f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 33f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffiestring getXmlAttribute(const xmlNode *cur, const char *attribute) 34f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie{ 35f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie xmlChar *xmlValue = xmlGetProp(cur, (const xmlChar*)attribute); 36f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie if (xmlValue == NULL) { 37f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie return ""; 38f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 39f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie string value((const char*)xmlValue); 40f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie xmlFree(xmlValue); 41f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie return value; 42f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie} 43f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 44f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieusing utilities::convertTo; 45f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 46f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieconst char *const PolicySerializer::rootName = "audioPolicyConfiguration"; 47f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieconst char *const PolicySerializer::versionAttribute = "version"; 48f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieconst uint32_t PolicySerializer::gMajor = 1; 49f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieconst uint32_t PolicySerializer::gMinor = 0; 50c9d7c4e35afd48ac8a315f53666943b6210dafa1François Gaffiestatic const char *const gReferenceElementName = "reference"; 51c9d7c4e35afd48ac8a315f53666943b6210dafa1François Gaffiestatic const char *const gReferenceAttributeName = "name"; 52c9d7c4e35afd48ac8a315f53666943b6210dafa1François Gaffie 5319219b44e05555b29e00ce56ce273d168fa83888François Gaffietemplate <class Trait> 54c9d7c4e35afd48ac8a315f53666943b6210dafa1François Gaffiestatic void getReference(const _xmlNode *root, const _xmlNode *&refNode, const string &refName) 55c9d7c4e35afd48ac8a315f53666943b6210dafa1François Gaffie{ 5619219b44e05555b29e00ce56ce273d168fa83888François Gaffie const _xmlNode *col = root; 5719219b44e05555b29e00ce56ce273d168fa83888François Gaffie while (col != NULL) { 5819219b44e05555b29e00ce56ce273d168fa83888François Gaffie if (!xmlStrcmp(col->name, (const xmlChar *)Trait::collectionTag)) { 5919219b44e05555b29e00ce56ce273d168fa83888François Gaffie const xmlNode *cur = col->children; 6019219b44e05555b29e00ce56ce273d168fa83888François Gaffie while (cur != NULL) { 6119219b44e05555b29e00ce56ce273d168fa83888François Gaffie if ((!xmlStrcmp(cur->name, (const xmlChar *)gReferenceElementName))) { 6219219b44e05555b29e00ce56ce273d168fa83888François Gaffie string name = getXmlAttribute(cur, gReferenceAttributeName); 6319219b44e05555b29e00ce56ce273d168fa83888François Gaffie if (refName == name) { 6419219b44e05555b29e00ce56ce273d168fa83888François Gaffie refNode = cur; 6519219b44e05555b29e00ce56ce273d168fa83888François Gaffie return; 6619219b44e05555b29e00ce56ce273d168fa83888François Gaffie } 6719219b44e05555b29e00ce56ce273d168fa83888François Gaffie } 6819219b44e05555b29e00ce56ce273d168fa83888François Gaffie cur = cur->next; 6919219b44e05555b29e00ce56ce273d168fa83888François Gaffie } 70c9d7c4e35afd48ac8a315f53666943b6210dafa1François Gaffie } 7119219b44e05555b29e00ce56ce273d168fa83888François Gaffie col = col->next; 72c9d7c4e35afd48ac8a315f53666943b6210dafa1François Gaffie } 73c9d7c4e35afd48ac8a315f53666943b6210dafa1François Gaffie return; 74c9d7c4e35afd48ac8a315f53666943b6210dafa1François Gaffie} 75f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 76f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffietemplate <class Trait> 77f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffiestatic status_t deserializeCollection(_xmlDoc *doc, const _xmlNode *cur, 78f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie typename Trait::Collection &collection, 79f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie typename Trait::PtrSerializingCtx serializingContext) 80f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie{ 81f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie const xmlNode *root = cur->xmlChildrenNode; 82f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie while (root != NULL) { 83f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie if (xmlStrcmp(root->name, (const xmlChar *)Trait::collectionTag) && 84f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie xmlStrcmp(root->name, (const xmlChar *)Trait::tag)) { 85f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie root = root->next; 86f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie continue; 87f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 88d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie const xmlNode *child = root; 89d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie if (!xmlStrcmp(child->name, (const xmlChar *)Trait::collectionTag)) { 90d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie child = child->xmlChildrenNode; 91f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 92d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie while (child != NULL) { 93d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie if (!xmlStrcmp(child->name, (const xmlChar *)Trait::tag)) { 94f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie typename Trait::PtrElement element; 95d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie status_t status = Trait::deserialize(doc, child, element, serializingContext); 96f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie if (status != NO_ERROR) { 97f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie return status; 98f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 99f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie if (collection.add(element) < 0) { 100f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie ALOGE("%s: could not add element to %s collection", __FUNCTION__, 101f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie Trait::collectionTag); 102f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 103f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 104d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie child = child->next; 105d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie } 106d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie if (!xmlStrcmp(root->name, (const xmlChar *)Trait::tag)) { 107d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie return NO_ERROR; 108f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 109d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie root = root->next; 110f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 111d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie return NO_ERROR; 112f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie} 113f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 114f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieconst char *const AudioGainTraits::tag = "gain"; 115f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieconst char *const AudioGainTraits::collectionTag = "gains"; 116f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 117f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieconst char AudioGainTraits::Attributes::mode[] = "mode"; 118f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieconst char AudioGainTraits::Attributes::channelMask[] = "channel_mask"; 119f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieconst char AudioGainTraits::Attributes::minValueMB[] = "minValueMB"; 120f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieconst char AudioGainTraits::Attributes::maxValueMB[] = "maxValueMB"; 121f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieconst char AudioGainTraits::Attributes::defaultValueMB[] = "defaultValueMB"; 122f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieconst char AudioGainTraits::Attributes::stepValueMB[] = "stepValueMB"; 123f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieconst char AudioGainTraits::Attributes::minRampMs[] = "minRampMs"; 124f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieconst char AudioGainTraits::Attributes::maxRampMs[] = "maxRampMs"; 125f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 126f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffiestatus_t AudioGainTraits::deserialize(_xmlDoc */*doc*/, const _xmlNode *root, PtrElement &gain, 127f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie PtrSerializingCtx /*serializingContext*/) 128f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie{ 129f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie static uint32_t index = 0; 130f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie gain = new Element(index++, true); 131f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 132f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie string mode = getXmlAttribute(root, Attributes::mode); 133f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie if (!mode.empty()) { 134f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie gain->setMode(GainModeConverter::maskFromString(mode)); 135f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 136f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 137f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie string channelsLiteral = getXmlAttribute(root, Attributes::channelMask); 138f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie if (!channelsLiteral.empty()) { 139f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie gain->setChannelMask(channelMaskFromString(channelsLiteral)); 140f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 141f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 142f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie string minValueMBLiteral = getXmlAttribute(root, Attributes::minValueMB); 143f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie uint32_t minValueMB; 144f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie if (!minValueMBLiteral.empty() && convertTo(minValueMBLiteral, minValueMB)) { 145f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie gain->setMinValueInMb(minValueMB); 146f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 147f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 148f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie string maxValueMBLiteral = getXmlAttribute(root, Attributes::maxValueMB); 149f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie uint32_t maxValueMB; 150f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie if (!maxValueMBLiteral.empty() && convertTo(maxValueMBLiteral, maxValueMB)) { 151f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie gain->setMaxValueInMb(maxValueMB); 152f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 153f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 154f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie string defaultValueMBLiteral = getXmlAttribute(root, Attributes::defaultValueMB); 155f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie uint32_t defaultValueMB; 156f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie if (!defaultValueMBLiteral.empty() && convertTo(defaultValueMBLiteral, defaultValueMB)) { 157f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie gain->setDefaultValueInMb(defaultValueMB); 158f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 159f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 160f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie string stepValueMBLiteral = getXmlAttribute(root, Attributes::stepValueMB); 161f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie uint32_t stepValueMB; 162f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie if (!stepValueMBLiteral.empty() && convertTo(stepValueMBLiteral, stepValueMB)) { 163f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie gain->setStepValueInMb(stepValueMB); 164f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 165f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 166f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie string minRampMsLiteral = getXmlAttribute(root, Attributes::minRampMs); 167f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie uint32_t minRampMs; 168f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie if (!minRampMsLiteral.empty() && convertTo(minRampMsLiteral, minRampMs)) { 169f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie gain->setMinRampInMs(minRampMs); 170f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 171f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 172f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie string maxRampMsLiteral = getXmlAttribute(root, Attributes::maxRampMs); 173f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie uint32_t maxRampMs; 174f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie if (!maxRampMsLiteral.empty() && convertTo(maxRampMsLiteral, maxRampMs)) { 175f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie gain->setMaxRampInMs(maxRampMs); 176f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 177f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie ALOGV("%s: adding new gain mode %08x channel mask %08x min mB %d max mB %d", __FUNCTION__, 178f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie gain->getMode(), gain->getChannelMask(), gain->getMinValueInMb(), 179f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie gain->getMaxValueInMb()); 180f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 181f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie if (gain->getMode() == 0) { 182f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie return BAD_VALUE; 183f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 184f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie return NO_ERROR; 185f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie} 186f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 187f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieconst char *const AudioProfileTraits::collectionTag = "profiles"; 188f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieconst char *const AudioProfileTraits::tag = "profile"; 189f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 190f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieconst char AudioProfileTraits::Attributes::name[] = "name"; 191f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieconst char AudioProfileTraits::Attributes::samplingRates[] = "samplingRates"; 192f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieconst char AudioProfileTraits::Attributes::format[] = "format"; 193f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieconst char AudioProfileTraits::Attributes::channelMasks[] = "channelMasks"; 194f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 195f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffiestatus_t AudioProfileTraits::deserialize(_xmlDoc */*doc*/, const _xmlNode *root, PtrElement &profile, 196f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie PtrSerializingCtx /*serializingContext*/) 197f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie{ 198f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie string samplingRates = getXmlAttribute(root, Attributes::samplingRates); 199f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie string format = getXmlAttribute(root, Attributes::format); 200f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie string channels = getXmlAttribute(root, Attributes::channelMasks); 201f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 202913d06c099bd689375483a839e11057ccf284d1cMikhail Naganov profile = new Element(formatFromString(format, gDynamicFormat), 203913d06c099bd689375483a839e11057ccf284d1cMikhail Naganov channelMasksFromString(channels, ","), 204f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie samplingRatesFromString(samplingRates, ",")); 205f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 206f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie profile->setDynamicFormat(profile->getFormat() == gDynamicFormat); 207f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie profile->setDynamicChannels(profile->getChannels().isEmpty()); 208f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie profile->setDynamicRate(profile->getSampleRates().isEmpty()); 209f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 210f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie return NO_ERROR; 211f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie} 212f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 213f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 214f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieconst char *const MixPortTraits::collectionTag = "mixPorts"; 215f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieconst char *const MixPortTraits::tag = "mixPort"; 216f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 217f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieconst char MixPortTraits::Attributes::name[] = "name"; 218f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieconst char MixPortTraits::Attributes::role[] = "role"; 219f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieconst char MixPortTraits::Attributes::flags[] = "flags"; 220f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 221f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffiestatus_t MixPortTraits::deserialize(_xmlDoc *doc, const _xmlNode *child, PtrElement &mixPort, 222f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie PtrSerializingCtx /*serializingContext*/) 223f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie{ 224f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie string name = getXmlAttribute(child, Attributes::name); 225f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie if (name.empty()) { 226f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie ALOGE("%s: No %s found", __FUNCTION__, Attributes::name); 227f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie return BAD_VALUE; 228f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 229f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie ALOGV("%s: %s %s=%s", __FUNCTION__, tag, Attributes::name, name.c_str()); 230f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie string role = getXmlAttribute(child, Attributes::role); 231f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie if (role.empty()) { 232f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie ALOGE("%s: No %s found", __FUNCTION__, Attributes::role); 233f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie return BAD_VALUE; 234f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 235f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie ALOGV("%s: Role=%s", __FUNCTION__, role.c_str()); 236f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie audio_port_role_t portRole = role == "source" ? AUDIO_PORT_ROLE_SOURCE : AUDIO_PORT_ROLE_SINK; 237f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 238f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie mixPort = new Element(String8(name.c_str()), portRole); 239f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 240f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie AudioProfileTraits::Collection profiles; 241f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie deserializeCollection<AudioProfileTraits>(doc, child, profiles, NULL); 242f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie if (profiles.isEmpty()) { 243f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie sp <AudioProfile> dynamicProfile = new AudioProfile(gDynamicFormat, 244f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie ChannelsVector(), SampleRateVector()); 245f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie dynamicProfile->setDynamicFormat(true); 246f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie dynamicProfile->setDynamicChannels(true); 247f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie dynamicProfile->setDynamicRate(true); 248f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie profiles.add(dynamicProfile); 249f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 250f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie mixPort->setAudioProfiles(profiles); 251f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 252f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie string flags = getXmlAttribute(child, Attributes::flags); 253f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie if (!flags.empty()) { 254f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie // Source role 255f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie if (portRole == AUDIO_PORT_ROLE_SOURCE) { 256f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie mixPort->setFlags(OutputFlagConverter::maskFromString(flags)); 257f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } else { 258f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie // Sink role 259f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie mixPort->setFlags(InputFlagConverter::maskFromString(flags)); 260f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 261f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 262f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie // Deserialize children 263f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie AudioGainTraits::Collection gains; 264f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie deserializeCollection<AudioGainTraits>(doc, child, gains, NULL); 265f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie mixPort->setGains(gains); 266f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 267f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie return NO_ERROR; 268f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie} 269f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 270f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieconst char *const DevicePortTraits::tag = "devicePort"; 271f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieconst char *const DevicePortTraits::collectionTag = "devicePorts"; 272f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 273f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieconst char DevicePortTraits::Attributes::tagName[] = "tagName"; 274f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieconst char DevicePortTraits::Attributes::type[] = "type"; 275f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieconst char DevicePortTraits::Attributes::role[] = "role"; 276f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieconst char DevicePortTraits::Attributes::address[] = "address"; 277f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieconst char DevicePortTraits::Attributes::roleSource[] = "source"; 278f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 279f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffiestatus_t DevicePortTraits::deserialize(_xmlDoc *doc, const _xmlNode *root, PtrElement &deviceDesc, 280f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie PtrSerializingCtx /*serializingContext*/) 281f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie{ 282f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie string name = getXmlAttribute(root, Attributes::tagName); 283f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie if (name.empty()) { 284f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie ALOGE("%s: No %s found", __FUNCTION__, Attributes::tagName); 285f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie return BAD_VALUE; 286f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 287f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie ALOGV("%s: %s %s=%s", __FUNCTION__, tag, Attributes::tagName, name.c_str()); 288f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie string typeName = getXmlAttribute(root, Attributes::type); 289f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie if (typeName.empty()) { 290f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie ALOGE("%s: no type for %s", __FUNCTION__, name.c_str()); 291f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie return BAD_VALUE; 292f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 293f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie ALOGV("%s: %s %s=%s", __FUNCTION__, tag, Attributes::type, typeName.c_str()); 294f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie string role = getXmlAttribute(root, Attributes::role); 295f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie if (role.empty()) { 296f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie ALOGE("%s: No %s found", __FUNCTION__, Attributes::role); 297f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie return BAD_VALUE; 298f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 299f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie ALOGV("%s: %s %s=%s", __FUNCTION__, tag, Attributes::role, role.c_str()); 300f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie audio_port_role_t portRole = (role == Attributes::roleSource) ? 301f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie AUDIO_PORT_ROLE_SOURCE : AUDIO_PORT_ROLE_SINK; 302f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 303f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie audio_devices_t type = AUDIO_DEVICE_NONE; 304913d06c099bd689375483a839e11057ccf284d1cMikhail Naganov if (!deviceFromString(typeName, type) || 305f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie (!audio_is_input_device(type) && portRole == AUDIO_PORT_ROLE_SOURCE) || 306f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie (!audio_is_output_devices(type) && portRole == AUDIO_PORT_ROLE_SINK)) { 307f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie ALOGW("%s: bad type %08x", __FUNCTION__, type); 308f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie return BAD_VALUE; 309f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 310f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie deviceDesc = new Element(type, String8(name.c_str())); 311f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 312f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie string address = getXmlAttribute(root, Attributes::address); 313f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie if (!address.empty()) { 314f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie ALOGV("%s: address=%s for %s", __FUNCTION__, address.c_str(), name.c_str()); 315f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie deviceDesc->mAddress = String8(address.c_str()); 316f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 317f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 318f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie AudioProfileTraits::Collection profiles; 319f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie deserializeCollection<AudioProfileTraits>(doc, root, profiles, NULL); 320f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie if (profiles.isEmpty()) { 321f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie sp <AudioProfile> dynamicProfile = new AudioProfile(gDynamicFormat, 322f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie ChannelsVector(), SampleRateVector()); 323f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie dynamicProfile->setDynamicFormat(true); 324f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie dynamicProfile->setDynamicChannels(true); 325f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie dynamicProfile->setDynamicRate(true); 326f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie profiles.add(dynamicProfile); 327f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 328f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie deviceDesc->setAudioProfiles(profiles); 329f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 330f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie // Deserialize AudioGain children 331f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie deserializeCollection<AudioGainTraits>(doc, root, deviceDesc->mGains, NULL); 332f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie ALOGV("%s: adding device tag %s type %08x address %s", __FUNCTION__, 333f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie deviceDesc->getName().string(), type, deviceDesc->mAddress.string()); 334f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie return NO_ERROR; 335f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie} 336f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 337f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieconst char *const RouteTraits::tag = "route"; 338f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieconst char *const RouteTraits::collectionTag = "routes"; 339f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 340f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieconst char RouteTraits::Attributes::type[] = "type"; 341f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieconst char RouteTraits::Attributes::typeMix[] = "mix"; 342f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieconst char RouteTraits::Attributes::sink[] = "sink"; 343f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieconst char RouteTraits::Attributes::sources[] = "sources"; 344f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 345f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 346f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffiestatus_t RouteTraits::deserialize(_xmlDoc */*doc*/, const _xmlNode *root, PtrElement &element, 347f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie PtrSerializingCtx ctx) 348f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie{ 349f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie string type = getXmlAttribute(root, Attributes::type); 350f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie if (type.empty()) { 351f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie ALOGE("%s: No %s found", __FUNCTION__, Attributes::type); 352f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie return BAD_VALUE; 353f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 354f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie audio_route_type_t routeType = (type == Attributes::typeMix) ? 355f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie AUDIO_ROUTE_MIX : AUDIO_ROUTE_MUX; 356f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 357f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie ALOGV("%s: %s %s=%s", __FUNCTION__, tag, Attributes::type, type.c_str()); 358f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie element = new Element(routeType); 359f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 360f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie string sinkAttr = getXmlAttribute(root, Attributes::sink); 361f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie if (sinkAttr.empty()) { 362f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie ALOGE("%s: No %s found", __FUNCTION__, Attributes::sink); 363f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie return BAD_VALUE; 364f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 365f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie // Convert Sink name to port pointer 366f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie sp<AudioPort> sink = ctx->findPortByTagName(String8(sinkAttr.c_str())); 367f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie if (sink == NULL) { 368f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie ALOGE("%s: no sink found with name=%s", __FUNCTION__, sinkAttr.c_str()); 369f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie return BAD_VALUE; 370f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 371f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie element->setSink(sink); 372f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 373f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie string sourcesAttr = getXmlAttribute(root, Attributes::sources); 374f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie if (sourcesAttr.empty()) { 375f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie ALOGE("%s: No %s found", __FUNCTION__, Attributes::sources); 376f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie return BAD_VALUE; 377f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 378f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie // Tokenize and Convert Sources name to port pointer 379f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie AudioPortVector sources; 380f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie char *sourcesLiteral = strndup(sourcesAttr.c_str(), strlen(sourcesAttr.c_str())); 381f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie char *devTag = strtok(sourcesLiteral, ","); 382f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie while (devTag != NULL) { 383f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie if (strlen(devTag) != 0) { 384f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie sp<AudioPort> source = ctx->findPortByTagName(String8(devTag)); 385f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie if (source == NULL) { 386f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie ALOGE("%s: no source found with name=%s", __FUNCTION__, devTag); 387cc7c0d6fff90c867f661b795e803043aee4d0bb8Yunlian Jiang free(sourcesLiteral); 388f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie return BAD_VALUE; 389f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 390f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie sources.add(source); 391f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 392f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie devTag = strtok(NULL, ","); 393f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 394f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie free(sourcesLiteral); 395f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 396f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie sink->addRoute(element); 397f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie for (size_t i = 0; i < sources.size(); i++) { 398f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie sp<AudioPort> source = sources.itemAt(i); 399f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie source->addRoute(element); 400f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 401f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie element->setSources(sources); 402f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie return NO_ERROR; 403f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie} 404f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 405f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieconst char *const ModuleTraits::childAttachedDevicesTag = "attachedDevices"; 406f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieconst char *const ModuleTraits::childAttachedDeviceTag = "item"; 407f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieconst char *const ModuleTraits::childDefaultOutputDeviceTag = "defaultOutputDevice"; 408f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 409f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieconst char *const ModuleTraits::tag = "module"; 410f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieconst char *const ModuleTraits::collectionTag = "modules"; 411f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 412f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieconst char ModuleTraits::Attributes::name[] = "name"; 413f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieconst char ModuleTraits::Attributes::version[] = "halVersion"; 414f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 415f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffiestatus_t ModuleTraits::deserialize(xmlDocPtr doc, const xmlNode *root, PtrElement &module, 416f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie PtrSerializingCtx ctx) 417f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie{ 418f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie string name = getXmlAttribute(root, Attributes::name); 419f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie if (name.empty()) { 420f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie ALOGE("%s: No %s found", __FUNCTION__, Attributes::name); 421f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie return BAD_VALUE; 422f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 4239ee0540d3a61bff03d561ca431a371c3d9335d2bMikhail Naganov uint32_t versionMajor = 0, versionMinor = 0; 424f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie string versionLiteral = getXmlAttribute(root, Attributes::version); 425f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie if (!versionLiteral.empty()) { 4269ee0540d3a61bff03d561ca431a371c3d9335d2bMikhail Naganov sscanf(versionLiteral.c_str(), "%u.%u", &versionMajor, &versionMinor); 4279ee0540d3a61bff03d561ca431a371c3d9335d2bMikhail Naganov ALOGV("%s: mHalVersion = major %u minor %u", __FUNCTION__, 4289ee0540d3a61bff03d561ca431a371c3d9335d2bMikhail Naganov versionMajor, versionMajor); 429f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 430f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 431f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie ALOGV("%s: %s %s=%s", __FUNCTION__, tag, Attributes::name, name.c_str()); 432f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 4339ee0540d3a61bff03d561ca431a371c3d9335d2bMikhail Naganov module = new Element(name.c_str(), versionMajor, versionMinor); 434f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 435f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie // Deserialize childrens: Audio Mix Port, Audio Device Ports (Source/Sink), Audio Routes 436f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie MixPortTraits::Collection mixPorts; 437f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie deserializeCollection<MixPortTraits>(doc, root, mixPorts, NULL); 438f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie module->setProfiles(mixPorts); 439f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 440f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie DevicePortTraits::Collection devicePorts; 441f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie deserializeCollection<DevicePortTraits>(doc, root, devicePorts, NULL); 442f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie module->setDeclaredDevices(devicePorts); 443f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 444f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie RouteTraits::Collection routes; 445f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie deserializeCollection<RouteTraits>(doc, root, routes, module.get()); 446f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie module->setRoutes(routes); 447f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 448f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie const xmlNode *children = root->xmlChildrenNode; 449f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie while (children != NULL) { 450f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie if (!xmlStrcmp(children->name, (const xmlChar *)childAttachedDevicesTag)) { 451f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie ALOGV("%s: %s %s found", __FUNCTION__, tag, childAttachedDevicesTag); 452f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie const xmlNode *child = children->xmlChildrenNode; 453f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie while (child != NULL) { 454f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie if (!xmlStrcmp(child->name, (const xmlChar *)childAttachedDeviceTag)) { 455f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie xmlChar *attachedDevice = xmlNodeListGetString(doc, child->xmlChildrenNode, 1); 456f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie if (attachedDevice != NULL) { 457f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie ALOGV("%s: %s %s=%s", __FUNCTION__, tag, childAttachedDeviceTag, 458f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie (const char*)attachedDevice); 459f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie sp<DeviceDescriptor> device = 460f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie module->getDeclaredDevices().getDeviceFromTagName(String8((const char*)attachedDevice)); 461f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie ctx->addAvailableDevice(device); 462f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie xmlFree(attachedDevice); 463f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 464f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 465f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie child = child->next; 466f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 467f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 468f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie if (!xmlStrcmp(children->name, (const xmlChar *)childDefaultOutputDeviceTag)) { 469f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie xmlChar *defaultOutputDevice = xmlNodeListGetString(doc, children->xmlChildrenNode, 1);; 470f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie if (defaultOutputDevice != NULL) { 471f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie ALOGV("%s: %s %s=%s", __FUNCTION__, tag, childDefaultOutputDeviceTag, 472f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie (const char*)defaultOutputDevice); 473f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie sp<DeviceDescriptor> device = 474f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie module->getDeclaredDevices().getDeviceFromTagName(String8((const char*)defaultOutputDevice)); 475f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie if (device != 0 && ctx->getDefaultOutputDevice() == 0) { 476f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie ctx->setDefaultOutputDevice(device); 477f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie ALOGV("%s: default is %08x", __FUNCTION__, ctx->getDefaultOutputDevice()->type()); 478f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 479f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie xmlFree(defaultOutputDevice); 480f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 481f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 482f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie children = children->next; 483f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 484f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie return NO_ERROR; 485f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie} 486f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 487f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieconst char *const GlobalConfigTraits::tag = "globalConfiguration"; 488f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 489f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieconst char GlobalConfigTraits::Attributes::speakerDrcEnabled[] = "speaker_drc_enabled"; 490f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 491f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 492f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffiestatus_t GlobalConfigTraits::deserialize(const xmlNode *cur, AudioPolicyConfig &config) 493f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie{ 494f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie const xmlNode *root = cur->xmlChildrenNode; 495f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie while (root != NULL) { 496f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie if (!xmlStrcmp(root->name, (const xmlChar *)tag)) { 497f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie string speakerDrcEnabled = 498f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie getXmlAttribute(root, Attributes::speakerDrcEnabled); 499f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie bool isSpeakerDrcEnabled; 500f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie if (!speakerDrcEnabled.empty() && 501f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie convertTo<string, bool>(speakerDrcEnabled, isSpeakerDrcEnabled)) { 502f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie config.setSpeakerDrcEnabled(isSpeakerDrcEnabled); 503f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 504f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie return NO_ERROR; 505f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 506f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie root = root->next; 507f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 508f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie return NO_ERROR; 509f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie} 510f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 511f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 512f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieconst char *const VolumeTraits::tag = "volume"; 513f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieconst char *const VolumeTraits::collectionTag = "volumes"; 514f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieconst char *const VolumeTraits::volumePointTag = "point"; 515f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 516f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieconst char VolumeTraits::Attributes::stream[] = "stream"; 517f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffieconst char VolumeTraits::Attributes::deviceCategory[] = "deviceCategory"; 518c9d7c4e35afd48ac8a315f53666943b6210dafa1François Gaffieconst char VolumeTraits::Attributes::reference[] = "ref"; 519f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 520f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffiestatus_t VolumeTraits::deserialize(_xmlDoc *doc, const _xmlNode *root, PtrElement &element, 521f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie PtrSerializingCtx /*serializingContext*/) 522f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie{ 523f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie string streamTypeLiteral = getXmlAttribute(root, Attributes::stream); 524f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie if (streamTypeLiteral.empty()) { 525f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie ALOGE("%s: No %s found", __FUNCTION__, Attributes::stream); 526f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie return BAD_VALUE; 527f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 528f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie audio_stream_type_t streamType; 529f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie if (!StreamTypeConverter::fromString(streamTypeLiteral, streamType)) { 530f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie ALOGE("%s: Invalid %s", __FUNCTION__, Attributes::stream); 531f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie return BAD_VALUE; 532f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 533f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie string deviceCategoryLiteral = getXmlAttribute(root, Attributes::deviceCategory); 534f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie if (deviceCategoryLiteral.empty()) { 535f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie ALOGE("%s: No %s found", __FUNCTION__, Attributes::deviceCategory); 536f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie return BAD_VALUE; 537f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 538f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie device_category deviceCategory; 539f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie if (!DeviceCategoryConverter::fromString(deviceCategoryLiteral, deviceCategory)) { 540f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie ALOGE("%s: Invalid %s=%s", __FUNCTION__, Attributes::deviceCategory, 541f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie deviceCategoryLiteral.c_str()); 542f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie return BAD_VALUE; 543f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 544c9d7c4e35afd48ac8a315f53666943b6210dafa1François Gaffie 545c9d7c4e35afd48ac8a315f53666943b6210dafa1François Gaffie string referenceName = getXmlAttribute(root, Attributes::reference); 546c9d7c4e35afd48ac8a315f53666943b6210dafa1François Gaffie const _xmlNode *ref = NULL; 547c9d7c4e35afd48ac8a315f53666943b6210dafa1François Gaffie if (!referenceName.empty()) { 54819219b44e05555b29e00ce56ce273d168fa83888François Gaffie getReference<VolumeTraits>(root->parent, ref, referenceName); 549c9d7c4e35afd48ac8a315f53666943b6210dafa1François Gaffie if (ref == NULL) { 550c9d7c4e35afd48ac8a315f53666943b6210dafa1François Gaffie ALOGE("%s: No reference Ptr found for %s", __FUNCTION__, referenceName.c_str()); 551c9d7c4e35afd48ac8a315f53666943b6210dafa1François Gaffie return BAD_VALUE; 552c9d7c4e35afd48ac8a315f53666943b6210dafa1François Gaffie } 553c9d7c4e35afd48ac8a315f53666943b6210dafa1François Gaffie } 554c9d7c4e35afd48ac8a315f53666943b6210dafa1François Gaffie 555d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie element = new Element(deviceCategory, streamType); 556d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie 557c9d7c4e35afd48ac8a315f53666943b6210dafa1François Gaffie const xmlNode *child = referenceName.empty() ? root->xmlChildrenNode : ref->xmlChildrenNode; 558f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie while (child != NULL) { 559f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie if (!xmlStrcmp(child->name, (const xmlChar *)volumePointTag)) { 560f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie xmlChar *pointDefinition = xmlNodeListGetString(doc, child->xmlChildrenNode, 1);; 561f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie if (pointDefinition == NULL) { 562f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie return BAD_VALUE; 563f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 564f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie ALOGV("%s: %s=%s", __FUNCTION__, tag, (const char*)pointDefinition); 565f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie Vector<int32_t> point; 566f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie collectionFromString<DefaultTraits<int32_t> >((const char*)pointDefinition, point, ","); 567f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie if (point.size() != 2) { 568f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie ALOGE("%s: Invalid %s: %s", __FUNCTION__, volumePointTag, 569f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie (const char*)pointDefinition); 570f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie return BAD_VALUE; 571f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 572d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie element->add(CurvePoint(point[0], point[1])); 573f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie xmlFree(pointDefinition); 574f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 575f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie child = child->next; 576f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 577f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie return NO_ERROR; 578f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie} 579f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 580f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois GaffiePolicySerializer::PolicySerializer() : mRootElementName(rootName) 581f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie{ 582f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie std::ostringstream oss; 583f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie oss << gMajor << "." << gMinor; 584f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie mVersion = oss.str(); 585f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie ALOGV("%s: Version=%s Root=%s", __FUNCTION__, mVersion.c_str(), mRootElementName.c_str()); 586f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie} 587f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 588f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffiestatus_t PolicySerializer::deserialize(const char *configFile, AudioPolicyConfig &config) 589f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie{ 590f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie xmlDocPtr doc; 591f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie doc = xmlParseFile(configFile); 592f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie if (doc == NULL) { 593f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie ALOGE("%s: Could not parse %s document.", __FUNCTION__, configFile); 594f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie return BAD_VALUE; 595f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 596f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie xmlNodePtr cur = xmlDocGetRootElement(doc); 597f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie if (cur == NULL) { 598f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie ALOGE("%s: Could not parse %s document: empty.", __FUNCTION__, configFile); 599f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie xmlFreeDoc(doc); 600f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie return BAD_VALUE; 601f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 602f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie if (xmlXIncludeProcess(doc) < 0) { 603f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie ALOGE("%s: libxml failed to resolve XIncludes on %s document.", __FUNCTION__, configFile); 604f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 605f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 606f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie if (xmlStrcmp(cur->name, (const xmlChar *) mRootElementName.c_str())) { 607f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie ALOGE("%s: No %s root element found in xml data %s.", __FUNCTION__, mRootElementName.c_str(), 608f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie (const char *)cur->name); 609f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie xmlFreeDoc(doc); 610f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie return BAD_VALUE; 611f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 612f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 613f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie string version = getXmlAttribute(cur, versionAttribute); 614f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie if (version.empty()) { 615f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie ALOGE("%s: No version found in root node %s", __FUNCTION__, mRootElementName.c_str()); 616f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie return BAD_VALUE; 617f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 618f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie if (version != mVersion) { 619f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie ALOGE("%s: Version does not match; expect %s got %s", __FUNCTION__, mVersion.c_str(), 620f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie version.c_str()); 621f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie return BAD_VALUE; 622f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie } 623f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie // Lets deserialize children 624f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie // Modules 625f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie ModuleTraits::Collection modules; 626f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie deserializeCollection<ModuleTraits>(doc, cur, modules, &config); 627f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie config.setHwModules(modules); 628f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 629f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie // deserialize volume section 630f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie VolumeTraits::Collection volumes; 631d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie deserializeCollection<VolumeTraits>(doc, cur, volumes, &config); 632d1ab2bd4f1ea166a7e9e81cfd7f3e5dd47135d4dFrançois Gaffie config.setVolumes(volumes); 633f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 634f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie // Global Configuration 635f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie GlobalConfigTraits::deserialize(cur, config); 636f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 637f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie xmlFreeDoc(doc); 638f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie return android::OK; 639f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie} 640f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie 641f4ad6e5637b6deccdac4b60615383f290b3806cfFrançois Gaffie}; // namespace android 642