Merge "C-ify MediaTrack"
diff --git a/camera/ndk/impl/ACameraMetadata.cpp b/camera/ndk/impl/ACameraMetadata.cpp
index d73f744..94b5713 100644
--- a/camera/ndk/impl/ACameraMetadata.cpp
+++ b/camera/ndk/impl/ACameraMetadata.cpp
@@ -430,6 +430,7 @@
     ANDROID_STATISTICS_INFO_MAX_HISTOGRAM_COUNT,
     ANDROID_STATISTICS_INFO_MAX_SHARPNESS_MAP_VALUE,
     ANDROID_STATISTICS_INFO_SHARPNESS_MAP_SIZE,
+    ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION,
     ANDROID_DEPTH_MAX_DEPTH_SAMPLES,
 });
 
diff --git a/media/bufferpool/2.0/Accessor.cpp b/media/bufferpool/2.0/Accessor.cpp
index c1b62f8..b9837f7 100644
--- a/media/bufferpool/2.0/Accessor.cpp
+++ b/media/bufferpool/2.0/Accessor.cpp
@@ -122,7 +122,7 @@
     ResultStatus status = connect(&connection, &connectionId, &fmqDesc, false);
     if (status == ResultStatus::OK) {
         _hidl_cb(status, connection, connectionId, *fmqDesc,
-                 android::hardware::MQDescriptorSync<BufferInvalidationMessage>(
+                 android::hardware::MQDescriptorUnsync<BufferInvalidationMessage>(
                          std::vector<android::hardware::GrantorDescriptor>(),
                          nullptr /* nhandle */, 0 /* size */));
     } else {
@@ -130,7 +130,7 @@
                  android::hardware::MQDescriptorSync<BufferStatusMessage>(
                          std::vector<android::hardware::GrantorDescriptor>(),
                          nullptr /* nhandle */, 0 /* size */),
-                 android::hardware::MQDescriptorSync<BufferInvalidationMessage>(
+                 android::hardware::MQDescriptorUnsync<BufferInvalidationMessage>(
                          std::vector<android::hardware::GrantorDescriptor>(),
                          nullptr /* nhandle */, 0 /* size */));
     }
diff --git a/media/bufferpool/2.0/include/bufferpool/BufferPoolTypes.h b/media/bufferpool/2.0/include/bufferpool/BufferPoolTypes.h
index eb845e1..7c906cb 100644
--- a/media/bufferpool/2.0/include/bufferpool/BufferPoolTypes.h
+++ b/media/bufferpool/2.0/include/bufferpool/BufferPoolTypes.h
@@ -48,6 +48,7 @@
 namespace implementation {
 
 using ::android::hardware::kSynchronizedReadWrite;
+using ::android::hardware::kUnsynchronizedWrite;
 
 typedef uint32_t BufferId;
 typedef uint64_t TransactionId;
@@ -60,7 +61,7 @@
 typedef android::hardware::MessageQueue<BufferStatusMessage, kSynchronizedReadWrite> BufferStatusQueue;
 typedef BufferStatusQueue::Descriptor StatusDescriptor;
 
-typedef android::hardware::MessageQueue<BufferInvalidationMessage, kSynchronizedReadWrite>
+typedef android::hardware::MessageQueue<BufferInvalidationMessage, kUnsynchronizedWrite>
         BufferInvalidationQueue;
 typedef BufferInvalidationQueue::Descriptor InvalidationDescriptor;
 
diff --git a/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2Types.h b/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2Types.h
index 1fe2efa..10e07ea 100644
--- a/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2Types.h
+++ b/media/libmediaplayer2/include/mediaplayer2/MediaPlayer2Types.h
@@ -154,8 +154,8 @@
 enum mediaplayer2_states {
     MEDIAPLAYER2_STATE_IDLE         = 1001,
     MEDIAPLAYER2_STATE_PREPARED     = 1002,
-    MEDIAPLAYER2_STATE_PLAYING      = 1003,
-    MEDIAPLAYER2_STATE_PAUSED       = 1004,
+    MEDIAPLAYER2_STATE_PAUSED       = 1003,
+    MEDIAPLAYER2_STATE_PLAYING      = 1004,
     MEDIAPLAYER2_STATE_ERROR        = 1005,
 };
 
diff --git a/media/libmediaplayer2/mediaplayer2.cpp b/media/libmediaplayer2/mediaplayer2.cpp
index bafd32c..d9c9826 100644
--- a/media/libmediaplayer2/mediaplayer2.cpp
+++ b/media/libmediaplayer2/mediaplayer2.cpp
@@ -660,7 +660,7 @@
     Mutex::Autolock _l(mLock);
     if (mCurrentState & (MEDIA_PLAYER2_PAUSED|MEDIA_PLAYER2_PLAYBACK_COMPLETE))
         return NO_ERROR;
-    if ((mPlayer != 0) && (mCurrentState & MEDIA_PLAYER2_STARTED)) {
+    if ((mPlayer != 0) && (mCurrentState & (MEDIA_PLAYER2_STARTED | MEDIA_PLAYER2_PREPARED))) {
         status_t ret = mPlayer->pause();
         if (ret != NO_ERROR) {
             mCurrentState = MEDIA_PLAYER2_STATE_ERROR;
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2.cpp b/media/libmediaplayer2/nuplayer2/NuPlayer2.cpp
index e51727b..5bd1674 100644
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2.cpp
+++ b/media/libmediaplayer2/nuplayer2/NuPlayer2.cpp
@@ -969,7 +969,7 @@
                     onResume();
                 }
             } else {
-                onStart();
+                onStart(true /* play */);
             }
             mPausedByClient = false;
             notifyListener(mSrcId, MEDIA2_STARTED, 0, 0);
@@ -1502,6 +1502,9 @@
 
         case kWhatPause:
         {
+            if (!mStarted) {
+                onStart(false /* play */);
+            }
             onPause();
             notifyListener(mSrcId, MEDIA2_PAUSED, 0, 0);
             mPausedByClient = true;
@@ -1575,7 +1578,7 @@
     startPlaybackTimer("onresume");
 }
 
-void NuPlayer2::onStart() {
+void NuPlayer2::onStart(bool play) {
     ALOGV("onStart: mCrypto: %p", mCrypto.get());
 
     if (!mSourceStarted) {
@@ -1649,6 +1652,11 @@
         mRenderer->setVideoFrameRate(rate);
     }
 
+    // Renderer is created in paused state.
+    if (play) {
+        mRenderer->resume();
+    }
+
     if (mVideoDecoder != NULL) {
         mVideoDecoder->setRenderer(mRenderer);
     }
@@ -2472,7 +2480,7 @@
         mRenderer->resume();
     }
 
-    onStart();
+    onStart(true /* play */);
     mPausedByClient = false;
     notifyListener(mSrcId, MEDIA2_STARTED, 0, 0);
 }
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2.h b/media/libmediaplayer2/nuplayer2/NuPlayer2.h
index 77845ac..e55cdbe 100644
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2.h
+++ b/media/libmediaplayer2/nuplayer2/NuPlayer2.h
@@ -301,7 +301,7 @@
     void handleFlushComplete(bool audio, bool isDecoder);
     void finishFlushIfPossible();
 
-    void onStart();
+    void onStart(bool play);
     void onResume();
     void onPause();
 
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2Driver.cpp b/media/libmediaplayer2/nuplayer2/NuPlayer2Driver.cpp
index b02e3f6..cb4b06d 100644
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2Driver.cpp
+++ b/media/libmediaplayer2/nuplayer2/NuPlayer2Driver.cpp
@@ -327,9 +327,9 @@
 
     switch (mState) {
         case STATE_PAUSED:
-        case STATE_PREPARED:
             return OK;
 
+        case STATE_PREPARED:
         case STATE_RUNNING:
             mState = STATE_PAUSED;
             mPlayer->pause();
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2Renderer.cpp b/media/libmediaplayer2/nuplayer2/NuPlayer2Renderer.cpp
index 021ddde..c5ce15a 100644
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2Renderer.cpp
+++ b/media/libmediaplayer2/nuplayer2/NuPlayer2Renderer.cpp
@@ -115,7 +115,7 @@
       mNotifyCompleteAudio(false),
       mNotifyCompleteVideo(false),
       mSyncQueues(false),
-      mPaused(false),
+      mPaused(true),
       mPauseDrainAudioAllowedUs(0),
       mVideoSampleReceived(false),
       mVideoRenderingStarted(false),
diff --git a/media/libstagefright/MediaExtractorFactory.cpp b/media/libstagefright/MediaExtractorFactory.cpp
index a0a3a75..f1c6acd 100644
--- a/media/libstagefright/MediaExtractorFactory.cpp
+++ b/media/libstagefright/MediaExtractorFactory.cpp
@@ -271,6 +271,9 @@
     if (libDir) {
         struct dirent* libEntry;
         while ((libEntry = readdir(libDir))) {
+            if (libEntry->d_name[0] == '.') {
+                continue;
+            }
             String8 libPath = String8(libDirPath) + "/" + libEntry->d_name;
             void *libHandle = dlopen(libPath.string(), RTLD_NOW | RTLD_LOCAL);
             if (libHandle) {
diff --git a/media/libstagefright/httplive/LiveSession.cpp b/media/libstagefright/httplive/LiveSession.cpp
index 7eff8eb..86872c5 100644
--- a/media/libstagefright/httplive/LiveSession.cpp
+++ b/media/libstagefright/httplive/LiveSession.cpp
@@ -445,7 +445,7 @@
                return -EAGAIN;
             };
             (*accessUnit)->meta()->setInt32(
-                    "trackIndex", mPlaylist->getSelectedIndex());
+                    "track-index", mPlaylist->getSelectedIndex());
             (*accessUnit)->meta()->setInt64("baseUs", mRealTimeBaseUs);
         } else if (stream == STREAMTYPE_METADATA) {
             HLSTime mdTime((*accessUnit)->meta());
diff --git a/media/mtp/MtpFfsHandle.cpp b/media/mtp/MtpFfsHandle.cpp
index f25fc71..ad3c068 100644
--- a/media/mtp/MtpFfsHandle.cpp
+++ b/media/mtp/MtpFfsHandle.cpp
@@ -212,7 +212,6 @@
     uint16_t value = setup->wValue;
     std::vector<char> buf;
     buf.resize(length);
-    int ret = 0;
 
     if (!(type & USB_DIR_IN)) {
         if (::read(mControl, buf.data(), length) != length) {
@@ -225,8 +224,8 @@
         case MTP_REQ_RESET:
         case MTP_REQ_CANCEL:
             errno = ECANCELED;
-            ret = -1;
-            break;
+            return -1;
+        //    break;
         case MTP_REQ_GET_DEVICE_STATUS:
         {
             if (length < sizeof(struct mtp_device_status) + 4) {
diff --git a/packages/MediaComponents/Android.mk b/packages/MediaComponents/Android.mk
index 55a5424..fff3a62 100644
--- a/packages/MediaComponents/Android.mk
+++ b/packages/MediaComponents/Android.mk
@@ -14,59 +14,57 @@
 # limitations under the License.
 #
 
-# This package is excluded from build for now since APIs using this apk became hidden.
-#
-#LOCAL_PATH := $(call my-dir)
-#ifneq ($(TARGET_BUILD_PDK),true) # Build MediaComponents only if this is not a PDK build.  MediaComponents won't
-## build in PDK builds because frameworks/base/core/java is not available but
-## IMediaSession2.aidl and IMediaController2.aidl are using classes from
-## frameworks/base/core/java.
-#
-#include $(CLEAR_VARS)
-#
-#LOCAL_PACKAGE_NAME := MediaComponents
-#LOCAL_MODULE_OWNER := google
-#
-## TODO: create a separate key for this package.
-#LOCAL_CERTIFICATE := platform
-#
-## TODO: Use System SDK once public APIs are approved
-## LOCAL_SDK_VERSION := system_current
-#LOCAL_PRIVATE_PLATFORM_APIS := true
-#
-#LOCAL_SRC_FILES := \
-#    $(call all-java-files-under, src) \
-#    $(call all-Iaidl-files-under, src)
-#
-#LOCAL_PROGUARD_FLAG_FILES := proguard.cfg
-#
-#LOCAL_MULTILIB := first
-#
-#LOCAL_JAVA_LIBRARIES += androidx.annotation_annotation
-#
-## To embed native libraries in package, uncomment the lines below.
-##LOCAL_MODULE_TAGS := samples
-##LOCAL_JNI_SHARED_LIBRARIES := \
-##    libaacextractor \
-##    libamrextractor \
-##    libflacextractor \
-##    libmidiextractor \
-##    libmkvextractor \
-##    libmp3extractor \
-##    libmp4extractor \
-##    libmpeg2extractor \
-##    liboggextractor \
-##    libwavextractor \
-#
-## TODO: Remove dependency with other support libraries.
-#LOCAL_STATIC_ANDROID_LIBRARIES += \
-#    androidx.legacy_legacy-support-v4 \
-#    androidx.appcompat_appcompat \
-#    androidx.palette_palette
-#LOCAL_USE_AAPT2 := true
-#
-#include $(BUILD_PACKAGE)
-#
-#endif  # ifneq ($(TARGET_BUILD_PDK),true)
-#
-#include $(call all-makefiles-under,$(LOCAL_PATH))
+LOCAL_PATH := $(call my-dir)
+ifneq ($(TARGET_BUILD_PDK),true) # Build MediaComponents only if this is not a PDK build.  MediaComponents won't
+# build in PDK builds because frameworks/base/core/java is not available but
+# IMediaSession2.aidl and IMediaController2.aidl are using classes from
+# frameworks/base/core/java.
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := MediaComponents
+LOCAL_MODULE_OWNER := google
+
+# TODO: create a separate key for this package.
+LOCAL_CERTIFICATE := platform
+
+# TODO: Use System SDK once public APIs are approved
+# LOCAL_SDK_VERSION := system_current
+LOCAL_PRIVATE_PLATFORM_APIS := true
+
+LOCAL_SRC_FILES := \
+    $(call all-java-files-under, src) \
+    $(call all-Iaidl-files-under, src)
+
+LOCAL_PROGUARD_FLAG_FILES := proguard.cfg
+
+LOCAL_MULTILIB := first
+
+LOCAL_JAVA_LIBRARIES += androidx.annotation_annotation
+
+# To embed native libraries in package, uncomment the lines below.
+#LOCAL_MODULE_TAGS := samples
+#LOCAL_JNI_SHARED_LIBRARIES := \
+#    libaacextractor \
+#    libamrextractor \
+#    libflacextractor \
+#    libmidiextractor \
+#    libmkvextractor \
+#    libmp3extractor \
+#    libmp4extractor \
+#    libmpeg2extractor \
+#    liboggextractor \
+#    libwavextractor \
+
+# TODO: Remove dependency with other support libraries.
+LOCAL_STATIC_ANDROID_LIBRARIES += \
+    androidx.legacy_legacy-support-v4 \
+    androidx.appcompat_appcompat \
+    androidx.palette_palette
+LOCAL_USE_AAPT2 := true
+
+include $(BUILD_PACKAGE)
+
+endif  # ifneq ($(TARGET_BUILD_PDK),true)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/packages/MediaComponents/src/com/android/widget/VideoView2Impl.java b/packages/MediaComponents/src/com/android/widget/VideoView2Impl.java
index ffb145a..54ef719 100644
--- a/packages/MediaComponents/src/com/android/widget/VideoView2Impl.java
+++ b/packages/MediaComponents/src/com/android/widget/VideoView2Impl.java
@@ -33,8 +33,7 @@
 import android.media.MediaMetadata2;
 import android.media.MediaMetadataRetriever;
 import android.media.MediaPlayer2;
-import android.media.MediaPlayer2.MediaPlayer2EventCallback;
-import android.media.MediaPlayer2.OnSubtitleDataListener;
+import android.media.MediaPlayer2.EventCallback;
 import android.media.MediaPlayer2Impl;
 import android.media.Metadata;
 import android.media.PlaybackParams;
@@ -733,12 +732,11 @@
                     runnable.run();
                 }
             };
-            mMediaPlayer.setMediaPlayer2EventCallback(executor, mMediaPlayer2Callback);
+            mMediaPlayer.registerEventCallback(executor, mMediaPlayer2Callback);
 
             mCurrentBufferPercentage = -1;
             mMediaPlayer.setDataSource(dsd);
             mMediaPlayer.setAudioAttributes(mAudioAttributes);
-            mMediaPlayer.setOnSubtitleDataListener(mSubtitleListener);
             // we don't set the target state here either, but preserve the
             // target state that was there before.
             mCurrentState = STATE_PREPARING;
@@ -1106,10 +1104,10 @@
         mInstance.addView(mMusicView, 0);
     }
 
-    OnSubtitleDataListener mSubtitleListener =
-            new OnSubtitleDataListener() {
+    EventCallback mMediaPlayer2Callback =
+            new EventCallback() {
                 @Override
-                public void onSubtitleData(MediaPlayer2 mp, SubtitleData data) {
+                public void onSubtitleData(MediaPlayer2 mp, DataSourceDesc dsd, SubtitleData data) {
                     if (DEBUG) {
                         Log.d(TAG, "onSubtitleData(): getTrackIndex: " + data.getTrackIndex()
                                 + ", getCurrentPosition: " + mp.getCurrentPosition()
@@ -1133,10 +1131,7 @@
                         }
                     }
                 }
-            };
 
-    MediaPlayer2EventCallback mMediaPlayer2Callback =
-            new MediaPlayer2EventCallback() {
                 @Override
                 public void onVideoSizeChanged(
                         MediaPlayer2 mp, DataSourceDesc dsd, int width, int height) {
@@ -1169,7 +1164,7 @@
                         extractTracks();
                     } else if (what == MediaPlayer2.MEDIA_INFO_PREPARED) {
                         this.onPrepared(mp, dsd);
-                    } else if (what == MediaPlayer2.MEDIA_INFO_PLAYBACK_COMPLETE) {
+                    } else if (what == MediaPlayer2.MEDIA_INFO_DATA_SOURCE_END) {
                         this.onCompletion(mp, dsd);
                     } else if (what == MediaPlayer2.MEDIA_INFO_BUFFERING_UPDATE) {
                         this.onBufferingUpdate(mp, dsd, extra);
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index d7a4451..13ca912 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -6963,7 +6963,7 @@
                                 framesIn, mSampleRate, activeTrack->mSampleRate));
 
                 if (activeTrack->isDirect()) {
-                    // No RecordBufferConverter used for compressed formats. Pass
+                    // No RecordBufferConverter used for direct streams. Pass
                     // straight from RecordThread buffer to RecordTrack buffer.
                     AudioBufferProvider::Buffer buffer;
                     buffer.frameCount = framesOut;
@@ -6973,7 +6973,7 @@
                                 "%s() read less than expected (%zu vs %zu)",
                                 __func__, buffer.frameCount, framesOut);
                         framesOut = buffer.frameCount;
-                        memcpy(activeTrack->mSink.raw, buffer.raw, buffer.frameCount);
+                        memcpy(activeTrack->mSink.raw, buffer.raw, buffer.frameCount * mFrameSize);
                         activeTrack->mResamplerBufferProvider->releaseBuffer(&buffer);
                     } else {
                         framesOut = 0;
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;
 }
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 600f968..380f0fb 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -2697,7 +2697,7 @@
     mAudioSources.dump(fd);
 
     if (!mSurroundFormats.empty()) {
-        result = String8("\nManually Enabled Surround Formats:\n");
+        result = String8("\nEnabled Surround Formats:\n");
         size_t i = 0;
         for (const auto& fmt : mSurroundFormats) {
             result.append(i++ == 0 ? "  " : ", ");
@@ -3554,50 +3554,6 @@
     return computeVolume(stream, index, device);
 }
 
-status_t AudioPolicyManager::getSupportedFormats(audio_io_handle_t ioHandle,
-                                                 FormatVector& formats) {
-    if (ioHandle == AUDIO_IO_HANDLE_NONE) {
-        return BAD_VALUE;
-    }
-    String8 reply;
-    reply = mpClientInterface->getParameters(
-            ioHandle, String8(AudioParameter::keyStreamSupportedFormats));
-    ALOGV("%s: supported formats %s", __FUNCTION__, reply.string());
-    AudioParameter repliedParameters(reply);
-    if (repliedParameters.get(
-            String8(AudioParameter::keyStreamSupportedFormats), reply) != NO_ERROR) {
-        ALOGE("%s: failed to retrieve format, bailing out", __FUNCTION__);
-        return BAD_VALUE;
-    }
-    for (auto format : formatsFromString(reply.string())) {
-        // Only AUDIO_FORMAT_AAC_LC will be used in Settings UI for all AAC formats.
-        for (size_t i = 0; i < ARRAY_SIZE(AAC_FORMATS); i++) {
-            if (format == AAC_FORMATS[i]) {
-                format = AUDIO_FORMAT_AAC_LC;
-                break;
-            }
-        }
-        bool exist = false;
-        for (size_t i = 0; i < formats.size(); i++) {
-            if (format == formats[i]) {
-                exist = true;
-                break;
-            }
-        }
-        bool isSurroundFormat = false;
-        for (size_t i = 0; i < ARRAY_SIZE(SURROUND_FORMATS); i++) {
-            if (SURROUND_FORMATS[i] == format) {
-                isSurroundFormat = true;
-                break;
-            }
-        }
-        if (!exist && isSurroundFormat) {
-            formats.add(format);
-        }
-    }
-    return NO_ERROR;
-}
-
 status_t AudioPolicyManager::getSurroundFormats(unsigned int *numSurroundFormats,
                                                 audio_format_t *surroundFormats,
                                                 bool *surroundFormatsEnabled,
@@ -3618,89 +3574,45 @@
     size_t formatsWritten = 0;
     size_t formatsMax = *numSurroundFormats;
     *numSurroundFormats = 0;
-    FormatVector formats;
+    std::unordered_set<audio_format_t> formats;
     if (reported) {
-        // Only get surround formats which are reported by device.
-        // First list already open outputs that can be routed to this device
-        audio_devices_t device = AUDIO_DEVICE_OUT_HDMI;
-        SortedVector<audio_io_handle_t> outputs;
-        bool reportedFormatFound = false;
-        status_t status;
-        sp<SwAudioOutputDescriptor> desc;
-        for (size_t i = 0; i < mOutputs.size(); i++) {
-            desc = mOutputs.valueAt(i);
-            if (!desc->isDuplicated() && (desc->supportedDevices() & device)) {
-                outputs.add(mOutputs.keyAt(i));
-            }
-        }
-        // Open an output to query dynamic parameters.
-        DeviceVector hdmiOutputDevices = mAvailableOutputDevices.getDevicesFromTypeMask(
-                AUDIO_DEVICE_OUT_HDMI);
-        for (size_t i = 0; i < hdmiOutputDevices.size(); i++) {
-            String8 address = hdmiOutputDevices[i]->mAddress;
-            for (const auto& hwModule : mHwModules) {
-                for (size_t i = 0; i < hwModule->getOutputProfiles().size(); i++) {
-                    sp<IOProfile> profile = hwModule->getOutputProfiles()[i];
-                    if (profile->supportDevice(AUDIO_DEVICE_OUT_HDMI) &&
-                            profile->supportDeviceAddress(address)) {
-                        size_t j;
-                        for (j = 0; j < outputs.size(); j++) {
-                            desc = mOutputs.valueFor(outputs.itemAt(j));
-                            if (!desc->isDuplicated() && desc->mProfile == profile) {
-                                break;
-                            }
-                        }
-                        if (j != outputs.size()) {
-                            status = getSupportedFormats(outputs.itemAt(j), formats);
-                            reportedFormatFound |= (status == NO_ERROR);
-                            continue;
-                        }
-
-                        if (!profile->canOpenNewIo()) {
-                            ALOGW("Max Output number %u already opened for this profile %s",
-                                  profile->maxOpenCount, profile->getTagName().c_str());
-                            continue;
-                        }
-
-                        ALOGV("opening output for device %08x with params %s profile %p name %s",
-                              device, address.string(), profile.get(), profile->getName().string());
-                        desc = new SwAudioOutputDescriptor(profile, mpClientInterface);
-                        audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
-                        status_t status = desc->open(nullptr, device, address,
-                                                     AUDIO_STREAM_DEFAULT, AUDIO_OUTPUT_FLAG_NONE,
-                                                     &output);
-
-                        if (status == NO_ERROR) {
-                            status = getSupportedFormats(output, formats);
-                            reportedFormatFound |= (status == NO_ERROR);
-                            desc->close();
-                            output = AUDIO_IO_HANDLE_NONE;
-                        }
-                    }
-                }
-            }
-        }
-
-        if (!reportedFormatFound) {
-            return UNKNOWN_ERROR;
+        // Return formats from HDMI profiles, that have already been resolved by
+        // checkOutputsForDevice().
+        DeviceVector hdmiOutputDevs = mAvailableOutputDevices.getDevicesFromTypeMask(
+              AUDIO_DEVICE_OUT_HDMI);
+        for (size_t i = 0; i < hdmiOutputDevs.size(); i++) {
+             FormatVector supportedFormats =
+                 hdmiOutputDevs[i]->getAudioPort()->getAudioProfiles().getSupportedFormats();
+             for (size_t j = 0; j < supportedFormats.size(); j++) {
+                 if (std::find(std::begin(SURROUND_FORMATS),
+                                 std::end(SURROUND_FORMATS),
+                                 supportedFormats[j]) != std::end(SURROUND_FORMATS)) {
+                     formats.insert(supportedFormats[j]);
+                 } else if (std::find(std::begin(AAC_FORMATS),
+                                 std::end(AAC_FORMATS),
+                                 supportedFormats[j]) != std::end(AAC_FORMATS)) {
+                     // if any format in AAC_FORMATS is reported, insert AUDIO_FORMAT_AAC_LC as this
+                     // is the only AAC format used in the TvSettings UI for all AAC formats.
+                     formats.insert(AUDIO_FORMAT_AAC_LC);
+                 }
+             }
         }
     } else {
         for (size_t i = 0; i < ARRAY_SIZE(SURROUND_FORMATS); i++) {
-            formats.add(SURROUND_FORMATS[i]);
+            formats.insert(SURROUND_FORMATS[i]);
         }
     }
-    for (size_t i = 0; i < formats.size(); i++) {
+    for (const auto& format: formats) {
         if (formatsWritten < formatsMax) {
-            surroundFormats[formatsWritten] = formats[i];
+            surroundFormats[formatsWritten] = format;
             bool formatEnabled = false;
-            if (formats[i] == AUDIO_FORMAT_AAC_LC) {
-                for (size_t j = 0; j < ARRAY_SIZE(AAC_FORMATS); j++) {
+            if (format == AUDIO_FORMAT_AAC_LC) {
+                for (size_t j = 0; j < ARRAY_SIZE(AAC_FORMATS) && !formatEnabled; j++) {
                     formatEnabled =
-                            mSurroundFormats.find(AAC_FORMATS[i]) != mSurroundFormats.end();
-                    break;
+                            mSurroundFormats.find(AAC_FORMATS[j]) != mSurroundFormats.end();
                 }
             } else {
-                formatEnabled = mSurroundFormats.find(formats[i]) != mSurroundFormats.end();
+                formatEnabled = mSurroundFormats.find(format) != mSurroundFormats.end();
             }
             surroundFormatsEnabled[formatsWritten++] = formatEnabled;
         }
@@ -3744,6 +3656,7 @@
         return INVALID_OPERATION;
     }
 
+    std::unordered_set<audio_format_t> surroundFormatsBackup(mSurroundFormats);
     if (enabled) {
         if (audioFormat == AUDIO_FORMAT_AAC_LC) {
             for (size_t i = 0; i < ARRAY_SIZE(AAC_FORMATS); i++) {
@@ -3806,23 +3719,7 @@
     // Undo the surround formats change due to no audio profiles updated.
     if (!profileUpdated) {
         ALOGW("%s() no audio profiles updated, undoing surround formats change", __func__);
-        if (enabled) {
-            if (audioFormat == AUDIO_FORMAT_AAC_LC) {
-                for (size_t i = 0; i < ARRAY_SIZE(AAC_FORMATS); i++) {
-                    mSurroundFormats.erase(AAC_FORMATS[i]);
-                }
-            } else {
-                mSurroundFormats.erase(audioFormat);
-            }
-        } else {
-            if (audioFormat == AUDIO_FORMAT_AAC_LC) {
-                for (size_t i = 0; i < ARRAY_SIZE(AAC_FORMATS); i++) {
-                    mSurroundFormats.insert(AAC_FORMATS[i]);
-                }
-            } else {
-                mSurroundFormats.insert(audioFormat);
-            }
-        }
+        mSurroundFormats = std::move(surroundFormatsBackup);
     }
 
     return profileUpdated ? NO_ERROR : INVALID_OPERATION;
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 6f4cce1..fcb9d25 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -613,8 +613,6 @@
         void filterSurroundFormats(FormatVector *formatsPtr);
         void filterSurroundChannelMasks(ChannelsVector *channelMasksPtr);
 
-        status_t getSupportedFormats(audio_io_handle_t ioHandle, FormatVector& formats);
-
         // Support for Multi-Stream Decoder (MSD) module
         sp<DeviceDescriptor> getMsdAudioInDevice() const;
         audio_devices_t getMsdAudioOutDeviceTypes() const;
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 786fd7f..48e38bb 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -281,7 +281,6 @@
 status_t Camera3Device::disconnectImpl() {
     ATRACE_CALL();
     Mutex::Autolock il(mInterfaceLock);
-    Mutex::Autolock stLock(mTrackerLock);
 
     ALOGI("%s: E", __FUNCTION__);
 
@@ -346,6 +345,7 @@
     {
         Mutex::Autolock l(mLock);
         mRequestThread.clear();
+        Mutex::Autolock stLock(mTrackerLock);
         mStatusTracker.clear();
         interface = mInterface.get();
     }