Merge "Heif decoder API for decoding image sequences"
diff --git a/camera/ndk/impl/ACameraCaptureSession.cpp b/camera/ndk/impl/ACameraCaptureSession.cpp
index d6f1412..68db233 100644
--- a/camera/ndk/impl/ACameraCaptureSession.cpp
+++ b/camera/ndk/impl/ACameraCaptureSession.cpp
@@ -33,7 +33,9 @@
         dev->unlockDevice();
     }
     // Fire onClosed callback
-    (*mUserSessionCallback.onClosed)(mUserSessionCallback.context, this);
+    if (mUserSessionCallback.onClosed != nullptr) {
+        (*mUserSessionCallback.onClosed)(mUserSessionCallback.context, this);
+    }
     ALOGV("~ACameraCaptureSession: %p is deleted", this);
 }
 
diff --git a/camera/ndk/ndk_vendor/tests/AImageReaderVendorTest.cpp b/camera/ndk/ndk_vendor/tests/AImageReaderVendorTest.cpp
index 7ab0124..938b5f5 100644
--- a/camera/ndk/ndk_vendor/tests/AImageReaderVendorTest.cpp
+++ b/camera/ndk/ndk_vendor/tests/AImageReaderVendorTest.cpp
@@ -253,21 +253,9 @@
         return true;
     }
 
-    static void onDeviceDisconnected(void* /*obj*/, ACameraDevice* /*device*/) {}
-
-    static void onDeviceError(void* /*obj*/, ACameraDevice* /*device*/, int /*errorCode*/) {}
-
-    static void onSessionClosed(void* /*obj*/, ACameraCaptureSession* /*session*/) {}
-
-    static void onSessionReady(void* /*obj*/, ACameraCaptureSession* /*session*/) {}
-
-    static void onSessionActive(void* /*obj*/, ACameraCaptureSession* /*session*/) {}
-
    private:
-    ACameraDevice_StateCallbacks mDeviceCb{this, onDeviceDisconnected,
-                                           onDeviceError};
-    ACameraCaptureSession_stateCallbacks mSessionCb{
-        this, onSessionClosed, onSessionReady, onSessionActive};
+    ACameraDevice_StateCallbacks mDeviceCb{this, nullptr, nullptr};
+    ACameraCaptureSession_stateCallbacks mSessionCb{ this, nullptr, nullptr, nullptr};
 
     native_handle_t* mImgReaderAnw = nullptr;  // not owned by us.
 
diff --git a/include/media/ExtendedAudioBufferProvider.h b/include/media/ExtendedAudioBufferProvider.h
index d653cc3..99d3c13 120000
--- a/include/media/ExtendedAudioBufferProvider.h
+++ b/include/media/ExtendedAudioBufferProvider.h
@@ -1 +1 @@
-../../media/libmedia/include/media/ExtendedAudioBufferProvider.h
\ No newline at end of file
+../../media/libaudioclient/include/media/ExtendedAudioBufferProvider.h
\ No newline at end of file
diff --git a/include/media/SingleStateQueue.h b/include/media/SingleStateQueue.h
deleted file mode 120000
index 619f6ee..0000000
--- a/include/media/SingleStateQueue.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/SingleStateQueue.h
\ No newline at end of file
diff --git a/include/media/nbaio/SingleStateQueue.h b/include/media/nbaio/SingleStateQueue.h
new file mode 120000
index 0000000..d3e0553
--- /dev/null
+++ b/include/media/nbaio/SingleStateQueue.h
@@ -0,0 +1 @@
+../../../media/libnbaio/include_mono/media/nbaio/SingleStateQueue.h
\ No newline at end of file
diff --git a/include/private/media/AudioTrackShared.h b/include/private/media/AudioTrackShared.h
index 5f19f74..1b1f149 100644
--- a/include/private/media/AudioTrackShared.h
+++ b/include/private/media/AudioTrackShared.h
@@ -28,7 +28,7 @@
 #include <media/AudioResamplerPublic.h>
 #include <media/AudioTimestamp.h>
 #include <media/Modulo.h>
-#include <media/SingleStateQueue.h>
+#include <media/nbaio/SingleStateQueue.h>
 
 namespace android {
 
diff --git a/media/codec2/components/aac/C2SoftAacEnc.cpp b/media/codec2/components/aac/C2SoftAacEnc.cpp
index 1dc676b..a8f39d5 100644
--- a/media/codec2/components/aac/C2SoftAacEnc.cpp
+++ b/media/codec2/components/aac/C2SoftAacEnc.cpp
@@ -159,7 +159,8 @@
       mInputSize(0),
       mNextFrameTimestampUs(0),
       mSignalledError(false),
-      mOutIndex(0u) {
+      mOutIndex(0u),
+      mRemainderLen(0u) {
 }
 
 C2SoftAacEnc::~C2SoftAacEnc() {
@@ -185,6 +186,7 @@
     mInputSize = 0u;
     mNextFrameTimestampUs = 0;
     mSignalledError = false;
+    mRemainderLen = 0;
     return C2_OK;
 }
 
@@ -369,18 +371,21 @@
         mInputTimeSet = true;
     }
 
-    size_t numFrames = (capacity + mInputSize + (eos ? mNumBytesPerInputFrame - 1 : 0))
-            / mNumBytesPerInputFrame;
+    size_t numFrames =
+        (mRemainderLen + capacity + mInputSize + (eos ? mNumBytesPerInputFrame - 1 : 0))
+        / mNumBytesPerInputFrame;
     ALOGV("capacity = %zu; mInputSize = %zu; numFrames = %zu "
-          "mNumBytesPerInputFrame = %u inputTS = %lld",
+          "mNumBytesPerInputFrame = %u inputTS = %lld remaining = %zu",
           capacity, mInputSize, numFrames,
-          mNumBytesPerInputFrame, work->input.ordinal.timestamp.peekll());
+          mNumBytesPerInputFrame, work->input.ordinal.timestamp.peekll(),
+          mRemainderLen);
 
     std::shared_ptr<C2LinearBlock> block;
     std::unique_ptr<C2WriteView> wView;
     uint8_t *outPtr = temp;
     size_t outAvailable = 0u;
     uint64_t inputIndex = work->input.ordinal.frameIndex.peeku();
+    size_t bytesPerSample = channelCount * sizeof(int16_t);
 
     AACENC_InArgs inargs;
     AACENC_OutArgs outargs;
@@ -449,7 +454,25 @@
     };
     std::list<OutputBuffer> outputBuffers;
 
-    while (encoderErr == AACENC_OK && inargs.numInSamples > 0) {
+    if (mRemainderLen > 0) {
+        size_t offset = 0;
+        for (; mRemainderLen < bytesPerSample && offset < capacity; ++offset) {
+            mRemainder[mRemainderLen++] = data[offset];
+        }
+        data += offset;
+        capacity -= offset;
+        if (mRemainderLen == bytesPerSample) {
+            inBuffer[0] = mRemainder;
+            inBufferSize[0] = bytesPerSample;
+            inargs.numInSamples = channelCount;
+            mRemainderLen = 0;
+            ALOGV("Processing remainder");
+        } else {
+            // We have exhausted the input already
+            inargs.numInSamples = 0;
+        }
+    }
+    while (encoderErr == AACENC_OK && inargs.numInSamples >= channelCount) {
         if (numFrames && !block) {
             C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
             // TODO: error handling, proper usage, etc.
@@ -486,7 +509,7 @@
                 mNextFrameTimestampUs = work->input.ordinal.timestamp
                         + (consumed * 1000000ll / channelCount / sampleRate);
                 std::shared_ptr<C2Buffer> buffer = createLinearBuffer(block, 0, outargs.numOutBytes);
-#if defined(LOG_NDEBUG) && !LOG_NDEBUG
+#if 0
                 hexdump(outPtr, std::min(outargs.numOutBytes, 256));
 #endif
                 outPtr = temp;
@@ -503,12 +526,17 @@
                 inBufferSize[0] -= outargs.numInSamples * sizeof(int16_t);
                 inargs.numInSamples -= outargs.numInSamples;
             }
+
+            if (inBuffer[0] == mRemainder) {
+                inBuffer[0] = const_cast<uint8_t *>(data);
+                inBufferSize[0] = capacity;
+                inargs.numInSamples = capacity / sizeof(int16_t);
+            }
         }
         ALOGV("encoderErr = %d mInputSize = %zu "
               "inargs.numInSamples = %d, mNextFrameTimestampUs = %lld",
               encoderErr, mInputSize, inargs.numInSamples, mNextFrameTimestampUs.peekll());
     }
-
     if (eos && inBufferSize[0] > 0) {
         if (numFrames && !block) {
             C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE };
@@ -539,6 +567,14 @@
                            &outBufDesc,
                            &inargs,
                            &outargs);
+        inBufferSize[0] = 0;
+    }
+
+    if (inBufferSize[0] > 0) {
+        for (size_t i = 0; i < inBufferSize[0]; ++i) {
+            mRemainder[i] = static_cast<uint8_t *>(inBuffer[0])[i];
+        }
+        mRemainderLen = inBufferSize[0];
     }
 
     while (outputBuffers.size() > 1) {
diff --git a/media/codec2/components/aac/C2SoftAacEnc.h b/media/codec2/components/aac/C2SoftAacEnc.h
index 2655039..6ecfbdd 100644
--- a/media/codec2/components/aac/C2SoftAacEnc.h
+++ b/media/codec2/components/aac/C2SoftAacEnc.h
@@ -61,6 +61,10 @@
     bool mSignalledError;
     std::atomic_uint64_t mOutIndex;
 
+    // We support max 6 channels
+    uint8_t mRemainder[6 * sizeof(int16_t)];
+    size_t mRemainderLen;
+
     status_t initEncoder();
 
     status_t setAudioParams();
diff --git a/media/codec2/components/mpeg2/C2SoftMpeg2Dec.cpp b/media/codec2/components/mpeg2/C2SoftMpeg2Dec.cpp
index df7b403..a1f8ff3 100644
--- a/media/codec2/components/mpeg2/C2SoftMpeg2Dec.cpp
+++ b/media/codec2/components/mpeg2/C2SoftMpeg2Dec.cpp
@@ -47,6 +47,12 @@
         noInputLatency();
         noTimeStretch();
 
+        // TODO: Proper support for reorder depth.
+        addParameter(
+                DefineParam(mActualOutputDelay, C2_PARAMKEY_OUTPUT_DELAY)
+                .withConstValue(new C2PortActualDelayTuning::output(3u))
+                .build());
+
         // TODO: output latency and reordering
 
         addParameter(
diff --git a/media/codec2/sfplugin/Codec2InfoBuilder.cpp b/media/codec2/sfplugin/Codec2InfoBuilder.cpp
index 6b75eba..745d701 100644
--- a/media/codec2/sfplugin/Codec2InfoBuilder.cpp
+++ b/media/codec2/sfplugin/Codec2InfoBuilder.cpp
@@ -117,8 +117,9 @@
         }
     }
 
