audiopolicy: More XML deserializer refactorings

 -- use root and cur argument names consistently;

 -- replace 'while' loops with 'for' loops;

 -- avoid passing around of 'xmlDoc';

 -- get rid of PtrElement, parametrize adding to collections.

 -- make possible to return immutable elements via Return<>
    container from android::hardware.

Test: Compare dumpsys media.audio_policy A/B, check audio
Change-Id: I5e499bdd7196703c4f788d881f331eb9629bf790
diff --git a/services/audiopolicy/Android.mk b/services/audiopolicy/Android.mk
index b75e957..c577589 100644
--- a/services/audiopolicy/Android.mk
+++ b/services/audiopolicy/Android.mk
@@ -81,7 +81,7 @@
 LOCAL_SHARED_LIBRARIES += libmediametrics
 
 ifeq ($(USE_XML_AUDIO_POLICY_CONF), 1)
-LOCAL_SHARED_LIBRARIES += libicuuc libxml2
+LOCAL_SHARED_LIBRARIES += libhidlbase libicuuc libxml2
 
 LOCAL_CFLAGS += -DUSE_XML_AUDIO_POLICY_CONF
 endif #ifeq ($(USE_XML_AUDIO_POLICY_CONF), 1)
diff --git a/services/audiopolicy/common/managerdefinitions/Android.mk b/services/audiopolicy/common/managerdefinitions/Android.mk
index bacb780..3336b79 100644
--- a/services/audiopolicy/common/managerdefinitions/Android.mk
+++ b/services/audiopolicy/common/managerdefinitions/Android.mk
@@ -39,7 +39,7 @@
 
 LOCAL_SRC_FILES += src/Serializer.cpp
 
-LOCAL_SHARED_LIBRARIES += libicuuc libxml2
+LOCAL_SHARED_LIBRARIES += libhidlbase libicuuc libxml2
 
 LOCAL_C_INCLUDES += \
     external/libxml2/include \
diff --git a/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp b/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
index e062e4e..d5a09fe 100644
--- a/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
@@ -20,6 +20,7 @@
 #include <memory>
 #include <string>
 
+#include <hidl/Status.h>
 #include <libxml/parser.h>
 #include <libxml/xinclude.h>
 #include <media/convert.h>
@@ -34,14 +35,20 @@
 
 namespace {
 
+// TODO(mnaganov): Consider finding an alternative for using HIDL code.
+using hardware::Return;
+using hardware::Status;
 using utilities::convertTo;
 
 template<typename E, typename C>
 struct BaseSerializerTraits {
-    typedef E Element;
-    typedef sp<E> PtrElement;
+    typedef sp<E> Element;
     typedef C Collection;
     typedef void* PtrSerializingCtx;
+
+    static status_t addElementToCollection(const Element &element, Collection *collection) {
+        return collection->add(element) >= 0 ? NO_ERROR : BAD_VALUE;
+    }
 };
 
 struct AudioGainTraits : public BaseSerializerTraits<AudioGain, AudioGainCollection>
@@ -66,8 +73,7 @@
         static constexpr const char *maxRampMs = "maxRampMs";
     };
 
-    static status_t deserialize(xmlDoc *doc, const xmlNode *root, PtrElement *element,
-                                PtrSerializingCtx serializingContext);
+    static Return<Element> deserialize(const xmlNode *cur, PtrSerializingCtx serializingContext);
     // No children
 };
 
@@ -85,8 +91,7 @@
         static constexpr const char *channelMasks = "channelMasks";
     };
 
-    static status_t deserialize(xmlDoc *doc, const xmlNode *root, PtrElement *element,
-                                PtrSerializingCtx serializingContext);
+    static Return<Element> deserialize(const xmlNode *cur, PtrSerializingCtx serializingContext);
 };
 
 struct MixPortTraits : public BaseSerializerTraits<IOProfile, IOProfileCollection>
@@ -104,8 +109,7 @@
         static constexpr const char *maxActiveCount = "maxActiveCount";
     };
 
-    static status_t deserialize(xmlDoc *doc, const xmlNode *root, PtrElement *element,
-                                PtrSerializingCtx serializingContext);
+    static Return<Element> deserialize(const xmlNode *cur, PtrSerializingCtx serializingContext);
     // Children: GainTraits
 };
 
@@ -125,8 +129,7 @@
         static constexpr const char *address = "address";
     };
 