-    // For VP9, the static info is always propagated by framework.
+    // For VP9/AV1, the static info is always propagated by framework.
     supportsHdr |= (mediaType == MIMETYPE_VIDEO_VP9);
+    supportsHdr |= (mediaType == MIMETYPE_VIDEO_AV1);
 
     for (C2Value::Primitive profile : profileQuery[0].values.values) {
         pl.profile = (C2Config::profile_t)profile.ref<uint32_t>();
diff --git a/media/codec2/sfplugin/utils/Codec2Mapper.cpp b/media/codec2/sfplugin/utils/Codec2Mapper.cpp
index 7334834..ef6af48 100644
--- a/media/codec2/sfplugin/utils/Codec2Mapper.cpp
+++ b/media/codec2/sfplugin/utils/Codec2Mapper.cpp
@@ -382,10 +382,11 @@
     // TODO: will need to disambiguate between Main8 and Main10
     { C2Config::PROFILE_AV1_0, AV1ProfileMain8 },
     { C2Config::PROFILE_AV1_0, AV1ProfileMain10 },
+    { C2Config::PROFILE_AV1_0, AV1ProfileMain10HDR10 },
+    { C2Config::PROFILE_AV1_0, AV1ProfileMain10HDR10Plus },
 };
 
 ALookup<C2Config::profile_t, int32_t> sAv1HdrProfiles = {
-    { C2Config::PROFILE_AV1_0, AV1ProfileMain10 },
     { C2Config::PROFILE_AV1_0, AV1ProfileMain10HDR10 },
 };
 
@@ -662,6 +663,8 @@
         return std::make_shared<HevcProfileLevelMapper>(true, isHdr10Plus);
     } else if (mediaType == MIMETYPE_VIDEO_VP9) {
         return std::make_shared<Vp9ProfileLevelMapper>(true, isHdr10Plus);
+    } else if (mediaType == MIMETYPE_VIDEO_AV1) {
+        return std::make_shared<Av1ProfileLevelMapper>(true, isHdr10Plus);
     }
     return nullptr;
 }
diff --git a/media/libmedia/include/media/ExtendedAudioBufferProvider.h b/media/libaudioclient/include/media/ExtendedAudioBufferProvider.h
similarity index 100%
rename from media/libmedia/include/media/ExtendedAudioBufferProvider.h
rename to media/libaudioclient/include/media/ExtendedAudioBufferProvider.h
diff --git a/media/libaudiofoundation/include/media/AudioContainers.h b/media/libaudiofoundation/include/media/AudioContainers.h
new file mode 100644
index 0000000..3313224
--- /dev/null
+++ b/media/libaudiofoundation/include/media/AudioContainers.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <set>
+#include <vector>
+
+#include <system/audio.h>
+
+namespace android {
+
+using ChannelMaskSet = std::set<audio_channel_mask_t>;
+using FormatSet = std::set<audio_format_t>;
+using SampleRateSet = std::set<uint32_t>;
+
+using FormatVector = std::vector<audio_format_t>;
+
+static inline ChannelMaskSet asInMask(const ChannelMaskSet& channelMasks) {
+    ChannelMaskSet inMaskSet;
+    for (const auto &channel : channelMasks) {
+        if (audio_channel_mask_out_to_in(channel) != AUDIO_CHANNEL_INVALID) {
+            inMaskSet.insert(audio_channel_mask_out_to_in(channel));
+        }
+    }
+    return inMaskSet;
+}
+
+static inline ChannelMaskSet asOutMask(const ChannelMaskSet& channelMasks) {
+    ChannelMaskSet outMaskSet;
+    for (const auto &channel : channelMasks) {
+        if (audio_channel_mask_in_to_out(channel) != AUDIO_CHANNEL_INVALID) {
+            outMaskSet.insert(audio_channel_mask_in_to_out(channel));
+        }
+    }
+    return outMaskSet;
+}
+
+} // namespace android
\ No newline at end of file
diff --git a/media/libaudiohal/Android.bp b/media/libaudiohal/Android.bp
index 9803473..5837fcf 100644
--- a/media/libaudiohal/Android.bp
+++ b/media/libaudiohal/Android.bp
@@ -52,4 +52,10 @@
     name: "libaudiohal_headers",
 
     export_include_dirs: ["include"],
+
+    // This is needed because the stream interface includes media/MicrophoneInfo.h
+    // which is not in any library but has a dependency on headers from libbinder.
+    header_libs: ["libbinder_headers"],
+
+    export_header_lib_headers: ["libbinder_headers"],
 }
diff --git a/media/libmedia/IResourceManagerService.cpp b/media/libmedia/IResourceManagerService.cpp
index 9724fc1..00f9b88 100644
--- a/media/libmedia/IResourceManagerService.cpp
+++ b/media/libmedia/IResourceManagerService.cpp
@@ -72,12 +72,14 @@
 
     virtual void addResource(
             int pid,
+            int uid,
             int64_t clientId,
             const sp<IResourceManagerClient> client,
             const Vector<MediaResource> &resources) {
         Parcel data, reply;
         data.writeInterfaceToken(IResourceManagerService::getInterfaceDescriptor());
         data.writeInt32(pid);
+        data.writeInt32(uid);
         data.writeInt64(clientId);
         data.writeStrongBinder(IInterface::asBinder(client));
         writeToParcel(&data, resources);
@@ -129,6 +131,7 @@
         case ADD_RESOURCE: {
             CHECK_INTERFACE(IResourceManagerService, data, reply);
             int pid = data.readInt32();
+            int uid = data.readInt32();
             int64_t clientId = data.readInt64();
             sp<IResourceManagerClient> client(
                     interface_cast<IResourceManagerClient>(data.readStrongBinder()));
@@ -137,7 +140,7 @@
             }
             Vector<MediaResource> resources;
             readFromParcel(data, &resources);
-            addResource(pid, clientId, client, resources);
+            addResource(pid, uid, clientId, client, resources);
             return NO_ERROR;
         } break;
 
diff --git a/media/libmedia/include/media/IResourceManagerService.h b/media/libmedia/include/media/IResourceManagerService.h
index 1e4f6de..404519b 100644
--- a/media/libmedia/include/media/IResourceManagerService.h
+++ b/media/libmedia/include/media/IResourceManagerService.h
@@ -39,6 +39,7 @@
 
     virtual void addResource(
             int pid,
+            int uid,
             int64_t clientId,
             const sp<IResourceManagerClient> client,
             const Vector<MediaResource> &resources) = 0;
diff --git a/media/libmedia/include/media/MediaResource.h b/media/libmedia/include/media/MediaResource.h
index e1fdb9b..10d0e3b 100644
--- a/media/libmedia/include/media/MediaResource.h
+++ b/media/libmedia/include/media/MediaResource.h
@@ -31,12 +31,13 @@
         kNonSecureCodec,
         kGraphicMemory,
         kCpuBoost,
+        kBattery,
     };
 
     enum SubType {
         kUnspecifiedSubType = 0,
         kAudioCodec,
-        kVideoCodec
+        kVideoCodec,
     };
 
     MediaResource();
diff --git a/media/libmedia/include/media/TypeConverter.h b/media/libmedia/include/media/TypeConverter.h
index 2f8c209..011498a 100644
--- a/media/libmedia/include/media/TypeConverter.h
+++ b/media/libmedia/include/media/TypeConverter.h
@@ -17,10 +17,11 @@
 #ifndef ANDROID_TYPE_CONVERTER_H_
 #define ANDROID_TYPE_CONVERTER_H_
 
+#include <set>
 #include <string>
 #include <string.h>
-
 #include <vector>
+
 #include <system/audio.h>
 #include <utils/Log.h>
 #include <utils/Vector.h>
@@ -42,16 +43,6 @@
     }
 };
 template <typename T>
-struct VectorTraits
-{
-    typedef T Type;
-    typedef Vector<Type> Collection;
-    static void add(Collection &collection, Type value)
-    {
-        collection.add(value);
-    }
-};
-template <typename T>
 struct SortedVectorTraits
 {
     typedef T Type;
@@ -61,18 +52,28 @@
         collection.add(value);
     }
 };
+template <typename T>
+struct SetTraits
+{
+    typedef T Type;
+    typedef std::set<Type> Collection;
+    static void add(Collection &collection, Type value)
+    {
+        collection.insert(value);
+    }
+};
 
-using SampleRateTraits = SortedVectorTraits<uint32_t>;
+using SampleRateTraits = SetTraits<uint32_t>;
 using DeviceTraits = DefaultTraits<audio_devices_t>;
 struct OutputDeviceTraits : public DeviceTraits {};
 struct InputDeviceTraits : public DeviceTraits {};
-using ChannelTraits = SortedVectorTraits<audio_channel_mask_t>;
+using ChannelTraits = SetTraits<audio_channel_mask_t>;
 struct OutputChannelTraits : public ChannelTraits {};
 struct InputChannelTraits : public ChannelTraits {};
 struct ChannelIndexTraits : public ChannelTraits {};
 using InputFlagTraits = DefaultTraits<audio_input_flags_t>;
 using OutputFlagTraits = DefaultTraits<audio_output_flags_t>;
-using FormatTraits = VectorTraits<audio_format_t>;
+using FormatTraits = DefaultTraits<audio_format_t>;
 using GainModeTraits = DefaultTraits<audio_gain_mode_t>;
 using StreamTraits = DefaultTraits<audio_stream_type_t>;
 using AudioModeTraits = DefaultTraits<audio_mode_t>;
@@ -259,6 +260,7 @@
                                     || std::is_same<T, audio_source_t>::value
                                     || std::is_same<T, audio_stream_type_t>::value
                                     || std::is_same<T, audio_usage_t>::value
+                                    || std::is_same<T, audio_format_t>::value
                                     , int> = 0>
 static inline std::string toString(const T& value)
 {
@@ -291,14 +293,6 @@
     return result;
 }
 
-// TODO: Remove when FormatTraits uses DefaultTraits.
-static inline std::string toString(const audio_format_t& format)
-{
-    std::string result;
-    return TypeConverter<VectorTraits<audio_format_t>>::toString(format, result)
-            ? result : std::to_string(static_cast<int>(format));
-}
-
 static inline std::string toString(const audio_attributes_t& attributes)
 {
     std::ostringstream result;
diff --git a/media/libmedia/xsd/vts/Android.bp b/media/libmedia/xsd/vts/Android.bp
index b590a12..4739504 100644
--- a/media/libmedia/xsd/vts/Android.bp
+++ b/media/libmedia/xsd/vts/Android.bp
@@ -24,6 +24,7 @@
         "libxml2",
     ],
     shared_libs: [
+        "libbase",
         "liblog",
     ],
     cflags: [
diff --git a/media/libmedia/xsd/vts/ValidateMediaProfiles.cpp b/media/libmedia/xsd/vts/ValidateMediaProfiles.cpp
index ff9b060..7729d52 100644
--- a/media/libmedia/xsd/vts/ValidateMediaProfiles.cpp
+++ b/media/libmedia/xsd/vts/ValidateMediaProfiles.cpp
@@ -14,6 +14,10 @@
  * limitations under the License.
  */
 
+#include <string>
+
+#include <android-base/file.h>
+#include <android-base/properties.h>
 #include "utility/ValidateXml.h"
 
 TEST(CheckConfig, mediaProfilesValidation) {
@@ -21,8 +25,12 @@
                    "Verify that the media profiles file "
                    "is valid according to the schema");
 
-    const char* location = "/vendor/etc";
+    std::string mediaSettingsPath = android::base::GetProperty("media.settings.xml", "");
+    if (mediaSettingsPath.empty()) {
+        mediaSettingsPath.assign("/vendor/etc/media_profiles_V1_0.xml");
+    }
 
-    EXPECT_ONE_VALID_XML_MULTIPLE_LOCATIONS("media_profiles_V1_0.xml", {location},
+    EXPECT_ONE_VALID_XML_MULTIPLE_LOCATIONS(android::base::Basename(mediaSettingsPath).c_str(),
+                                            {android::base::Dirname(mediaSettingsPath).c_str()},
                                             "/data/local/tmp/media_profiles.xsd");
 }
diff --git a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
index bf14ec2..83da092 100644
--- a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
@@ -144,6 +144,10 @@
     if (mLooper == NULL) {
         return;
     }
+
+    // Close socket before posting message to RTSPSource message handler.
+    close(mHandler->getARTSPConnection()->getSocket());
+
     sp<AMessage> msg = new AMessage(kWhatDisconnect, this);
 
     sp<AMessage> dummy;
diff --git a/media/libnbaio/Android.bp b/media/libnbaio/Android.bp
index 6345742..04ddcff 100644
--- a/media/libnbaio/Android.bp
+++ b/media/libnbaio/Android.bp
@@ -8,15 +8,14 @@
     header_libs: [
         "libaudioclient_headers",
         "libaudio_system_headers",
-        "libmedia_headers",
     ],
     export_header_lib_headers: [
         "libaudioclient_headers",
-        "libmedia_headers",
     ],
 
     shared_libs: [
         "libaudioutils",
+        "libcutils",
         "liblog",
         "libutils",
     ],
@@ -25,6 +24,11 @@
     ],
 
     export_include_dirs: ["include_mono"],
+
+    cflags: [
+        "-Werror",
+        "-Wall",
+    ],
 }
 
 // libnbaio_mono is the part of libnbaio that is available for vendors to use. Vendor modules can't
@@ -55,18 +59,7 @@
     // ],
     // static_libs: ["libsndfile"],
 
-    shared_libs: [
-        "libaudioutils",
-        "libbinder",
-        "libcutils",
-        "liblog",
-        "libutils",
-    ],
-
-    cflags: [
-        "-Werror",
-        "-Wall",
-    ],
+    header_libs: ["libaudiohal_headers"],
 
     export_include_dirs: ["include"],
 }
diff --git a/media/libnbaio/include_mono/media/nbaio/MonoPipe.h b/media/libnbaio/include_mono/media/nbaio/MonoPipe.h
index c51d0fe..926d84a 100644
--- a/media/libnbaio/include_mono/media/nbaio/MonoPipe.h
+++ b/media/libnbaio/include_mono/media/nbaio/MonoPipe.h
@@ -19,7 +19,7 @@
 
 #include <time.h>
 #include <audio_utils/fifo.h>
-#include <media/SingleStateQueue.h>
+#include <media/nbaio/SingleStateQueue.h>
 #include <media/nbaio/NBAIO.h>
 
 namespace android {
diff --git a/media/libmedia/include/media/SingleStateQueue.h b/media/libnbaio/include_mono/media/nbaio/SingleStateQueue.h
similarity index 100%
rename from media/libmedia/include/media/SingleStateQueue.h
rename to media/libnbaio/include_mono/media/nbaio/SingleStateQueue.h
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index 2f13dc9..f130c9b 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -1635,8 +1635,13 @@
         return BAD_VALUE;
     }
 
+    // Increase moovExtraSize once only irrespective of how many times
+    // setCaptureRate is called.
+    bool containsCaptureFps = mMetaKeys->contains(kMetaKey_CaptureFps);
     mMetaKeys->setFloat(kMetaKey_CaptureFps, captureFps);
-    mMoovExtraSize += sizeof(kMetaKey_CaptureFps) + 4 + 32;
+    if (!containsCaptureFps) {
+        mMoovExtraSize += sizeof(kMetaKey_CaptureFps) + 4 + 32;
+    }
 
     return OK;
 }
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index f579e9d..a6a856c 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -57,7 +57,6 @@
 #include <media/stagefright/OMXClient.h>
 #include <media/stagefright/PersistentSurface.h>
 #include <media/stagefright/SurfaceUtils.h>
-#include <mediautils/BatteryNotifier.h>
 #include <private/android_filesystem_config.h>
 #include <utils/Singleton.h>
 
@@ -166,8 +165,9 @@
     DISALLOW_EVIL_CONSTRUCTORS(ResourceManagerClient);
 };
 
-MediaCodec::ResourceManagerServiceProxy::ResourceManagerServiceProxy(pid_t pid)
-        : mPid(pid) {
+MediaCodec::ResourceManagerServiceProxy::ResourceManagerServiceProxy(
+        pid_t pid, uid_t uid)
+        : mPid(pid), mUid(uid) {
     if (mPid == MediaCodec::kNoPid) {
         mPid = IPCThreadState::self()->getCallingPid();
     }
@@ -204,7 +204,7 @@
     if (mService == NULL) {
         return;
     }
-    mService->addResource(mPid, clientId, client, resources);
+    mService->addResource(mPid, mUid, clientId, client, resources);
 }
 
 void MediaCodec::ResourceManagerServiceProxy::removeResource(int64_t clientId) {
@@ -517,8 +517,6 @@
       mStickyError(OK),
       mSoftRenderer(NULL),
       mAnalyticsItem(NULL),
-      mResourceManagerClient(new ResourceManagerClient(this)),
-      mResourceManagerService(new ResourceManagerServiceProxy(pid)),
       mBatteryStatNotified(false),
       mIsVideo(false),
       mVideoWidth(0),
@@ -537,6 +535,8 @@
     } else {
         mUid = uid;
     }
+    mResourceManagerClient = new ResourceManagerClient(this);
+    mResourceManagerService = new ResourceManagerServiceProxy(pid, mUid);
 
     initAnalyticsItem();
 }
@@ -1977,6 +1977,11 @@
                     if (mIsVideo) {
                         // audio codec is currently ignored.
                         addResource(resourceType, MediaResource::kVideoCodec, 1);
+                        // TODO: track battery on/off by actual queueing/dequeueing
+                        // For now, keep existing behavior and request battery on/off
+                        // together with codec init/uninit. We'll improve the tracking
+                        // later by adding/removing this based on queue/dequeue timing.
+                        addResource(MediaResource::kBattery, MediaResource::kVideoCodec, 1);
                     }
 
                     (new AMessage)->postReply(mReplyID);
@@ -3126,8 +3131,6 @@
     mState = newState;
 
     cancelPendingDequeueOperations();
-
-    updateBatteryStat();
 }
 
 void MediaCodec::returnBuffersToCodec(bool isReclaim) {
@@ -3631,20 +3634,6 @@
     return OK;
 }
 