-    static status_t deserialize(xmlDoc *doc, const xmlNode *root, PtrElement *element,
-                                PtrSerializingCtx serializingContext);
+    static Return<Element> deserialize(const xmlNode *cur, PtrSerializingCtx serializingContext);
     // Children: GainTraits (optional)
 };
 
@@ -146,8 +149,7 @@
 
     typedef HwModule *PtrSerializingCtx;
 
-    static status_t deserialize(xmlDoc *doc, const xmlNode *root, PtrElement *element,
-                                PtrSerializingCtx ctx);
+    static Return<Element> deserialize(const xmlNode *cur, PtrSerializingCtx serializingContext);
 };
 
 struct ModuleTraits : public BaseSerializerTraits<HwModule, HwModuleCollection>
@@ -167,9 +169,7 @@
 
     typedef AudioPolicyConfig *PtrSerializingCtx;
 
-    static status_t deserialize(xmlDoc *doc, const xmlNode *root, PtrElement *element,
-                                PtrSerializingCtx serializingContext);
-
+    static Return<Element> deserialize(const xmlNode *cur, PtrSerializingCtx serializingContext);
     // Children: mixPortTraits, devicePortTraits, and routeTraits
     // Need to call deserialize on each child
 };
@@ -201,8 +201,7 @@
         static constexpr const char *referenceName = "name";
     };
 
-    static status_t deserialize(xmlDoc *doc, const xmlNode *root, PtrElement *element,
-                                PtrSerializingCtx serializingContext);
+    static Return<Element> deserialize(const xmlNode *cur, PtrSerializingCtx serializingContext);
     // No Children
 };
 
@@ -213,7 +212,7 @@
     {
         ALOGV("%s: Version=%s Root=%s", __func__, mVersion.c_str(), rootName);
     }
-    status_t deserialize(const char *str, AudioPolicyConfig *config);
+    status_t deserialize(const char *configFile, AudioPolicyConfig *config);
 
 private:
     static constexpr const char *rootName = "audioPolicyConfiguration";