-void MediaCodec::updateBatteryStat() {
-    if (!mIsVideo) {
-        return;
-    }
-
-    if (mState == CONFIGURED && !mBatteryStatNotified) {
-        BatteryNotifier::getInstance().noteStartVideo(mUid);
-        mBatteryStatNotified = true;
-    } else if (mState == UNINITIALIZED && mBatteryStatNotified) {
-        BatteryNotifier::getInstance().noteStopVideo(mUid);
-        mBatteryStatNotified = false;
-    }
-}
-
 std::string MediaCodec::stateString(State state) {
     const char *rval = NULL;
     char rawbuffer[16]; // room for "%d"
diff --git a/media/libstagefright/MediaMuxer.cpp b/media/libstagefright/MediaMuxer.cpp
index 9ba2add..7ebdb1a 100644
--- a/media/libstagefright/MediaMuxer.cpp
+++ b/media/libstagefright/MediaMuxer.cpp
@@ -96,10 +96,18 @@
 
     sp<MediaAdapter> newTrack = new MediaAdapter(trackMeta);
     status_t result = mWriter->addSource(newTrack);
-    if (result == OK) {
-        return mTrackList.add(newTrack);
+    if (result != OK) {
+        return -1;
     }
-    return -1;
+    float captureFps = -1.0;
+    if (format->findAsFloat("time-lapse-fps", &captureFps)) {
+        ALOGV("addTrack() time-lapse-fps: %f", captureFps);
+        result = mWriter->setCaptureRate(captureFps);
+        if (result != OK) {
+            ALOGW("addTrack() setCaptureRate failed :%d", result);
+        }
+    }
+    return mTrackList.add(newTrack);
 }
 
 status_t MediaMuxer::setOrientationHint(int degrees) {
diff --git a/media/libstagefright/include/media/stagefright/MediaCodec.h b/media/libstagefright/include/media/stagefright/MediaCodec.h
index 89cca63..0218a88 100644
--- a/media/libstagefright/include/media/stagefright/MediaCodec.h
+++ b/media/libstagefright/include/media/stagefright/MediaCodec.h
@@ -283,7 +283,7 @@
     };
 
     struct ResourceManagerServiceProxy : public IBinder::DeathRecipient {
-        ResourceManagerServiceProxy(pid_t pid);
+        ResourceManagerServiceProxy(pid_t pid, uid_t uid);
         ~ResourceManagerServiceProxy();
 
         void init();
@@ -304,6 +304,7 @@
         Mutex mLock;
         sp<IResourceManagerService> mService;
         pid_t mPid;
+        uid_t mUid;
     };
 
     State mState;
@@ -425,7 +426,6 @@
     status_t onSetParameters(const sp<AMessage> &params);
 
     status_t amendOutputFormatWithCodecSpecificData(const sp<MediaCodecBuffer> &buffer);
-    void updateBatteryStat();
     bool isExecuting() const;
 
     uint64_t getGraphicBufferSize();
diff --git a/media/libstagefright/include/media/stagefright/MediaWriter.h b/media/libstagefright/include/media/stagefright/MediaWriter.h
index 2c12a87..972ae1d 100644
--- a/media/libstagefright/include/media/stagefright/MediaWriter.h
+++ b/media/libstagefright/include/media/stagefright/MediaWriter.h
@@ -35,6 +35,10 @@
     virtual status_t start(MetaData *params = NULL) = 0;
     virtual status_t stop() = 0;
     virtual status_t pause() = 0;
+    virtual status_t setCaptureRate(float /* captureFps */) {
+        ALOGW("setCaptureRate unsupported");
+        return ERROR_UNSUPPORTED;
+    }
 
     virtual void setMaxFileSize(int64_t bytes) { mMaxFileSizeLimitBytes = bytes; }
     virtual void setMaxFileDuration(int64_t durationUs) { mMaxFileDurationLimitUs = durationUs; }
diff --git a/media/libstagefright/rtsp/ARTSPConnection.h b/media/libstagefright/rtsp/ARTSPConnection.h
index 8df2676..56b604d 100644
--- a/media/libstagefright/rtsp/ARTSPConnection.h
+++ b/media/libstagefright/rtsp/ARTSPConnection.h
@@ -46,6 +46,8 @@
             const char *url, AString *host, unsigned *port, AString *path,
             AString *user, AString *pass);
 
+    int getSocket() { return mSocket; }
+
 protected:
     virtual ~ARTSPConnection();
     virtual void onMessageReceived(const sp<AMessage> &msg);
diff --git a/media/libstagefright/rtsp/MyHandler.h b/media/libstagefright/rtsp/MyHandler.h
index 48bc8ce..85ffba2 100644
--- a/media/libstagefright/rtsp/MyHandler.h
+++ b/media/libstagefright/rtsp/MyHandler.h
@@ -257,6 +257,10 @@
         msg->post();
     }
 
+    sp<ARTSPConnection> getARTSPConnection() {
+      return mConn;
+    }
+
     static void addRR(const sp<ABuffer> &buf) {
         uint8_t *ptr = buf->data() + buf->size();
         ptr[0] = 0x80 | 0;
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioPort.h b/services/audiopolicy/common/managerdefinitions/include/AudioPort.h
index 2e9ddf4..641cebf 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioPort.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioPort.h
@@ -110,8 +110,8 @@
     // Used to select an audio HAL output stream with a sample format providing the
     // less degradation for a given AudioTrack sample format.
     static bool isBetterFormatMatch(audio_format_t newFormat,
-                                        audio_format_t currentFormat,
-                                        audio_format_t targetFormat);
+                                    audio_format_t currentFormat,
+                                    audio_format_t targetFormat);
     static uint32_t formatDistance(audio_format_t format1,
                                    audio_format_t format2);
     static const uint32_t kFormatDistanceMax = 4;
@@ -143,8 +143,9 @@
     AudioGains mGains; // gain controllers
 
 private:
-    void pickChannelMask(audio_channel_mask_t &channelMask, const ChannelsVector &channelMasks) const;
-    void pickSamplingRate(uint32_t &rate,const SampleRateVector &samplingRates) const;
+    void pickChannelMask(audio_channel_mask_t &channelMask,
+                         const ChannelMaskSet &channelMasks) const;
+    void pickSamplingRate(uint32_t &rate, const SampleRateSet &samplingRates) const;
 
     sp<HwModule> mModule;                 // audio HW module exposing this I/O stream
     String8  mName;
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioProfile.h b/services/audiopolicy/common/managerdefinitions/include/AudioProfile.h
index b588d57..ea56729 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioProfile.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioProfile.h
@@ -16,55 +16,15 @@
 
 #pragma once
 
-#include <vector>
-
+#include <media/AudioContainers.h>
 #include <system/audio.h>
 #include <utils/RefBase.h>
-#include <utils/SortedVector.h>
 #include <utils/String8.h>
 
 #include "policy.h"
 
 namespace android {
 
-typedef SortedVector<uint32_t> SampleRateVector;
-typedef Vector<audio_format_t> FormatVector;
-
-template <typename T>
-bool operator== (const SortedVector<T> &left, const SortedVector<T> &right)
-{
-    if (left.size() != right.size()) {
-        return false;
-    }
-    for (size_t index = 0; index < right.size(); index++) {
-        if (left[index] != right[index]) {
-            return false;
-        }
-    }
-    return true;
-}
-
-template <typename T>
-bool operator!= (const SortedVector<T> &left, const SortedVector<T> &right)
-{
-    return !(left == right);
-}
-
-class ChannelsVector : public SortedVector<audio_channel_mask_t>
-{
-public:
-    ChannelsVector() = default;
-    ChannelsVector(const ChannelsVector&) = default;
-    ChannelsVector(const SortedVector<audio_channel_mask_t>& sv) :
-            SortedVector<audio_channel_mask_t>(sv) {}
-    ChannelsVector& operator=(const ChannelsVector&) = default;
-
-    // Applies audio_channel_mask_out_to_in to all elements and returns the result.
-    ChannelsVector asInMask() const;
-    // Applies audio_channel_mask_in_to_out to all elements and returns the result.
-    ChannelsVector asOutMask() const;
-};
-
 class AudioProfile : public virtual RefBase
 {
 public:
@@ -72,22 +32,22 @@
 
     AudioProfile(audio_format_t format, audio_channel_mask_t channelMasks, uint32_t samplingRate);
     AudioProfile(audio_format_t format,
-                 const ChannelsVector &channelMasks,
-                 const SampleRateVector &samplingRateCollection);
+                 const ChannelMaskSet &channelMasks,
+                 const SampleRateSet &samplingRateCollection);
 
     audio_format_t getFormat() const { return mFormat; }
-    const ChannelsVector &getChannels() const { return mChannelMasks; }
-    const SampleRateVector &getSampleRates() const { return mSamplingRates; }
-    void setChannels(const ChannelsVector &channelMasks);
-    void setSampleRates(const SampleRateVector &sampleRates);
+    const ChannelMaskSet &getChannels() const { return mChannelMasks; }
+    const SampleRateSet &getSampleRates() const { return mSamplingRates; }
+    void setChannels(const ChannelMaskSet &channelMasks);
+    void setSampleRates(const SampleRateSet &sampleRates);
 
     void clear();
     bool isValid() const { return hasValidFormat() && hasValidRates() && hasValidChannels(); }
     bool supportsChannels(audio_channel_mask_t channels) const
     {
-        return mChannelMasks.indexOf(channels) >= 0;
+        return mChannelMasks.count(channels) != 0;
     }
-    bool supportsRate(uint32_t rate) const { return mSamplingRates.indexOf(rate) >= 0; }
+    bool supportsRate(uint32_t rate) const { return mSamplingRates.count(rate) != 0; }
 
     status_t checkExact(uint32_t rate, audio_channel_mask_t channels, audio_format_t format) const;
     status_t checkCompatibleChannelMask(audio_channel_mask_t channelMask,
@@ -98,8 +58,8 @@
                                          uint32_t &updatedSamplingRate) const;
 
     bool hasValidFormat() const { return mFormat != AUDIO_FORMAT_DEFAULT; }
-    bool hasValidRates() const { return !mSamplingRates.isEmpty(); }
-    bool hasValidChannels() const { return !mChannelMasks.isEmpty(); }
+    bool hasValidRates() const { return !mSamplingRates.empty(); }
+    bool hasValidChannels() const { return !mChannelMasks.empty(); }
 
     void setDynamicChannels(bool dynamic) { mIsDynamicChannels = dynamic; }
     bool isDynamicChannels() const { return mIsDynamicChannels; }
@@ -117,8 +77,8 @@
 private:
     String8  mName;
     audio_format_t mFormat;
-    ChannelsVector mChannelMasks;
-    SampleRateVector mSamplingRates;
+    ChannelMaskSet mChannelMasks;
+    SampleRateSet mSamplingRates;
 
     bool mIsDynamicFormat = false;
     bool mIsDynamicChannels = false;
@@ -126,13 +86,16 @@
 };
 
 
-class AudioProfileVector : public Vector<sp<AudioProfile> >
+class AudioProfileVector : public std::vector<sp<AudioProfile> >
 {
 public:
     ssize_t add(const sp<AudioProfile> &profile);
     // This API is intended to be used by the policy manager once retrieving capabilities
     // for a profile with dynamic format, rate and channels attributes
     ssize_t addProfileFromHal(const sp<AudioProfile> &profileToAdd);
+    void appendProfiles(const AudioProfileVector& audioProfiles) {
+        insert(end(), audioProfiles.begin(), audioProfiles.end());
+    }
 
     status_t checkExactProfile(uint32_t samplingRate, audio_channel_mask_t channelMask,
                                audio_format_t format) const;
@@ -169,10 +132,8 @@
 
 private:
     sp<AudioProfile> getProfileFor(audio_format_t format) const;
-    void setSampleRatesFor(const SampleRateVector &sampleRates, audio_format_t format);
-    void setChannelsFor(const ChannelsVector &channelMasks, audio_format_t format);
-
-    static int compareFormats(const sp<AudioProfile> *profile1, const sp<AudioProfile> *profile2);
+    void setSampleRatesFor(const SampleRateSet &sampleRates, audio_format_t format);
+    void setChannelsFor(const ChannelMaskSet &channelMasks, audio_format_t format);
 };
 
 bool operator == (const AudioProfile &left, const AudioProfile &right);
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp
index 68811e9..ff32284 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp
@@ -64,30 +64,19 @@
 {
     // TODO: update this function once audio_port structure reflects the new profile definition.
     // For compatibility reason: flatening the AudioProfile into audio_port structure.
-    SortedVector<audio_format_t> flatenedFormats;
-    SampleRateVector flatenedRates;
-    ChannelsVector flatenedChannels;
+    FormatSet flatenedFormats;
+    SampleRateSet flatenedRates;
+    ChannelMaskSet flatenedChannels;
     for (const auto& profile : mProfiles) {
         if (profile->isValid()) {
             audio_format_t formatToExport = profile->getFormat();
-            const SampleRateVector &ratesToExport = profile->getSampleRates();
-            const ChannelsVector &channelsToExport = profile->getChannels();
+            const SampleRateSet &ratesToExport = profile->getSampleRates();
+            const ChannelMaskSet &channelsToExport = profile->getChannels();
 
-            if (flatenedFormats.indexOf(formatToExport) < 0) {
-                flatenedFormats.add(formatToExport);
-            }
-            for (size_t rateIndex = 0; rateIndex < ratesToExport.size(); rateIndex++) {
-                uint32_t rate = ratesToExport[rateIndex];
-                if (flatenedRates.indexOf(rate) < 0) {
-                    flatenedRates.add(rate);
-                }
-            }
-            for (size_t chanIndex = 0; chanIndex < channelsToExport.size(); chanIndex++) {
-                audio_channel_mask_t channels = channelsToExport[chanIndex];
-                if (flatenedChannels.indexOf(channels) < 0) {
-                    flatenedChannels.add(channels);
-                }
-            }
+            flatenedFormats.insert(formatToExport);
+            flatenedRates.insert(ratesToExport.begin(), ratesToExport.end());
+            flatenedChannels.insert(channelsToExport.begin(), channelsToExport.end());
+
             if (flatenedRates.size() > AUDIO_PORT_MAX_SAMPLING_RATES ||
                     flatenedChannels.size() > AUDIO_PORT_MAX_CHANNEL_MASKS ||
                     flatenedFormats.size() > AUDIO_PORT_MAX_FORMATS) {
@@ -102,23 +91,16 @@
     port->num_sample_rates = flatenedRates.size();
     port->num_channel_masks = flatenedChannels.size();
     port->num_formats = flatenedFormats.size();
-    for (size_t i = 0; i < flatenedRates.size(); i++) {
-        port->sample_rates[i] = flatenedRates[i];
-    }
-    for (size_t i = 0; i < flatenedChannels.size(); i++) {
-        port->channel_masks[i] = flatenedChannels[i];
-    }
-    for (size_t i = 0; i < flatenedFormats.size(); i++) {
-        port->formats[i] = flatenedFormats[i];
-    }
+    std::copy(flatenedRates.begin(), flatenedRates.end(), port->sample_rates);
+    std::copy(flatenedChannels.begin(), flatenedChannels.end(), port->channel_masks);
+    std::copy(flatenedFormats.begin(), flatenedFormats.end(), port->formats);
 
     ALOGV("AudioPort::toAudioPort() num gains %zu", mGains.size());
 
-    uint32_t i;
-    for (i = 0; i < mGains.size() && i < AUDIO_PORT_MAX_GAINS; i++) {
+    port->num_gains = std::min(mGains.size(), (size_t) AUDIO_PORT_MAX_GAINS);
+    for (size_t i = 0; i < port->num_gains; i++) {
         port->gains[i] = mGains[i]->getGain();
     }
-    port->num_gains = i;
 }
 
 void AudioPort::importAudioPort(const sp<AudioPort>& port, bool force __unused)
@@ -162,7 +144,7 @@
     return status;
 }
 
-void AudioPort::pickSamplingRate(uint32_t &pickedRate,const SampleRateVector &samplingRates) const
+void AudioPort::pickSamplingRate(uint32_t &pickedRate,const SampleRateSet &samplingRates) const
 {
     pickedRate = 0;
     // For direct outputs, pick minimum sampling rate: this helps ensuring that the
@@ -170,9 +152,9 @@
     // sink
     if (isDirectOutput()) {
         uint32_t samplingRate = UINT_MAX;
-        for (size_t i = 0; i < samplingRates.size(); i ++) {
-            if ((samplingRates[i] < samplingRate) && (samplingRates[i] > 0)) {
-                samplingRate = samplingRates[i];
+        for (const auto rate : samplingRates) {
+            if ((rate < samplingRate) && (rate > 0)) {
+                samplingRate = rate;
             }
         }
         pickedRate = (samplingRate == UINT_MAX) ? 0 : samplingRate;
@@ -188,16 +170,16 @@
         // TODO: should mSamplingRates[] be ordered in terms of our preference
         // and we return the first (and hence most preferred) match?  This is of concern if
         // we want to choose 96kHz over 192kHz for USB driver stability or resource constraints.
-        for (size_t i = 0; i < samplingRates.size(); i ++) {
-            if ((samplingRates[i] > pickedRate) && (samplingRates[i] <= maxRate)) {
-                pickedRate = samplingRates[i];
+        for (const auto rate : samplingRates) {
+            if ((rate > pickedRate) && (rate <= maxRate)) {
+                pickedRate = rate;
             }
         }
     }
 }
 
 void AudioPort::pickChannelMask(audio_channel_mask_t &pickedChannelMask,
-                                const ChannelsVector &channelMasks) const
+                                const ChannelMaskSet &channelMasks) const
 {
     pickedChannelMask = AUDIO_CHANNEL_NONE;
     // For direct outputs, pick minimum channel count: this helps ensuring that the
@@ -205,15 +187,15 @@
     // sink
     if (isDirectOutput()) {
         uint32_t channelCount = UINT_MAX;
-        for (size_t i = 0; i < channelMasks.size(); i ++) {
+        for (const auto channelMask : channelMasks) {
             uint32_t cnlCount;
             if (useInputChannelMask()) {
-                cnlCount = audio_channel_count_from_in_mask(channelMasks[i]);
+                cnlCount = audio_channel_count_from_in_mask(channelMask);
             } else {
-                cnlCount = audio_channel_count_from_out_mask(channelMasks[i]);
+                cnlCount = audio_channel_count_from_out_mask(channelMask);
             }
             if ((cnlCount < channelCount) && (cnlCount > 0)) {
-                pickedChannelMask = channelMasks[i];
+                pickedChannelMask = channelMask;
                 channelCount = cnlCount;
             }
         }
@@ -226,15 +208,15 @@
         if (mType != AUDIO_PORT_TYPE_MIX) {
             maxCount = UINT_MAX;
         }
-        for (size_t i = 0; i < channelMasks.size(); i ++) {
+        for (const auto channelMask : channelMasks) {
             uint32_t cnlCount;
             if (useInputChannelMask()) {
-                cnlCount = audio_channel_count_from_in_mask(channelMasks[i]);
+                cnlCount = audio_channel_count_from_in_mask(channelMask);
             } else {
-                cnlCount = audio_channel_count_from_out_mask(channelMasks[i]);
+                cnlCount = audio_channel_count_from_out_mask(channelMask);
             }
             if ((cnlCount > channelCount) && (cnlCount <= maxCount)) {
-                pickedChannelMask = channelMasks[i];
+                pickedChannelMask = channelMask;
                 channelCount = cnlCount;
             }
         }
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioProfile.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioProfile.cpp
index a5fe07b..d1082e8 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioProfile.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioProfile.cpp
@@ -21,6 +21,7 @@
 #define LOG_TAG "APM::AudioProfile"
 //#define LOG_NDEBUG 0
 
+#include <media/AudioContainers.h>
 #include <media/AudioResamplerPublic.h>
 #include <utils/Errors.h>
 
@@ -31,28 +32,6 @@
 
 namespace android {
 
-ChannelsVector ChannelsVector::asInMask() const
-{
-    ChannelsVector inMaskVector;
-    for (const auto& channel : *this) {
-        if (audio_channel_mask_out_to_in(channel) != AUDIO_CHANNEL_INVALID) {
-            inMaskVector.add(audio_channel_mask_out_to_in(channel));
-        }
-    }
-    return inMaskVector;
-}
-
-ChannelsVector ChannelsVector::asOutMask() const
-{
-    ChannelsVector outMaskVector;
-    for (const auto& channel : *this) {
-        if (audio_channel_mask_in_to_out(channel) != AUDIO_CHANNEL_INVALID) {
-            outMaskVector.add(audio_channel_mask_in_to_out(channel));
-        }
-    }
-    return outMaskVector;
-}
-
 bool operator == (const AudioProfile &left, const AudioProfile &compareTo)
 {
     return (left.getFormat() == compareTo.getFormat()) &&
@@ -63,7 +42,7 @@
 static AudioProfile* createFullDynamicImpl()
 {
     AudioProfile* dynamicProfile = new AudioProfile(gDynamicFormat,
-            ChannelsVector(), SampleRateVector());
+            ChannelMaskSet(), SampleRateSet());
     dynamicProfile->setDynamicFormat(true);
     dynamicProfile->setDynamicChannels(true);
     dynamicProfile->setDynamicRate(true);
@@ -83,26 +62,26 @@
         mName(String8("")),
         mFormat(format)
 {
-    mChannelMasks.add(channelMasks);
-    mSamplingRates.add(samplingRate);
+    mChannelMasks.insert(channelMasks);
+    mSamplingRates.insert(samplingRate);
 }
 
 AudioProfile::AudioProfile(audio_format_t format,
-                           const ChannelsVector &channelMasks,
-                           const SampleRateVector &samplingRateCollection) :
+                           const ChannelMaskSet &channelMasks,
+                           const SampleRateSet &samplingRateCollection) :
         mName(String8("")),
         mFormat(format),
         mChannelMasks(channelMasks),
         mSamplingRates(samplingRateCollection) {}
 
-void AudioProfile::setChannels(const ChannelsVector &channelMasks)
+void AudioProfile::setChannels(const ChannelMaskSet &channelMasks)
 {
     if (mIsDynamicChannels) {
         mChannelMasks = channelMasks;
     }
 }
 
-void AudioProfile::setSampleRates(const SampleRateVector &sampleRates)
+void AudioProfile::setSampleRates(const SampleRateSet &sampleRates)
 {
     if (mIsDynamicRate) {
         mSamplingRates = sampleRates;
@@ -135,7 +114,7 @@
 {
     ALOG_ASSERT(samplingRate > 0);
 
-    if (mSamplingRates.isEmpty()) {
+    if (mSamplingRates.empty()) {
         updatedSamplingRate = samplingRate;
         return NO_ERROR;
     }
@@ -143,19 +122,18 @@
     // Search for the closest supported sampling rate that is above (preferred)
     // or below (acceptable) the desired sampling rate, within a permitted ratio.
     // The sampling rates are sorted in ascending order.
-    size_t orderOfDesiredRate = mSamplingRates.orderOf(samplingRate);
+    auto desiredRate = mSamplingRates.lower_bound(samplingRate);
 
     // Prefer to down-sample from a higher sampling rate, as we get the desired frequency spectrum.
-    if (orderOfDesiredRate < mSamplingRates.size()) {
-        uint32_t candidate = mSamplingRates[orderOfDesiredRate];
-        if (candidate / AUDIO_RESAMPLER_DOWN_RATIO_MAX <= samplingRate) {
-            updatedSamplingRate = candidate;
+    if (desiredRate != mSamplingRates.end()) {
+        if (*desiredRate / AUDIO_RESAMPLER_DOWN_RATIO_MAX <= samplingRate) {
+            updatedSamplingRate = *desiredRate;
             return NO_ERROR;
         }
     }
     // But if we have to up-sample from a lower sampling rate, that's OK.
-    if (orderOfDesiredRate != 0) {
-        uint32_t candidate = mSamplingRates[orderOfDesiredRate - 1];
+    if (desiredRate != mSamplingRates.begin()) {
+        uint32_t candidate = *(--desiredRate);
         if (candidate * AUDIO_RESAMPLER_UP_RATIO_MAX >= samplingRate) {
             updatedSamplingRate = candidate;
             return NO_ERROR;
@@ -170,7 +148,7 @@
                                                   audio_port_type_t portType,
                                                   audio_port_role_t portRole) const
 {
-    if (mChannelMasks.isEmpty()) {
+    if (mChannelMasks.empty()) {
         updatedChannelMask = channelMask;
         return NO_ERROR;
     }
@@ -179,8 +157,7 @@
             == AUDIO_CHANNEL_REPRESENTATION_INDEX;
     const uint32_t channelCount = audio_channel_count_from_in_mask(channelMask);
     int bestMatch = 0;
-    for (size_t i = 0; i < mChannelMasks.size(); i ++) {
-        audio_channel_mask_t supported = mChannelMasks[i];
+    for (const auto &supported : mChannelMasks) {
         if (supported == channelMask) {
             // Exact matches always taken.
             updatedChannelMask = channelMask;
@@ -270,20 +247,20 @@
     if (FormatConverter::toString(mFormat, formatLiteral)) {
         dst->appendFormat("%*s- format: %s\n", spaces, "", formatLiteral.c_str());
     }
-    if (!mSamplingRates.isEmpty()) {
+    if (!mSamplingRates.empty()) {
         dst->appendFormat("%*s- sampling rates:", spaces, "");
-        for (size_t i = 0; i < mSamplingRates.size(); i++) {
-            dst->appendFormat("%d", mSamplingRates[i]);
-            dst->append(i == (mSamplingRates.size() - 1) ? "" : ", ");
+        for (auto it = mSamplingRates.begin(); it != mSamplingRates.end();) {
+            dst->appendFormat("%d", *it);
+            dst->append(++it == mSamplingRates.end() ? "" : ", ");
         }
         dst->append("\n");
     }
 
-    if (!mChannelMasks.isEmpty()) {
+    if (!mChannelMasks.empty()) {
         dst->appendFormat("%*s- channel masks:", spaces, "");
-        for (size_t i = 0; i < mChannelMasks.size(); i++) {
-            dst->appendFormat("0x%04x", mChannelMasks[i]);
-            dst->append(i == (mChannelMasks.size() - 1) ? "" : ", ");
+        for (auto it = mChannelMasks.begin(); it != mChannelMasks.end();) {
+            dst->appendFormat("0x%04x", *it);
+            dst->append(++it == mChannelMasks.end() ? "" : ", ");
         }
         dst->append("\n");
     }
@@ -291,13 +268,14 @@
 
 ssize_t AudioProfileVector::add(const sp<AudioProfile> &profile)
 {
-    ssize_t index = Vector::add(profile);
+    ssize_t index = size();
+    push_back(profile);
     // we sort from worst to best, so that AUDIO_FORMAT_DEFAULT is always the first entry.
-    // TODO: compareFormats could be a lambda to convert between pointer-to-format to format:
-    // [](const audio_format_t *format1, const audio_format_t *format2) {
-    //     return compareFormats(*format1, *format2);
-    // }
-    sort(compareFormats);
+    std::sort(begin(), end(),
+            [](const sp<AudioProfile> & a, const sp<AudioProfile> & b)
+            {
+                return AudioPort::compareFormats(a->getFormat(), b->getFormat()) < 0;
+            });
     return index;
 }
 
@@ -309,7 +287,7 @@
     }
     if (!profileToAdd->hasValidChannels() && !profileToAdd->hasValidRates()) {
         FormatVector formats;
-        formats.add(profileToAdd->getFormat());
+        formats.push_back(profileToAdd->getFormat());
         setFormats(FormatVector(formats));
         return 0;
     }
@@ -323,7 +301,7 @@
     }
     // Go through the list of profile to avoid duplicates
     for (size_t profileIndex = 0; profileIndex < size(); profileIndex++) {
-        const sp<AudioProfile> &profile = itemAt(profileIndex);
+        const sp<AudioProfile> &profile = at(profileIndex);
         if (profile->isValid() && profile == profileToAdd) {
             // Nothing to do
             return profileIndex;
@@ -337,7 +315,7 @@
                                                audio_channel_mask_t channelMask,
                                                audio_format_t format) const
 {
-    if (isEmpty()) {
+    if (empty()) {
         return NO_ERROR;
     }
 
@@ -355,7 +333,7 @@
                                                     audio_port_type_t portType,
                                                     audio_port_role_t portRole) const
 {
-    if (isEmpty()) {
+    if (empty()) {
         return NO_ERROR;
     }
 
@@ -365,7 +343,7 @@
 
     // iterate from best format to worst format (reverse order)
     for (ssize_t i = size() - 1; i >= 0 ; --i) {
-        const sp<AudioProfile> profile = itemAt(i);
+        const sp<AudioProfile> profile = at(i);
         audio_format_t formatToCompare = profile->getFormat();
         if (formatToCompare == format ||
                 (checkInexact
@@ -391,13 +369,13 @@
 
 void AudioProfileVector::clearProfiles()
 {
-    for (size_t i = size(); i != 0; ) {
-        sp<AudioProfile> profile = itemAt(--i);
-        if (profile->isDynamicFormat() && profile->hasValidFormat()) {
-            removeAt(i);
-            continue;
+    for (auto it = begin(); it != end();) {
+        if ((*it)->isDynamicFormat() && (*it)->hasValidFormat()) {
+            it = erase(it);
+        } else {
+            (*it)->clear();
+            ++it;
         }
-        profile->clear();
     }
 }
 
@@ -448,16 +426,16 @@
         if (inputProfile == nullptr || outputProfile == nullptr) {
             continue;
         }
-        auto channels = intersectFilterAndOrder(inputProfile->getChannels().asOutMask(),
+        auto channels = intersectFilterAndOrder(asOutMask(inputProfile->getChannels()),
                 outputProfile->getChannels(), preferredOutputChannels);
         if (channels.empty()) {
             continue;
         }
         auto sampleRates = preferHigherSamplingRates ?
                 intersectAndOrder(inputProfile->getSampleRates(), outputProfile->getSampleRates(),
-                        std::greater<typename SampleRateVector::value_type>()) :
+                        std::greater<typename SampleRateSet::value_type>()) :
                 intersectAndOrder(inputProfile->getSampleRates(), outputProfile->getSampleRates(),
-                        std::less<typename SampleRateVector::value_type>());
+                        std::less<typename SampleRateSet::value_type>());
         if (sampleRates.empty()) {
             continue;
         }
@@ -473,30 +451,30 @@
 
 sp<AudioProfile> AudioProfileVector::getFirstValidProfile() const
 {
-    for (size_t i = 0; i < size(); i++) {
-        if (itemAt(i)->isValid()) {
-            return itemAt(i);
+    for (const auto &profile : *this) {
+        if (profile->isValid()) {
+            return profile;
         }
     }
-    return 0;
+    return nullptr;
 }
 
 sp<AudioProfile> AudioProfileVector::getFirstValidProfileFor(audio_format_t format) const
 {
-    for (size_t i = 0; i < size(); i++) {
-        if (itemAt(i)->isValid() && itemAt(i)->getFormat() == format) {
-            return itemAt(i);
+    for (const auto &profile : *this) {
+        if (profile->isValid() && profile->getFormat() == format) {
+            return profile;
         }
     }
-    return 0;
+    return nullptr;
 }
 
 FormatVector AudioProfileVector::getSupportedFormats() const
 {
     FormatVector supportedFormats;
-    for (size_t i = 0; i < size(); i++) {
-        if (itemAt(i)->hasValidFormat()) {
-            supportedFormats.add(itemAt(i)->getFormat());
+    for (const auto &profile : *this) {
+        if (profile->hasValidFormat()) {
+            supportedFormats.push_back(profile->getFormat());
         }
     }
     return supportedFormats;
@@ -504,8 +482,7 @@
 
 bool AudioProfileVector::hasDynamicChannelsFor(audio_format_t format) const
 {
-    for (size_t i = 0; i < size(); i++) {
-        sp<AudioProfile> profile = itemAt(i);
+    for (const auto &profile : *this) {
         if (profile->getFormat() == format && profile->isDynamicChannels()) {
             return true;
         }
@@ -515,8 +492,8 @@
 
 bool AudioProfileVector::hasDynamicProfile() const
 {
-    for (size_t i = 0; i < size(); i++) {
-        if (itemAt(i)->isDynamic()) {
+    for (const auto &profile : *this) {
+        if (profile->isDynamic()) {
             return true;
         }
     }
@@ -525,8 +502,7 @@
 
 bool AudioProfileVector::hasDynamicRateFor(audio_format_t format) const
 {
-    for (size_t i = 0; i < size(); i++) {
-        sp<AudioProfile> profile = itemAt(i);
+    for (const auto &profile : *this) {
         if (profile->getFormat() == format && profile->isDynamicRate()) {
             return true;
         }
@@ -541,8 +517,8 @@
     if (dynamicFormatProfile == 0) {
         return;
     }
-    for (size_t i = 0; i < formats.size(); i++) {
-        sp<AudioProfile> profile = new AudioProfile(formats[i],
+    for (const auto &format : formats) {
+        sp<AudioProfile> profile = new AudioProfile(format,
                 dynamicFormatProfile->getChannels(),
                 dynamicFormatProfile->getSampleRates());
         profile->setDynamicFormat(true);
@@ -557,25 +533,24 @@
     dst->appendFormat("%*s- Profiles:\n", spaces, "");
     for (size_t i = 0; i < size(); i++) {
         dst->appendFormat("%*sProfile %zu:", spaces + 4, "", i);
-        itemAt(i)->dump(dst, spaces + 8);
+        at(i)->dump(dst, spaces + 8);
     }
 }
 
 sp<AudioProfile> AudioProfileVector::getProfileFor(audio_format_t format) const
 {
-    for (size_t i = 0; i < size(); i++) {
-        if (itemAt(i)->getFormat() == format) {
-            return itemAt(i);
+    for (const auto &profile : *this) {
+        if (profile->getFormat() == format) {
+            return profile;
         }
     }
-    return 0;
+    return nullptr;
 }
 
 void AudioProfileVector::setSampleRatesFor(
-        const SampleRateVector &sampleRates, audio_format_t format)
+        const SampleRateSet &sampleRates, audio_format_t format)
 {
-    for (size_t i = 0; i < size(); i++) {
-        sp<AudioProfile> profile = itemAt(i);
+    for (const auto &profile : *this) {
         if (profile->getFormat() == format && profile->isDynamicRate()) {
             if (profile->hasValidRates()) {
                 // Need to create a new profile with same format
@@ -591,10 +566,9 @@
     }
 }
 
-void AudioProfileVector::setChannelsFor(const ChannelsVector &channelMasks, audio_format_t format)
+void AudioProfileVector::setChannelsFor(const ChannelMaskSet &channelMasks, audio_format_t format)
 {
-    for (size_t i = 0; i < size(); i++) {
-        sp<AudioProfile> profile = itemAt(i);
+    for (const auto &profile : *this) {
         if (profile->getFormat() == format && profile->isDynamicChannels()) {
             if (profile->hasValidChannels()) {
                 // Need to create a new profile with same format
@@ -610,11 +584,4 @@
     }
 }
 
-// static
-int AudioProfileVector::compareFormats(const sp<AudioProfile> *profile1,
-                                       const sp<AudioProfile> *profile2)
-{
-    return AudioPort::compareFormats((*profile1)->getFormat(), (*profile2)->getFormat());
-}
-
 } // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
index 57564e5..e395caa 100644
--- a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
@@ -47,9 +47,9 @@
      * For now, the workaround to remove AC3 and IEC61937 support on HDMI is to declare
      * something like 'encodedFormats="AUDIO_FORMAT_PCM_16_BIT"' on the HDMI devicePort.
      */
-    if (type == AUDIO_DEVICE_OUT_HDMI && mEncodedFormats.isEmpty()) {
-        mEncodedFormats.add(AUDIO_FORMAT_AC3);
-        mEncodedFormats.add(AUDIO_FORMAT_IEC61937);
+    if (type == AUDIO_DEVICE_OUT_HDMI && mEncodedFormats.empty()) {
+        mEncodedFormats.push_back(AUDIO_FORMAT_AC3);
+        mEncodedFormats.push_back(AUDIO_FORMAT_IEC61937);
     }
 }
 
@@ -96,7 +96,7 @@
     if (!device_has_encoding_capability(type())) {
         return true;
     }
-    if (mEncodedFormats.isEmpty()) {
+    if (mEncodedFormats.empty()) {
         return true;
     }
 
@@ -105,7 +105,7 @@
 
 bool DeviceDescriptor::supportsFormat(audio_format_t format)
 {
-    if (mEncodedFormats.isEmpty()) {
+    if (mEncodedFormats.empty()) {
         return true;
     }
 
diff --git a/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp b/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
index 5f820c2..c699aa7 100644
--- a/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
@@ -406,8 +406,8 @@
             samplingRatesFromString(samplingRates, ","));
 
     profile->setDynamicFormat(profile->getFormat() == gDynamicFormat);
-    profile->setDynamicChannels(profile->getChannels().isEmpty());
-    profile->setDynamicRate(profile->getSampleRates().isEmpty());
+    profile->setDynamicChannels(profile->getChannels().empty());
+    profile->setDynamicRate(profile->getSampleRates().empty());
 
     return profile;
 }
@@ -437,7 +437,7 @@
     if (status != NO_ERROR) {
         return Status::fromStatusT(status);
     }
-    if (profiles.isEmpty()) {
+    if (profiles.empty()) {
         profiles.add(AudioProfile::createFullDynamic());
     }
     mixPort->setAudioProfiles(profiles);
@@ -521,7 +521,7 @@
     if (status != NO_ERROR) {
         return Status::fromStatusT(status);
     }
-    if (profiles.isEmpty()) {
+    if (profiles.empty()) {
         profiles.add(AudioProfile::createFullDynamic());
     }
     deviceDesc->setAudioProfiles(profiles);
diff --git a/services/audiopolicy/enginedefault/src/Engine.cpp b/services/audiopolicy/enginedefault/src/Engine.cpp
index cfb2206..cbc46d5 100644
--- a/services/audiopolicy/enginedefault/src/Engine.cpp
+++ b/services/audiopolicy/enginedefault/src/Engine.cpp
@@ -203,7 +203,8 @@
             // audio_policy_configuration.xml, hearing aid is not there, but it's
             // a primary device
             // FIXME: this is not the right way of solving this problem
-            DeviceVector availPrimaryOutputDevices = primaryOutput->supportedDevices();
+            DeviceVector availPrimaryOutputDevices = availableOutputDevices.getDevicesFromTypeMask(
+                    primaryOutput->supportedDevices().types());
             availPrimaryOutputDevices.add(
                     availableOutputDevices.getDevicesFromTypeMask(AUDIO_DEVICE_OUT_HEARING_AID));
 
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 83ae35e..499fc8a 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -73,6 +73,26 @@
         AUDIO_CHANNEL_OUT_2POINT1POINT2, AUDIO_CHANNEL_OUT_2POINT0POINT2,
         AUDIO_CHANNEL_OUT_5POINT1, AUDIO_CHANNEL_OUT_STEREO }};
 
+template <typename T>
+bool operator== (const SortedVector<T> &left, const SortedVector<T> &right)
+{
+    if (left.size() != right.size()) {
+        return false;
+    }
+    for (size_t index = 0; index < right.size(); index++) {
+        if (left[index] != right[index]) {
+            return false;
+        }
+    }
+    return true;
+}
+
+template <typename T>
+bool operator!= (const SortedVector<T> &left, const SortedVector<T> &right)
+{
+    return !(left == right);
+}
+
 // ----------------------------------------------------------------------------
 // AudioPolicyInterface implementation
 // ----------------------------------------------------------------------------
@@ -1339,13 +1359,13 @@
     // Each IOProfile represents a MixPort from audio_policy_configuration.xml
     for (const auto &inProfile : inputProfiles) {
         if (hwAvSync == ((inProfile->getFlags() & AUDIO_INPUT_FLAG_HW_AV_SYNC) != 0)) {
-            msdProfiles.appendVector(inProfile->getAudioProfiles());
+            msdProfiles.appendProfiles(inProfile->getAudioProfiles());
         }
     }
     AudioProfileVector deviceProfiles;
     for (const auto &outProfile : outputProfiles) {
         if (hwAvSync == ((outProfile->getFlags() & AUDIO_OUTPUT_FLAG_HW_AV_SYNC) != 0)) {
-            deviceProfiles.appendVector(outProfile->getAudioProfiles());
+            deviceProfiles.appendProfiles(outProfile->getAudioProfiles());
         }
     }
     struct audio_config_base bestSinkConfig;
@@ -6084,24 +6104,24 @@
         formatSet.insert(enforcedSurround.begin(), enforcedSurround.end());
     }
     for (const auto& format : formatSet) {
-        formatsPtr->push(format);
+        formatsPtr->push_back(format);
     }
 }
 
-void AudioPolicyManager::modifySurroundChannelMasks(ChannelsVector *channelMasksPtr) {
-    ChannelsVector &channelMasks = *channelMasksPtr;
+void AudioPolicyManager::modifySurroundChannelMasks(ChannelMaskSet *channelMasksPtr) {
+    ChannelMaskSet &channelMasks = *channelMasksPtr;
     audio_policy_forced_cfg_t forceUse = mEngine->getForceUse(
             AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND);
 
     // If NEVER, then remove support for channelMasks > stereo.
     if (forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_NEVER) {
-        for (size_t maskIndex = 0; maskIndex < channelMasks.size(); ) {
-            audio_channel_mask_t channelMask = channelMasks[maskIndex];
+        for (auto it = channelMasks.begin(); it != channelMasks.end();) {
+            audio_channel_mask_t channelMask = *it;
             if (channelMask & ~AUDIO_CHANNEL_OUT_STEREO) {
                 ALOGI("%s: force NEVER, so remove channelMask 0x%08x", __FUNCTION__, channelMask);
-                channelMasks.removeAt(maskIndex);
+                it = channelMasks.erase(it);
             } else {
-                maskIndex++;
+                ++it;
             }
         }
     // If ALWAYS or MANUAL, then make sure we at least support 5.1
@@ -6117,7 +6137,7 @@
         }
         // If not then add 5.1 support.
         if (!supports5dot1) {
-            channelMasks.add(AUDIO_CHANNEL_OUT_5POINT1);
+            channelMasks.insert(AUDIO_CHANNEL_OUT_5POINT1);
             ALOGI("%s: force MANUAL or ALWAYS, so adding channelMask for 5.1 surround", __func__);
         }
     }
@@ -6150,8 +6170,8 @@
     }
 
     for (audio_format_t format : profiles.getSupportedFormats()) {
-        ChannelsVector channelMasks;
-        SampleRateVector samplingRates;
+        ChannelMaskSet channelMasks;
+        SampleRateSet samplingRates;
         AudioParameter requestedParameters;
         requestedParameters.addInt(String8(AudioParameter::keyFormat), format);
 
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index d38176b..02c6171 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -762,7 +762,7 @@
 private:
         // Add or remove AC3 DTS encodings based on user preferences.
         void modifySurroundFormats(const sp<DeviceDescriptor>& devDesc, FormatVector *formatsPtr);
-        void modifySurroundChannelMasks(ChannelsVector *channelMasksPtr);
+        void modifySurroundChannelMasks(ChannelMaskSet *channelMasksPtr);
 
         // Support for Multi-Stream Decoder (MSD) module
         sp<DeviceDescriptor> getMsdAudioInDevice() const;
diff --git a/services/mediaresourcemanager/ResourceManagerService.cpp b/services/mediaresourcemanager/ResourceManagerService.cpp
index 28bfd3f..117a211 100644
--- a/services/mediaresourcemanager/ResourceManagerService.cpp
+++ b/services/mediaresourcemanager/ResourceManagerService.cpp
@@ -21,8 +21,11 @@
 
 #include <binder/IMediaResourceMonitor.h>
 #include <binder/IServiceManager.h>
+#include <cutils/sched_policy.h>
 #include <dirent.h>
 #include <media/stagefright/ProcessInfo.h>
+#include <mediautils/BatteryNotifier.h>
+#include <mediautils/SchedulingPolicyService.h>
 #include <string.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -31,8 +34,7 @@
 
 #include "ResourceManagerService.h"
 #include "ServiceLog.h"
-#include "mediautils/SchedulingPolicyService.h"
-#include <cutils/sched_policy.h>
+
 namespace android {
 
 namespace {
@@ -101,6 +103,7 @@
 }
 
 static ResourceInfo& getResourceInfoForEdit(
+        uid_t uid,
         int64_t clientId,
         const sp<IResourceManagerClient>& client,
         ResourceInfos& infos) {
@@ -110,9 +113,11 @@
         }
     }
     ResourceInfo info;
+    info.uid = uid;
     info.clientId = clientId;
     info.client = client;
     info.cpuBoost = false;
+    info.batteryNoted = false;
     infos.push_back(info);
     return infos.editItemAt(infos.size() - 1);
 }
@@ -204,7 +209,9 @@
       mServiceLog(new ServiceLog()),
       mSupportsMultipleSecureCodecs(true),
       mSupportsSecureWithNonSecureCodec(true),
-      mCpuBoostCount(0) {}
+      mCpuBoostCount(0) {
+    BatteryNotifier::getInstance().noteResetVideo();
+}
 
 ResourceManagerService::~ResourceManagerService() {}
 
@@ -226,6 +233,7 @@
 
 void ResourceManagerService::addResource(
         int pid,
+        int uid,
         int64_t clientId,
         const sp<IResourceManagerClient> client,
         const Vector<MediaResource> &resources) {
@@ -239,7 +247,7 @@
         return;
     }
     ResourceInfos& infos = getResourceInfosForEdit(pid, mMap);
-    ResourceInfo& info = getResourceInfoForEdit(clientId, client, infos);
+    ResourceInfo& info = getResourceInfoForEdit(uid, clientId, client, infos);
     // TODO: do the merge instead of append.
     info.resources.appendVector(resources);
 
@@ -253,6 +261,11 @@
                 ALOGW("couldn't request cpuset boost");
             }
             mCpuBoostCount++;
+        } else if (resources[i].mType == MediaResource::kBattery
+                && resources[i].mSubType == MediaResource::kVideoCodec
+                && !info.batteryNoted) {
+            info.batteryNoted = true;
+            BatteryNotifier::getInstance().noteStartVideo(info.uid);
         }
     }
     if (info.deathNotifier == nullptr) {
@@ -291,6 +304,9 @@
                     requestCpusetBoost(false, this);
                 }
             }
+            if (infos[j].batteryNoted) {
+                BatteryNotifier::getInstance().noteStopVideo(infos[j].uid);
+            }
             IInterface::asBinder(infos[j].client)->unlinkToDeath(infos[j].deathNotifier);
             j = infos.removeAt(j);
             found = true;
diff --git a/services/mediaresourcemanager/ResourceManagerService.h b/services/mediaresourcemanager/ResourceManagerService.h
index 82d2a0b..741ef73 100644
--- a/services/mediaresourcemanager/ResourceManagerService.h
+++ b/services/mediaresourcemanager/ResourceManagerService.h
@@ -35,10 +35,12 @@
 
 struct ResourceInfo {
     int64_t clientId;
+    uid_t uid;
     sp<IResourceManagerClient> client;
     sp<IBinder::DeathRecipient> deathNotifier;
     Vector<MediaResource> resources;
     bool cpuBoost;
+    bool batteryNoted;
 };
 
 typedef Vector<ResourceInfo> ResourceInfos;
@@ -61,6 +63,7 @@
 
     virtual void addResource(
             int pid,
+            int uid,
             int64_t clientId,
             const sp<IResourceManagerClient> client,
             const Vector<MediaResource> &resources);
diff --git a/services/mediaresourcemanager/test/ResourceManagerService_test.cpp b/services/mediaresourcemanager/test/ResourceManagerService_test.cpp
index ed0b0ef..8a3987a 100644
--- a/services/mediaresourcemanager/test/ResourceManagerService_test.cpp
+++ b/services/mediaresourcemanager/test/ResourceManagerService_test.cpp
@@ -86,7 +86,10 @@
 };
 
 static const int kTestPid1 = 30;
+static const int kTestUid1 = 1010;
+
 static const int kTestPid2 = 20;
+static const int kTestUid2 = 1011;
 
 static const int kLowPriorityPid = 40;
 static const int kMidPriorityPid = 25;
@@ -115,8 +118,11 @@
         return true;
     }
 
-    static void expectEqResourceInfo(const ResourceInfo &info, sp<IResourceManagerClient> client,
+    static void expectEqResourceInfo(const ResourceInfo &info,
+            int uid,
+            sp<IResourceManagerClient> client,
             const Vector<MediaResource> &resources) {
+        EXPECT_EQ(uid, info.uid);
         EXPECT_EQ(client, info.client);
         EXPECT_TRUE(isEqualResources(resources, info.resources));
     }
@@ -153,24 +159,24 @@
         // kTestPid1 mTestClient1
         Vector<MediaResource> resources1;
         resources1.push_back(MediaResource(MediaResource::kSecureCodec, 1));
-        mService->addResource(kTestPid1, getId(mTestClient1), mTestClient1, resources1);
+        mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
         resources1.push_back(MediaResource(MediaResource::kGraphicMemory, 200));
         Vector<MediaResource> resources11;
         resources11.push_back(MediaResource(MediaResource::kGraphicMemory, 200));
-        mService->addResource(kTestPid1, getId(mTestClient1), mTestClient1, resources11);
+        mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources11);
 
         // kTestPid2 mTestClient2
         Vector<MediaResource> resources2;
         resources2.push_back(MediaResource(MediaResource::kNonSecureCodec, 1));
         resources2.push_back(MediaResource(MediaResource::kGraphicMemory, 300));
-        mService->addResource(kTestPid2, getId(mTestClient2), mTestClient2, resources2);
+        mService->addResource(kTestPid2, kTestUid2, getId(mTestClient2), mTestClient2, resources2);
 
         // kTestPid2 mTestClient3
         Vector<MediaResource> resources3;
-        mService->addResource(kTestPid2, getId(mTestClient3), mTestClient3, resources3);
+        mService->addResource(kTestPid2, kTestUid2, getId(mTestClient3), mTestClient3, resources3);
         resources3.push_back(MediaResource(MediaResource::kSecureCodec, 1));
         resources3.push_back(MediaResource(MediaResource::kGraphicMemory, 100));
-        mService->addResource(kTestPid2, getId(mTestClient3), mTestClient3, resources3);
+        mService->addResource(kTestPid2, kTestUid2, getId(mTestClient3), mTestClient3, resources3);
 
         const PidResourceInfosMap &map = mService->mMap;
         EXPECT_EQ(2u, map.size());
@@ -178,14 +184,14 @@
         ASSERT_GE(index1, 0);
         const ResourceInfos &infos1 = map[index1];
         EXPECT_EQ(1u, infos1.size());
-        expectEqResourceInfo(infos1[0], mTestClient1, resources1);
+        expectEqResourceInfo(infos1[0], kTestUid1, mTestClient1, resources1);
 
         ssize_t index2 = map.indexOfKey(kTestPid2);
         ASSERT_GE(index2, 0);
         const ResourceInfos &infos2 = map[index2];
         EXPECT_EQ(2u, infos2.size());
-        expectEqResourceInfo(infos2[0], mTestClient2, resources2);
-        expectEqResourceInfo(infos2[1], mTestClient3, resources3);
+        expectEqResourceInfo(infos2[0], kTestUid2, mTestClient2, resources2);
+        expectEqResourceInfo(infos2[1], kTestUid2, mTestClient3, resources3);
     }
 
     void testConfig() {