@@ -257,10 +256,9 @@
 template <class Trait>
 const xmlNode* getReference(const xmlNode *cur, const std::string &refName)
 {
-    while (cur != NULL) {
+    for (; cur != NULL; cur = cur->next) {
         if (!xmlStrcmp(cur->name, reinterpret_cast<const xmlChar*>(Trait::collectionTag))) {
-            const xmlNode *child = cur->children;
-            while (child != NULL) {
+            for (const xmlNode *child = cur->children; child != NULL; child = child->next) {
                 if ((!xmlStrcmp(child->name,
                                         reinterpret_cast<const xmlChar*>(Trait::referenceTag)))) {
                     std::string name = getXmlAttribute(child, Trait::Attributes::referenceName);
@@ -268,100 +266,93 @@
                         return child;
                     }
                 }
-                child = child->next;
             }
         }
-        cur = cur->next;
     }
     return NULL;
 }
 
 template <class Trait>
-status_t deserializeCollection(xmlDoc *doc, const xmlNode *cur,
+status_t deserializeCollection(const xmlNode *cur,
         typename Trait::Collection *collection,
         typename Trait::PtrSerializingCtx serializingContext)
 {
-    cur = cur->xmlChildrenNode;
-    while (cur != NULL) {
-        if (xmlStrcmp(cur->name, reinterpret_cast<const xmlChar*>(Trait::collectionTag)) &&
-                xmlStrcmp(cur->name, reinterpret_cast<const xmlChar*>(Trait::tag))) {
-            cur = cur->next;
-            continue;
+    for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) {
+        const xmlNode *child = NULL;
+        if (!xmlStrcmp(cur->name, reinterpret_cast<const xmlChar*>(Trait::collectionTag))) {
+            child = cur->xmlChildrenNode;
+        } else if (!xmlStrcmp(cur->name, reinterpret_cast<const xmlChar*>(Trait::tag))) {
+            child = cur;
         }
-        const xmlNode *child = cur;
-        if (!xmlStrcmp(child->name, reinterpret_cast<const xmlChar*>(Trait::collectionTag))) {
-            child = child->xmlChildrenNode;
-        }
-        while (child != NULL) {
+        for (; child != NULL; child = child->next) {
             if (!xmlStrcmp(child->name, reinterpret_cast<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", __func__,
-                          Trait::collectionTag);
+                auto element = Trait::deserialize(child, serializingContext);
+                if (element.isOk()) {
+                    status_t status = Trait::addElementToCollection(element, collection);
+                    if (status != NO_ERROR) {
+                        ALOGE("%s: could not add element to %s collection", __func__,
+                            Trait::collectionTag);
+                        return status;
+                    }
+                } else {
                     return BAD_VALUE;
                 }
             }
-            child = child->next;
         }
         if (!xmlStrcmp(cur->name, reinterpret_cast<const xmlChar*>(Trait::tag))) {
             return NO_ERROR;
         }
-        cur = cur->next;
     }
     return NO_ERROR;
 }
 
-status_t AudioGainTraits::deserialize(xmlDoc */*doc*/, const xmlNode *root, PtrElement *element,
-                                      PtrSerializingCtx /*serializingContext*/)
+Return<AudioGainTraits::Element> AudioGainTraits::deserialize(const xmlNode *cur,
+        PtrSerializingCtx /*serializingContext*/)
 {
     static uint32_t index = 0;
-    PtrElement &gain = *element = new Element(index++, true);
+    Element gain = new AudioGain(index++, true);
 
-    std::string mode = getXmlAttribute(root, Attributes::mode);
+    std::string mode = getXmlAttribute(cur, Attributes::mode);
     if (!mode.empty()) {
         gain->setMode(GainModeConverter::maskFromString(mode));
     }
 
-    std::string channelsLiteral = getXmlAttribute(root, Attributes::channelMask);
+    std::string channelsLiteral = getXmlAttribute(cur, Attributes::channelMask);
     if (!channelsLiteral.empty()) {
         gain->setChannelMask(channelMaskFromString(channelsLiteral));
     }
 
-    std::string minValueMBLiteral = getXmlAttribute(root, Attributes::minValueMB);
+    std::string minValueMBLiteral = getXmlAttribute(cur, Attributes::minValueMB);
     int32_t minValueMB;
     if (!minValueMBLiteral.empty() && convertTo(minValueMBLiteral, minValueMB)) {
         gain->setMinValueInMb(minValueMB);
     }
 
-    std::string maxValueMBLiteral = getXmlAttribute(root, Attributes::maxValueMB);
+    std::string maxValueMBLiteral = getXmlAttribute(cur, Attributes::maxValueMB);
     int32_t maxValueMB;
     if (!maxValueMBLiteral.empty() && convertTo(maxValueMBLiteral, maxValueMB)) {
         gain->setMaxValueInMb(maxValueMB);
     }
 
-    std::string defaultValueMBLiteral = getXmlAttribute(root, Attributes::defaultValueMB);
+    std::string defaultValueMBLiteral = getXmlAttribute(cur, Attributes::defaultValueMB);
     int32_t defaultValueMB;
     if (!defaultValueMBLiteral.empty() && convertTo(defaultValueMBLiteral, defaultValueMB)) {
         gain->setDefaultValueInMb(defaultValueMB);
     }
 
-    std::string stepValueMBLiteral = getXmlAttribute(root, Attributes::stepValueMB);
+    std::string stepValueMBLiteral = getXmlAttribute(cur, Attributes::stepValueMB);
     uint32_t stepValueMB;
     if (!stepValueMBLiteral.empty() && convertTo(stepValueMBLiteral, stepValueMB)) {
         gain->setStepValueInMb(stepValueMB);
     }
 
-    std::string minRampMsLiteral = getXmlAttribute(root, Attributes::minRampMs);
+    std::string minRampMsLiteral = getXmlAttribute(cur, Attributes::minRampMs);
     uint32_t minRampMs;
     if (!minRampMsLiteral.empty() && convertTo(minRampMsLiteral, minRampMs)) {
         gain->setMinRampInMs(minRampMs);
     }
 
-    std::string maxRampMsLiteral = getXmlAttribute(root, Attributes::maxRampMs);
+    std::string maxRampMsLiteral = getXmlAttribute(cur, Attributes::maxRampMs);
     uint32_t maxRampMs;
     if (!maxRampMsLiteral.empty() && convertTo(maxRampMsLiteral, maxRampMs)) {
         gain->setMaxRampInMs(maxRampMs);
@@ -370,20 +361,21 @@
           gain->getMode(), gain->getChannelMask(), gain->getMinValueInMb(),
           gain->getMaxValueInMb());
 
-    if (gain->getMode() == 0) {
-        return BAD_VALUE;
+    if (gain->getMode() != 0) {
+        return gain;
+    } else {
+        return Status::fromStatusT(BAD_VALUE);
     }
-    return NO_ERROR;
 }
 
-status_t AudioProfileTraits::deserialize(xmlDoc */*doc*/, const xmlNode *root, PtrElement *element,
-                                         PtrSerializingCtx /*serializingContext*/)
+Return<AudioProfileTraits::Element> AudioProfileTraits::deserialize(const xmlNode *cur,
+        PtrSerializingCtx /*serializingContext*/)
 {
-    std::string samplingRates = getXmlAttribute(root, Attributes::samplingRates);
-    std::string format = getXmlAttribute(root, Attributes::format);
-    std::string channels = getXmlAttribute(root, Attributes::channelMasks);
+    std::string samplingRates = getXmlAttribute(cur, Attributes::samplingRates);
+    std::string format = getXmlAttribute(cur, Attributes::format);
+    std::string channels = getXmlAttribute(cur, Attributes::channelMasks);
 
-    PtrElement &profile = *element = new Element(formatFromString(format, gDynamicFormat),
+    Element profile = new AudioProfile(formatFromString(format, gDynamicFormat),
             channelMasksFromString(channels, ","),
             samplingRatesFromString(samplingRates, ","));
 
@@ -391,33 +383,33 @@
     profile->setDynamicChannels(profile->getChannels().isEmpty());
     profile->setDynamicRate(profile->getSampleRates().isEmpty());
 
-    return NO_ERROR;
+    return profile;
 }
 
-status_t MixPortTraits::deserialize(xmlDoc *doc, const xmlNode *child, PtrElement *element,
-                                    PtrSerializingCtx /*serializingContext*/)
+Return<MixPortTraits::Element> MixPortTraits::deserialize(const xmlNode *child,
+        PtrSerializingCtx /*serializingContext*/)
 {
     std::string name = getXmlAttribute(child, Attributes::name);
     if (name.empty()) {
         ALOGE("%s: No %s found", __func__, Attributes::name);
-        return BAD_VALUE;
+        return Status::fromStatusT(BAD_VALUE);
     }
     ALOGV("%s: %s %s=%s", __func__, tag, Attributes::name, name.c_str());
     std::string role = getXmlAttribute(child, Attributes::role);
     if (role.empty()) {
         ALOGE("%s: No %s found", __func__, Attributes::role);
-        return BAD_VALUE;
+        return Status::fromStatusT(BAD_VALUE);
     }
     ALOGV("%s: Role=%s", __func__, role.c_str());
     audio_port_role_t portRole = (role == Attributes::roleSource) ?
             AUDIO_PORT_ROLE_SOURCE : AUDIO_PORT_ROLE_SINK;
 
-    PtrElement &mixPort = *element = new Element(String8(name.c_str()), portRole);
+    Element mixPort = new IOProfile(String8(name.c_str()), portRole);
 
     AudioProfileTraits::Collection profiles;
-    status_t status = deserializeCollection<AudioProfileTraits>(doc, child, &profiles, NULL);
+    status_t status = deserializeCollection<AudioProfileTraits>(child, &profiles, NULL);
     if (status != NO_ERROR) {
-        return status;
+        return Status::fromStatusT(status);
     }
     if (profiles.isEmpty()) {
         profiles.add(AudioProfile::createFullDynamic());
@@ -444,34 +436,34 @@
     }
     // Deserialize children
     AudioGainTraits::Collection gains;
-    status = deserializeCollection<AudioGainTraits>(doc, child, &gains, NULL);
+    status = deserializeCollection<AudioGainTraits>(child, &gains, NULL);
     if (status != NO_ERROR) {
-        return status;
+        return Status::fromStatusT(status);
     }
     mixPort->setGains(gains);
 
-    return NO_ERROR;
+    return mixPort;
 }
 
-status_t DevicePortTraits::deserialize(xmlDoc *doc, const xmlNode *root, PtrElement *element,
-                                       PtrSerializingCtx /*serializingContext*/)
+Return<DevicePortTraits::Element> DevicePortTraits::deserialize(const xmlNode *cur,
+        PtrSerializingCtx /*serializingContext*/)
 {
-    std::string name = getXmlAttribute(root, Attributes::tagName);
+    std::string name = getXmlAttribute(cur, Attributes::tagName);
     if (name.empty()) {
         ALOGE("%s: No %s found", __func__, Attributes::tagName);
-        return BAD_VALUE;
+        return Status::fromStatusT(BAD_VALUE);
     }
     ALOGV("%s: %s %s=%s", __func__, tag, Attributes::tagName, name.c_str());
-    std::string typeName = getXmlAttribute(root, Attributes::type);
+    std::string typeName = getXmlAttribute(cur, Attributes::type);
     if (typeName.empty()) {
         ALOGE("%s: no type for %s", __func__, name.c_str());
-        return BAD_VALUE;
+        return Status::fromStatusT(BAD_VALUE);
     }
     ALOGV("%s: %s %s=%s", __func__, tag, Attributes::type, typeName.c_str());
-    std::string role = getXmlAttribute(root, Attributes::role);
+    std::string role = getXmlAttribute(cur, Attributes::role);
     if (role.empty()) {
         ALOGE("%s: No %s found", __func__, Attributes::role);
-        return BAD_VALUE;
+        return Status::fromStatusT(BAD_VALUE);
     }
     ALOGV("%s: %s %s=%s", __func__, tag, Attributes::role, role.c_str());
     audio_port_role_t portRole = (role == Attributes::roleSource) ?
@@ -482,20 +474,20 @@
             (!audio_is_input_device(type) && portRole == AUDIO_PORT_ROLE_SOURCE) ||
             (!audio_is_output_devices(type) && portRole == AUDIO_PORT_ROLE_SINK)) {
         ALOGW("%s: bad type %08x", __func__, type);
-        return BAD_VALUE;
+        return Status::fromStatusT(BAD_VALUE);
     }
-    PtrElement &deviceDesc = *element = new Element(type, String8(name.c_str()));
+    Element deviceDesc = new DeviceDescriptor(type, String8(name.c_str()));
 
-    std::string address = getXmlAttribute(root, Attributes::address);
+    std::string address = getXmlAttribute(cur, Attributes::address);
     if (!address.empty()) {
         ALOGV("%s: address=%s for %s", __func__, address.c_str(), name.c_str());
         deviceDesc->mAddress = String8(address.c_str());
     }
 
     AudioProfileTraits::Collection profiles;
-    status_t status = deserializeCollection<AudioProfileTraits>(doc, root, &profiles, NULL);
+    status_t status = deserializeCollection<AudioProfileTraits>(cur, &profiles, NULL);
     if (status != NO_ERROR) {
-        return status;
+        return Status::fromStatusT(status);
     }
     if (profiles.isEmpty()) {
         profiles.add(AudioProfile::createFullDynamic());
@@ -503,46 +495,45 @@
     deviceDesc->setAudioProfiles(profiles);
 
     // Deserialize AudioGain children
-    status = deserializeCollection<AudioGainTraits>(doc, root, &deviceDesc->mGains, NULL);
+    status = deserializeCollection<AudioGainTraits>(cur, &deviceDesc->mGains, NULL);
     if (status != NO_ERROR) {
-        return status;
+        return Status::fromStatusT(status);
     }
     ALOGV("%s: adding device tag %s type %08x address %s", __func__,
           deviceDesc->getName().string(), type, deviceDesc->mAddress.string());
-    return NO_ERROR;
+    return deviceDesc;
 }
 
-status_t RouteTraits::deserialize(xmlDoc */*doc*/, const xmlNode *root, PtrElement *element,
-                                  PtrSerializingCtx ctx)
+Return<RouteTraits::Element> RouteTraits::deserialize(const xmlNode *cur, PtrSerializingCtx ctx)
 {
-    std::string type = getXmlAttribute(root, Attributes::type);
+    std::string type = getXmlAttribute(cur, Attributes::type);
     if (type.empty()) {
         ALOGE("%s: No %s found", __func__, Attributes::type);
-        return BAD_VALUE;
+        return Status::fromStatusT(BAD_VALUE);
     }
     audio_route_type_t routeType = (type == Attributes::typeMix) ?
                 AUDIO_ROUTE_MIX : AUDIO_ROUTE_MUX;
 
     ALOGV("%s: %s %s=%s", __func__, tag, Attributes::type, type.c_str());
-    PtrElement &route = *element = new Element(routeType);
+    Element route = new AudioRoute(routeType);
 
-    std::string sinkAttr = getXmlAttribute(root, Attributes::sink);
+    std::string sinkAttr = getXmlAttribute(cur, Attributes::sink);
     if (sinkAttr.empty()) {
         ALOGE("%s: No %s found", __func__, Attributes::sink);
-        return BAD_VALUE;
+        return Status::fromStatusT(BAD_VALUE);
     }
     // Convert Sink name to port pointer
     sp<AudioPort> sink = ctx->findPortByTagName(String8(sinkAttr.c_str()));
     if (sink == NULL) {
         ALOGE("%s: no sink found with name=%s", __func__, sinkAttr.c_str());
-        return BAD_VALUE;
+        return Status::fromStatusT(BAD_VALUE);
     }
     route->setSink(sink);
 
-    std::string sourcesAttr = getXmlAttribute(root, Attributes::sources);
+    std::string sourcesAttr = getXmlAttribute(cur, Attributes::sources);
     if (sourcesAttr.empty()) {
         ALOGE("%s: No %s found", __func__, Attributes::sources);
-        return BAD_VALUE;
+        return Status::fromStatusT(BAD_VALUE);
     }
     // Tokenize and Convert Sources name to port pointer
     AudioPortVector sources;
@@ -554,7 +545,7 @@
             sp<AudioPort> source = ctx->findPortByTagName(String8(devTag));
             if (source == NULL) {
                 ALOGE("%s: no source found with name=%s", __func__, devTag);
-                return BAD_VALUE;
+                return Status::fromStatusT(BAD_VALUE);
             }
             sources.add(source);
         }
@@ -567,19 +558,18 @@
         source->addRoute(route);
     }
     route->setSources(sources);
-    return NO_ERROR;
+    return route;
 }
 
-status_t ModuleTraits::deserialize(xmlDocPtr doc, const xmlNode *root, PtrElement *element,
-                                   PtrSerializingCtx ctx)
+Return<ModuleTraits::Element> ModuleTraits::deserialize(const xmlNode *cur, PtrSerializingCtx ctx)
 {
-    std::string name = getXmlAttribute(root, Attributes::name);
+    std::string name = getXmlAttribute(cur, Attributes::name);
     if (name.empty()) {
         ALOGE("%s: No %s found", __func__, Attributes::name);
-        return BAD_VALUE;
+        return Status::fromStatusT(BAD_VALUE);
     }
     uint32_t versionMajor = 0, versionMinor = 0;
-    std::string versionLiteral = getXmlAttribute(root, Attributes::version);
+    std::string versionLiteral = getXmlAttribute(cur, Attributes::version);
     if (!versionLiteral.empty()) {
         sscanf(versionLiteral.c_str(), "%u.%u", &versionMajor, &versionMinor);
         ALOGV("%s: mHalVersion = major %u minor %u",  __func__,
@@ -588,40 +578,40 @@
 
     ALOGV("%s: %s %s=%s", __func__, tag, Attributes::name, name.c_str());
 
-    PtrElement &module = *element = new Element(name.c_str(), versionMajor, versionMinor);
+    Element module = new HwModule(name.c_str(), versionMajor, versionMinor);
 
     // Deserialize childrens: Audio Mix Port, Audio Device Ports (Source/Sink), Audio Routes
     MixPortTraits::Collection mixPorts;
-    status_t status = deserializeCollection<MixPortTraits>(doc, root, &mixPorts, NULL);
+    status_t status = deserializeCollection<MixPortTraits>(cur, &mixPorts, NULL);
     if (status != NO_ERROR) {
-        return status;
+        return Status::fromStatusT(status);
     }
     module->setProfiles(mixPorts);
 
     DevicePortTraits::Collection devicePorts;
-    status = deserializeCollection<DevicePortTraits>(doc, root, &devicePorts, NULL);
+    status = deserializeCollection<DevicePortTraits>(cur, &devicePorts, NULL);
     if (status != NO_ERROR) {
-        return status;
+        return Status::fromStatusT(status);
     }
     module->setDeclaredDevices(devicePorts);
 
     RouteTraits::Collection routes;
-    status = deserializeCollection<RouteTraits>(doc, root, &routes, module.get());
+    status = deserializeCollection<RouteTraits>(cur, &routes, module.get());
     if (status != NO_ERROR) {
-        return status;
+        return Status::fromStatusT(status);
     }
     module->setRoutes(routes);
 
-    const xmlNode *children = root->xmlChildrenNode;
-    while (children != NULL) {
+    for (const xmlNode *children = cur->xmlChildrenNode; children != NULL;
+         children = children->next) {
         if (!xmlStrcmp(children->name, reinterpret_cast<const xmlChar*>(childAttachedDevicesTag))) {
             ALOGV("%s: %s %s found", __func__, tag, childAttachedDevicesTag);
-            const xmlNode *child = children->xmlChildrenNode;
-            while (child != NULL) {
+            for (const xmlNode *child = children->xmlChildrenNode; child != NULL;
+                 child = child->next) {
                 if (!xmlStrcmp(child->name,
                                 reinterpret_cast<const xmlChar*>(childAttachedDeviceTag))) {
                     auto attachedDevice = make_xmlUnique(xmlNodeListGetString(
-                                    doc, child->xmlChildrenNode, 1));
+                                    child->doc, child->xmlChildrenNode, 1));
                     if (attachedDevice != nullptr) {
                         ALOGV("%s: %s %s=%s", __func__, tag, childAttachedDeviceTag,
                                 reinterpret_cast<const char*>(attachedDevice.get()));
@@ -631,13 +621,12 @@
                         ctx->addAvailableDevice(device);
                     }
                 }
-                child = child->next;
             }
         }
         if (!xmlStrcmp(children->name,
                         reinterpret_cast<const xmlChar*>(childDefaultOutputDeviceTag))) {
             auto defaultOutputDevice = make_xmlUnique(xmlNodeListGetString(
-                            doc, children->xmlChildrenNode, 1));
+                            children->doc, children->xmlChildrenNode, 1));
             if (defaultOutputDevice != nullptr) {
                 ALOGV("%s: %s %s=%s", __func__, tag, childDefaultOutputDeviceTag,
                         reinterpret_cast<const char*>(defaultOutputDevice.get()));
@@ -650,18 +639,16 @@
                 }
             }
         }
-        children = children->next;
     }
-    return NO_ERROR;
+    return module;
 }
 
-status_t GlobalConfigTraits::deserialize(const xmlNode *cur, AudioPolicyConfig *config)
+status_t GlobalConfigTraits::deserialize(const xmlNode *root, AudioPolicyConfig *config)
 {
-    const xmlNode *root = cur->xmlChildrenNode;
-    while (root != NULL) {
-        if (!xmlStrcmp(root->name, reinterpret_cast<const xmlChar*>(tag))) {
+    for (const xmlNode *cur = root->xmlChildrenNode; cur != NULL; cur = cur->next) {
+        if (!xmlStrcmp(cur->name, reinterpret_cast<const xmlChar*>(tag))) {
             std::string speakerDrcEnabled =
-                    getXmlAttribute(root, Attributes::speakerDrcEnabled);
+                    getXmlAttribute(cur, Attributes::speakerDrcEnabled);
             bool isSpeakerDrcEnabled;
             if (!speakerDrcEnabled.empty() &&
                     convertTo<std::string, bool>(speakerDrcEnabled, isSpeakerDrcEnabled)) {
@@ -669,55 +656,54 @@
             }
             return NO_ERROR;
         }
-        root = root->next;
     }
     return NO_ERROR;
 }
 
-status_t VolumeTraits::deserialize(xmlDoc *doc, const xmlNode *root, PtrElement *element,
-                                   PtrSerializingCtx /*serializingContext*/)
+Return<VolumeTraits::Element> VolumeTraits::deserialize(const xmlNode *cur,
+        PtrSerializingCtx /*serializingContext*/)
 {
-    std::string streamTypeLiteral = getXmlAttribute(root, Attributes::stream);
+    std::string streamTypeLiteral = getXmlAttribute(cur, Attributes::stream);
     if (streamTypeLiteral.empty()) {
         ALOGE("%s: No %s found", __func__, Attributes::stream);
-        return BAD_VALUE;
+        return Status::fromStatusT(BAD_VALUE);
     }
     audio_stream_type_t streamType;
     if (!StreamTypeConverter::fromString(streamTypeLiteral, streamType)) {
         ALOGE("%s: Invalid %s", __func__, Attributes::stream);
-        return BAD_VALUE;
+        return Status::fromStatusT(BAD_VALUE);
     }
-    std::string deviceCategoryLiteral = getXmlAttribute(root, Attributes::deviceCategory);
+    std::string deviceCategoryLiteral = getXmlAttribute(cur, Attributes::deviceCategory);
     if (deviceCategoryLiteral.empty()) {
         ALOGE("%s: No %s found", __func__, Attributes::deviceCategory);
-        return BAD_VALUE;
+        return Status::fromStatusT(BAD_VALUE);
     }
     device_category deviceCategory;
     if (!DeviceCategoryConverter::fromString(deviceCategoryLiteral, deviceCategory)) {
         ALOGE("%s: Invalid %s=%s", __func__, Attributes::deviceCategory,
               deviceCategoryLiteral.c_str());
-        return BAD_VALUE;
+        return Status::fromStatusT(BAD_VALUE);
     }
 
-    std::string referenceName = getXmlAttribute(root, Attributes::reference);
+    std::string referenceName = getXmlAttribute(cur, Attributes::reference);
     const xmlNode *ref = NULL;
     if (!referenceName.empty()) {
-        ref = getReference<VolumeTraits>(root->parent, referenceName);
+        ref = getReference<VolumeTraits>(cur->parent, referenceName);
         if (ref == NULL) {
             ALOGE("%s: No reference Ptr found for %s", __func__, referenceName.c_str());
-            return BAD_VALUE;
+            return Status::fromStatusT(BAD_VALUE);
         }
     }
 
-    PtrElement &volCurve = *element = new Element(deviceCategory, streamType);
+    Element volCurve = new VolumeCurve(deviceCategory, streamType);
 
-    const xmlNode *child = referenceName.empty() ? root->xmlChildrenNode : ref->xmlChildrenNode;
-    while (child != NULL) {
+    for (const xmlNode *child = referenceName.empty() ? cur->xmlChildrenNode : ref->xmlChildrenNode;
+         child != NULL; child = child->next) {
         if (!xmlStrcmp(child->name, reinterpret_cast<const xmlChar*>(volumePointTag))) {
             auto pointDefinition = make_xmlUnique(xmlNodeListGetString(
-                            doc, child->xmlChildrenNode, 1));
+                            child->doc, child->xmlChildrenNode, 1));
             if (pointDefinition == nullptr) {
-                return BAD_VALUE;
+                return Status::fromStatusT(BAD_VALUE);
             }
             ALOGV("%s: %s=%s",
                     __func__, tag, reinterpret_cast<const char*>(pointDefinition.get()));
@@ -727,13 +713,12 @@
             if (point.size() != 2) {
                 ALOGE("%s: Invalid %s: %s", __func__, volumePointTag,
                         reinterpret_cast<const char*>(pointDefinition.get()));
-                return BAD_VALUE;
+                return Status::fromStatusT(BAD_VALUE);
             }
             volCurve->add(CurvePoint(point[0], point[1]));
         }
-        child = child->next;
     }
-    return NO_ERROR;
+    return volCurve;
 }
 
 status_t PolicySerializer::deserialize(const char *configFile, AudioPolicyConfig *config)
@@ -743,8 +728,8 @@
         ALOGE("%s: Could not parse %s document.", __func__, configFile);
         return BAD_VALUE;
     }
-    xmlNodePtr cur = xmlDocGetRootElement(doc.get());
-    if (cur == NULL) {
+    xmlNodePtr root = xmlDocGetRootElement(doc.get());
+    if (root == NULL) {
         ALOGE("%s: Could not parse %s document: empty.", __func__, configFile);
         return BAD_VALUE;
     }
@@ -752,13 +737,13 @@
         ALOGE("%s: libxml failed to resolve XIncludes on %s document.", __func__, configFile);
     }
 
-    if (xmlStrcmp(cur->name, reinterpret_cast<const xmlChar*>(rootName)))  {
+    if (xmlStrcmp(root->name, reinterpret_cast<const xmlChar*>(rootName)))  {
         ALOGE("%s: No %s root element found in xml data %s.", __func__, rootName,
-                reinterpret_cast<const char*>(cur->name));
+                reinterpret_cast<const char*>(root->name));
         return BAD_VALUE;
     }
 
-    std::string version = getXmlAttribute(cur, versionAttribute);
+    std::string version = getXmlAttribute(root, versionAttribute);
     if (version.empty()) {
         ALOGE("%s: No version found in root node %s", __func__, rootName);
         return BAD_VALUE;
@@ -771,7 +756,7 @@
     // Lets deserialize children
     // Modules
     ModuleTraits::Collection modules;
-    status_t status = deserializeCollection<ModuleTraits>(doc.get(), cur, &modules, config);
+    status_t status = deserializeCollection<ModuleTraits>(root, &modules, config);
     if (status != NO_ERROR) {
         return status;
     }
@@ -779,14 +764,14 @@
 
     // deserialize volume section
     VolumeTraits::Collection volumes;
-    status = deserializeCollection<VolumeTraits>(doc.get(), cur, &volumes, config);
+    status = deserializeCollection<VolumeTraits>(root, &volumes, config);
     if (status != NO_ERROR) {
         return status;
     }
     config->setVolumes(volumes);
 
     // Global Configuration
-    GlobalConfigTraits::deserialize(cur, config);
+    GlobalConfigTraits::deserialize(root, config);
 
     return android::OK;
 }