Merge "NuPlayerRenderer: ignore fractional audio frame." into nyc-dev
diff --git a/cmds/stagefright/muxer.cpp b/cmds/stagefright/muxer.cpp
index 36fa3b5..0a3bdf3 100644
--- a/cmds/stagefright/muxer.cpp
+++ b/cmds/stagefright/muxer.cpp
@@ -43,6 +43,7 @@
     fprintf(stderr, "       -h help\n");
     fprintf(stderr, "       -a use audio\n");
     fprintf(stderr, "       -v use video\n");
+    fprintf(stderr, "       -w mux into WebM container (default is MP4)\n");
     fprintf(stderr, "       -s Time in milli-seconds when the trim should start\n");
     fprintf(stderr, "       -e Time in milli-seconds when the trim should end\n");
     fprintf(stderr, "       -o output file name. Default is /sdcard/muxeroutput.mp4\n");
@@ -60,7 +61,8 @@
         bool enableTrim,
         int trimStartTimeMs,
         int trimEndTimeMs,
-        int rotationDegrees) {
+        int rotationDegrees,
+        MediaMuxer::OutputFormat container = MediaMuxer::OUTPUT_FORMAT_MPEG_4) {
     sp<NuMediaExtractor> extractor = new NuMediaExtractor;
     if (extractor->setDataSource(NULL /* httpService */, path) != OK) {
         fprintf(stderr, "unable to instantiate extractor. %s\n", path);
@@ -80,8 +82,7 @@
         ALOGE("couldn't open file");
         return fd;
     }
-    sp<MediaMuxer> muxer = new MediaMuxer(fd,
-                                          MediaMuxer::OUTPUT_FORMAT_MPEG_4);
+    sp<MediaMuxer> muxer = new MediaMuxer(fd, container);
     close(fd);
 
     size_t trackCount = extractor->countTracks();
@@ -237,9 +238,10 @@
     // When trimStartTimeMs and trimEndTimeMs seems valid, we turn this switch
     // to true.
     bool enableTrim = false;
+    MediaMuxer::OutputFormat container = MediaMuxer::OUTPUT_FORMAT_MPEG_4;
 
     int res;
-    while ((res = getopt(argc, argv, "h?avo:s:e:r:")) >= 0) {
+    while ((res = getopt(argc, argv, "h?avo:s:e:r:w")) >= 0) {
         switch (res) {
             case 'a':
             {
@@ -253,6 +255,12 @@
                 break;
             }
 
+            case 'w':
+            {
+                container = MediaMuxer::OUTPUT_FORMAT_WEBM;
+                break;
+            }
+
             case 'o':
             {
                 outputFileName = optarg;
@@ -318,7 +326,7 @@
     looper->start();
 
     int result = muxing(argv[0], useAudio, useVideo, outputFileName,
-                        enableTrim, trimStartTimeMs, trimEndTimeMs, rotationDegrees);
+                        enableTrim, trimStartTimeMs, trimEndTimeMs, rotationDegrees, container);
 
     looper->stop();
 
diff --git a/drm/drmserver/DrmManagerService.cpp b/drm/drmserver/DrmManagerService.cpp
index 814ffcc..dad599b 100644
--- a/drm/drmserver/DrmManagerService.cpp
+++ b/drm/drmserver/DrmManagerService.cpp
@@ -337,7 +337,7 @@
     return mDrmManager->pread(uniqueId, decryptHandle, buffer, numBytes, offset);
 }
 
-status_t DrmManagerService::dump(int fd, const Vector<String16>& /* args */)
+status_t DrmManagerService::dump(int fd, const Vector<String16>& args)
 {
     const size_t SIZE = 256;
     char buffer[SIZE];
@@ -357,8 +357,12 @@
             }
         }
         if (dumpMem) {
-            dumpMemoryAddresses(fd);
+            result.append("\nDumping memory:\n");
+            std::string s = dumpMemoryAddresses(100 /* limit */);
+            result.append(s.c_str(), s.size());
         }
+#else
+        (void)args;
 #endif
     }
     write(fd, result.string(), result.size());
diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h
index 585ef59..2e6646a 100644
--- a/include/media/AudioSystem.h
+++ b/include/media/AudioSystem.h
@@ -238,6 +238,7 @@
     static status_t getInputForAttr(const audio_attributes_t *attr,
                                     audio_io_handle_t *input,
                                     audio_session_t session,
+                                    pid_t pid,
                                     uid_t uid,
                                     uint32_t samplingRate,
                                     audio_format_t format,
diff --git a/include/media/IAudioFlinger.h b/include/media/IAudioFlinger.h
index 1ade4ba..984bc02 100644
--- a/include/media/IAudioFlinger.h
+++ b/include/media/IAudioFlinger.h
@@ -73,6 +73,7 @@
                                 // reference and will release it when the track is destroyed.
                                 // However on failure, the client is responsible for release.
                                 audio_io_handle_t output,
+                                pid_t pid,
                                 pid_t tid,  // -1 means unused, otherwise must be valid non-0
                                 audio_session_t *sessionId,
                                 int clientUid,
@@ -89,6 +90,7 @@
                                 const String16& callingPackage,
                                 size_t *pFrameCount,
                                 track_flags_t *flags,
+                                pid_t pid,
                                 pid_t tid,  // -1 means unused, otherwise must be valid non-0
                                 int clientUid,
                                 audio_session_t *sessionId,
diff --git a/include/media/IAudioPolicyService.h b/include/media/IAudioPolicyService.h
index 80437dc..0e9e3bc 100644
--- a/include/media/IAudioPolicyService.h
+++ b/include/media/IAudioPolicyService.h
@@ -81,6 +81,7 @@
     virtual status_t  getInputForAttr(const audio_attributes_t *attr,
                               audio_io_handle_t *input,
                               audio_session_t session,
+                              pid_t pid,
                               uid_t uid,
                               uint32_t samplingRate,
                               audio_format_t format,
diff --git a/include/media/MemoryLeakTrackUtil.h b/include/media/MemoryLeakTrackUtil.h
index d2618aa..4c1a60c 100644
--- a/include/media/MemoryLeakTrackUtil.h
+++ b/include/media/MemoryLeakTrackUtil.h
@@ -16,11 +16,16 @@
 #ifndef MEMORY_LEAK_TRACK_UTIL_H
 #define MEMORY_LEAK_TRACK_UTIL_H
 
+#include <iostream>
+
 namespace android {
 /*
- * Dump the memory address of the calling process to the given fd.
+ * Dump the heap memory of the calling process, sorted by total size
+ * (allocation size * number of allocations).
+ *
+ *    limit is the number of unique allocations to return.
  */
-extern void dumpMemoryAddresses(int fd);
+extern std::string dumpMemoryAddresses(size_t limit);
 
 };
 
diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h
index d14bb7b..f4d0acd 100644
--- a/include/media/stagefright/ACodec.h
+++ b/include/media/stagefright/ACodec.h
@@ -250,6 +250,8 @@
     bool mUsingNativeWindow;
     sp<ANativeWindow> mNativeWindow;
     int mNativeWindowUsageBits;
+    android_native_rect_t mLastNativeWindowCrop;
+    int32_t mLastNativeWindowDataSpace;
     sp<AMessage> mConfigFormat;
     sp<AMessage> mInputFormat;
     sp<AMessage> mOutputFormat;
diff --git a/include/media/stagefright/AudioSource.h b/include/media/stagefright/AudioSource.h
index 3074910..8fc410d 100644
--- a/include/media/stagefright/AudioSource.h
+++ b/include/media/stagefright/AudioSource.h
@@ -38,7 +38,9 @@
             const String16 &opPackageName,
             uint32_t sampleRate,
             uint32_t channels,
-            uint32_t outSampleRate = 0);
+            uint32_t outSampleRate = 0,
+            uid_t uid = -1,
+            pid_t pid = -1);
 
     status_t initCheck() const;
 
diff --git a/include/media/stagefright/MetaData.h b/include/media/stagefright/MetaData.h
index 7b43f87..be7e5c1 100644
--- a/include/media/stagefright/MetaData.h
+++ b/include/media/stagefright/MetaData.h
@@ -194,8 +194,7 @@
     kKeyNalLengthSize     = 'nals', // int32_t
 
     // HDR related
-    kKeyMinLuminance     = 'minL', // int32_t, min luminance of the content in cd/m2.
-    kKeyMaxLuminance     = 'maxL', // int32_t, max luminance of the content in cd/m2.
+    kKeyHdrStaticInfo    = 'hdrS', // HDRStaticInfo
 
     // color aspects
     kKeyColorRange       = 'cRng', // int32_t, color range, value defined by ColorAspects.Range
diff --git a/include/media/stagefright/foundation/ABitReader.h b/include/media/stagefright/foundation/ABitReader.h
index c3bf0ff..a30dd2e 100644
--- a/include/media/stagefright/foundation/ABitReader.h
+++ b/include/media/stagefright/foundation/ABitReader.h
@@ -30,23 +30,44 @@
     ABitReader(const uint8_t *data, size_t size);
     virtual ~ABitReader();
 
-    uint32_t getBits(size_t n);
-    void skipBits(size_t n);
+    // Tries to get |n| bits. If not successful, returns |fallback|. Otherwise, returns result.
+    // Reading 0 bits will always succeed and return 0.
+    uint32_t getBitsWithFallback(size_t n, uint32_t fallback);
 
+    // Tries to get |n| bits. If not successful, returns false. Otherwise, stores result in |out|
+    // and returns true. Use !overRead() to determine if this call was successful. Reading 0 bits
+    // will always succeed and write 0 in |out|.
+    bool getBitsGraceful(size_t n, uint32_t *out);
+
+    // Gets |n| bits and returns result. ABORTS if unsuccessful. Reading 0 bits will always
+    // succeed.
+    uint32_t getBits(size_t n);
+
+    // Tries to skip |n| bits. Returns true iff successful. Skipping 0 bits will always succeed.
+    bool skipBits(size_t n);
+
+    // "Puts" |n| bits with the value |x| back virtually into the bit stream. The put-back bits
+    // are not actually written into the data, but are tracked in a separate buffer that can
+    // store at most 32 bits. This is a no-op if the stream has already been over-read.
     void putBits(uint32_t x, size_t n);
 
     size_t numBitsLeft() const;
 
     const uint8_t *data() const;
 
+    // Returns true iff the stream was over-read (e.g. any getBits operation has been unsuccessful
+    // due to overread (and not trying to read >32 bits).)
+    bool overRead() const { return mOverRead; }
+
 protected:
     const uint8_t *mData;
     size_t mSize;
 
     uint32_t mReservoir;  // left-aligned bits
     size_t mNumBitsLeft;
+    bool mOverRead;
 
-    virtual void fillReservoir();
+    virtual bool fillReservoir();
 
     DISALLOW_EVIL_CONSTRUCTORS(ABitReader);
 };
@@ -60,7 +81,7 @@
 private:
     int32_t mNumZeros;
 
-    virtual void fillReservoir();
+    virtual bool fillReservoir();
 
     DISALLOW_EVIL_CONSTRUCTORS(NALBitReader);
 };
diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk
index 63f9ed7..6586f41 100644
--- a/media/libmedia/Android.mk
+++ b/media/libmedia/Android.mk
@@ -81,6 +81,9 @@
 
 LOCAL_WHOLE_STATIC_LIBRARIES := libmedia_helper
 
+# for memory heap analysis
+LOCAL_STATIC_LIBRARIES := libc_malloc_debug_backtrace libc_logging
+
 LOCAL_MODULE:= libmedia
 
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index 2976a5c..d9bb856 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -533,7 +533,8 @@
     status = AudioSystem::getInputForAttr(&mAttributes, &input,
                                         mSessionId,
                                         // FIXME compare to AudioTrack
-                                        IPCThreadState::self()->getCallingUid(),
+                                        mClientPid,
+                                        mClientUid,
                                         mSampleRate, mFormat, mChannelMask,
                                         mFlags, mSelectedDeviceId);
 
@@ -615,6 +616,7 @@
                                                        opPackageName,
                                                        &temp,
                                                        &trackFlags,
+                                                       mClientPid,
                                                        tid,
                                                        mClientUid,
                                                        &mSessionId,
diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp
index bbdf65e..808b3ab 100644
--- a/media/libmedia/AudioSystem.cpp
+++ b/media/libmedia/AudioSystem.cpp
@@ -836,6 +836,7 @@
 status_t AudioSystem::getInputForAttr(const audio_attributes_t *attr,
                                 audio_io_handle_t *input,
                                 audio_session_t session,
+                                pid_t pid,
                                 uid_t uid,
                                 uint32_t samplingRate,
                                 audio_format_t format,
@@ -846,7 +847,8 @@
     const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
     if (aps == 0) return NO_INIT;
     return aps->getInputForAttr(
-            attr, input, session, uid, samplingRate, format, channelMask, flags, selectedDeviceId);
+            attr, input, session, pid, uid,
+            samplingRate, format, channelMask, flags, selectedDeviceId);
 }
 
 status_t AudioSystem::startInput(audio_io_handle_t input,
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index 22a5acd..1963da3 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -1401,6 +1401,7 @@
                                                       &trackFlags,
                                                       mSharedBuffer,
                                                       output,
+                                                      mClientPid,
                                                       tid,
                                                       &mSessionId,
                                                       mClientUid,
@@ -2389,6 +2390,9 @@
                     } else {
                         timestamp.mPosition = (uint32_t)(ets.mPosition[location] - frames);
                     }
+                } else if (location == ExtendedTimestamp::LOCATION_KERNEL) {
+                    ALOGV_IF(mPreviousLocation == ExtendedTimestamp::LOCATION_SERVER,
+                            "getTimestamp() location moved from server to kernel");
                 }
                 mPreviousLocation = location;
             } else {
diff --git a/media/libmedia/IAudioFlinger.cpp b/media/libmedia/IAudioFlinger.cpp
index aa75188..92e65e4 100644
--- a/media/libmedia/IAudioFlinger.cpp
+++ b/media/libmedia/IAudioFlinger.cpp
@@ -104,6 +104,7 @@
                                 track_flags_t *flags,
                                 const sp<IMemory>& sharedBuffer,
                                 audio_io_handle_t output,
+                                pid_t pid,
                                 pid_t tid,
                                 audio_session_t *sessionId,
                                 int clientUid,
@@ -128,6 +129,7 @@
             data.writeInt32(false);
         }
         data.writeInt32((int32_t) output);
+        data.writeInt32((int32_t) pid);
         data.writeInt32((int32_t) tid);
         audio_session_t lSessionId = AUDIO_SESSION_ALLOCATE;
         if (sessionId != NULL) {
@@ -179,6 +181,7 @@
                                 const String16& opPackageName,
                                 size_t *pFrameCount,
                                 track_flags_t *flags,
+                                pid_t pid,
                                 pid_t tid,
                                 int clientUid,
                                 audio_session_t *sessionId,
@@ -199,6 +202,7 @@
         data.writeInt64(frameCount);
         track_flags_t lFlags = flags != NULL ? *flags : (track_flags_t) TRACK_DEFAULT;
         data.writeInt32(lFlags);
+        data.writeInt32((int32_t) pid);
         data.writeInt32((int32_t) tid);
         data.writeInt32((int32_t) clientUid);
         audio_session_t lSessionId = AUDIO_SESSION_ALLOCATE;
@@ -950,6 +954,7 @@
                 buffer = interface_cast<IMemory>(data.readStrongBinder());
             }
             audio_io_handle_t output = (audio_io_handle_t) data.readInt32();
+            pid_t pid = (pid_t) data.readInt32();
             pid_t tid = (pid_t) data.readInt32();
             audio_session_t sessionId = (audio_session_t) data.readInt32();
             int clientUid = data.readInt32();
@@ -962,7 +967,7 @@
             } else {
                 track = createTrack(
                         (audio_stream_type_t) streamType, sampleRate, format,
-                        channelMask, &frameCount, &flags, buffer, output, tid,
+                        channelMask, &frameCount, &flags, buffer, output, pid, tid,
                         &sessionId, clientUid, &status);
                 LOG_ALWAYS_FATAL_IF((track != 0) != (status == NO_ERROR));
             }
@@ -982,6 +987,7 @@
             const String16& opPackageName = data.readString16();
             size_t frameCount = data.readInt64();
             track_flags_t flags = (track_flags_t) data.readInt32();
+            pid_t pid = (pid_t) data.readInt32();
             pid_t tid = (pid_t) data.readInt32();
             int clientUid = data.readInt32();
             audio_session_t sessionId = (audio_session_t) data.readInt32();
@@ -990,8 +996,9 @@
             sp<IMemory> buffers;
             status_t status = NO_ERROR;
             sp<IAudioRecord> record = openRecord(input,
-                    sampleRate, format, channelMask, opPackageName, &frameCount, &flags, tid,
-                    clientUid, &sessionId, &notificationFrames, cblk, buffers, &status);
+                    sampleRate, format, channelMask, opPackageName, &frameCount, &flags,
+                    pid, tid, clientUid, &sessionId, &notificationFrames, cblk, buffers,
+                    &status);
             LOG_ALWAYS_FATAL_IF((record != 0) != (status == NO_ERROR));
             reply->writeInt64(frameCount);
             reply->writeInt32(flags);
diff --git a/media/libmedia/IAudioPolicyService.cpp b/media/libmedia/IAudioPolicyService.cpp
index 4ea67da..6405d6d 100644
--- a/media/libmedia/IAudioPolicyService.cpp
+++ b/media/libmedia/IAudioPolicyService.cpp
@@ -280,6 +280,7 @@
     virtual status_t getInputForAttr(const audio_attributes_t *attr,
                                      audio_io_handle_t *input,
                                      audio_session_t session,
+                                     pid_t pid,
                                      uid_t uid,
                                      uint32_t samplingRate,
                                      audio_format_t format,
@@ -299,6 +300,7 @@
         }
         data.write(attr, sizeof(audio_attributes_t));
         data.writeInt32(session);
+        data.writeInt32(pid);
         data.writeInt32(uid);
         data.writeInt32(samplingRate);
         data.writeInt32(static_cast <uint32_t>(format));
@@ -959,6 +961,7 @@
             audio_attributes_t attr;
             data.read(&attr, sizeof(audio_attributes_t));
             audio_session_t session = (audio_session_t)data.readInt32();
+            pid_t pid = (pid_t)data.readInt32();
             uid_t uid = (uid_t)data.readInt32();
             uint32_t samplingRate = data.readInt32();
             audio_format_t format = (audio_format_t) data.readInt32();
@@ -966,7 +969,7 @@
             audio_input_flags_t flags = (audio_input_flags_t) data.readInt32();
             audio_port_handle_t selectedDeviceId = (audio_port_handle_t) data.readInt32();
             audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
-            status_t status = getInputForAttr(&attr, &input, session, uid,
+            status_t status = getInputForAttr(&attr, &input, session, pid, uid,
                                               samplingRate, format, channelMask,
                                               flags, selectedDeviceId);
             reply->writeInt32(status);
diff --git a/media/libmedia/MemoryLeakTrackUtil.cpp b/media/libmedia/MemoryLeakTrackUtil.cpp
index 554dbae..18f5f25 100644
--- a/media/libmedia/MemoryLeakTrackUtil.cpp
+++ b/media/libmedia/MemoryLeakTrackUtil.cpp
@@ -14,166 +14,84 @@
  * limitations under the License.
  */
 
-#include <media/MemoryLeakTrackUtil.h>
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <unistd.h>
+//#define LOG_NDEBUG 0
+#define LOG_TAG "MemoryLeackTrackUtil"
+#include <utils/Log.h>
+
+#include "media/MemoryLeakTrackUtil.h"
+#include <sstream>
 
 /*
- * The code here originally resided in MediaPlayerService.cpp and was
- * shamelessly copied over to support memory leak tracking from
- * multiple places.
+ * The code here originally resided in MediaPlayerService.cpp
  */
-namespace android {
 
+// Figure out the abi based on defined macros.
 #if defined(__arm__)
+#define ABI_STRING "arm"
+#elif defined(__aarch64__)
+#define ABI_STRING "arm64"
+#elif defined(__mips__) && !defined(__LP64__)
+#define ABI_STRING "mips"
+#elif defined(__mips__) && defined(__LP64__)
+#define ABI_STRING "mips64"
+#elif defined(__i386__)
+#define ABI_STRING "x86"
+#elif defined(__x86_64__)
+#define ABI_STRING "x86_64"
+#else
+#error "Unsupported ABI"
+#endif
+
+extern std::string backtrace_string(const uintptr_t* frames, size_t frame_count);
+
+namespace android {
 
 extern "C" void get_malloc_leak_info(uint8_t** info, size_t* overallSize,
         size_t* infoSize, size_t* totalMemory, size_t* backtraceSize);
 
 extern "C" void free_malloc_leak_info(uint8_t* info);
 
-// Use the String-class below instead of String8 to allocate all memory
-// beforehand and not reenter the heap while we are examining it...
-struct MyString8 {
-    static const size_t MAX_SIZE = 256 * 1024;
-
-    MyString8()
-        : mPtr((char *)malloc(MAX_SIZE)) {
-        *mPtr = '\0';
-    }
-
-    ~MyString8() {
-        free(mPtr);
-    }
-
-    void append(const char *s) {
-        strncat(mPtr, s, MAX_SIZE - size() - 1);
-    }
-
-    const char *string() const {
-        return mPtr;
-    }
-
-    size_t size() const {
-        return strlen(mPtr);
-    }
-
-    void clear() {
-        *mPtr = '\0';
-    }
-
-private:
-    char *mPtr;
-
-    MyString8(const MyString8 &);
-    MyString8 &operator=(const MyString8 &);
-};
-
-void dumpMemoryAddresses(int fd)
+std::string dumpMemoryAddresses(size_t limit)
 {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    MyString8 result;
-
-    typedef struct {
-        size_t size;
-        size_t dups;
-        intptr_t * backtrace;
-    } AllocEntry;
-
-    uint8_t *info = NULL;
-    size_t overallSize = 0;
-    size_t infoSize = 0;
-    size_t totalMemory = 0;
-    size_t backtraceSize = 0;
-
+    uint8_t *info;
+    size_t overallSize;
+    size_t infoSize;
+    size_t totalMemory;
+    size_t backtraceSize;
     get_malloc_leak_info(&info, &overallSize, &infoSize, &totalMemory, &backtraceSize);
-    if (info) {
-        uint8_t *ptr = info;
-        size_t count = overallSize / infoSize;
 
-        snprintf(buffer, SIZE, " Allocation count %i\n", count);
-        result.append(buffer);
-        snprintf(buffer, SIZE, " Total memory %i\n", totalMemory);
-        result.append(buffer);
-
-        AllocEntry * entries = new AllocEntry[count];
-
-        for (size_t i = 0; i < count; i++) {
-            // Each entry should be size_t, size_t, intptr_t[backtraceSize]
-            AllocEntry *e = &entries[i];
-
-            e->size = *reinterpret_cast<size_t *>(ptr);
-            ptr += sizeof(size_t);
-
-            e->dups = *reinterpret_cast<size_t *>(ptr);
-            ptr += sizeof(size_t);
-
-            e->backtrace = reinterpret_cast<intptr_t *>(ptr);
-            ptr += sizeof(intptr_t) * backtraceSize;
-        }
-
-        // Now we need to sort the entries.  They come sorted by size but
-        // not by stack trace which causes problems using diff.
-        bool moved;
-        do {
-            moved = false;
-            for (size_t i = 0; i < (count - 1); i++) {
-                AllocEntry *e1 = &entries[i];
-                AllocEntry *e2 = &entries[i+1];
-
-                bool swap = e1->size < e2->size;
-                if (e1->size == e2->size) {
-                    for(size_t j = 0; j < backtraceSize; j++) {
-                        if (e1->backtrace[j] == e2->backtrace[j]) {
-                            continue;
-                        }
-                        swap = e1->backtrace[j] < e2->backtrace[j];
-                        break;
-                    }
-                }
-                if (swap) {
-                    AllocEntry t = entries[i];
-                    entries[i] = entries[i+1];
-                    entries[i+1] = t;
-                    moved = true;
-                }
-            }
-        } while (moved);
-
-        write(fd, result.string(), result.size());
-        result.clear();
-
-        for (size_t i = 0; i < count; i++) {
-            AllocEntry *e = &entries[i];
-
-            snprintf(buffer, SIZE, "size %8i, dup %4i, ", e->size, e->dups);
-            result.append(buffer);
-            for (size_t ct = 0; (ct < backtraceSize) && e->backtrace[ct]; ct++) {
-                if (ct) {
-                    result.append(", ");
-                }
-                snprintf(buffer, SIZE, "0x%08x", e->backtrace[ct]);
-                result.append(buffer);
-            }
-            result.append("\n");
-
-            write(fd, result.string(), result.size());
-            result.clear();
-        }
-
-        delete[] entries;
-        free_malloc_leak_info(info);
+    size_t count;
+    if (info == nullptr || overallSize == 0 || infoSize == 0
+            || (count = overallSize / infoSize) == 0) {
+        ALOGD("no malloc info, libc.debug.malloc.program property should be set");
+        return std::string();
     }
+
+    std::ostringstream oss;
+    oss << totalMemory << " bytes in " << count << " allocations\n";
+    oss << "  ABI: '" ABI_STRING "'" << "\n\n";
+    if (count > limit) count = limit;
+
+    // The memory is sorted based on total size which is useful for finding
+    // worst memory offenders. For diffs, sometimes it is preferable to sort
+    // based on the backtrace.
+    for (size_t i = 0; i < count; i++) {
+        struct AllocEntry {
+            size_t size;  // bit 31 is set if this is zygote allocated memory
+            size_t allocations;
+            uintptr_t backtrace[];
+        };
+
+        const AllocEntry * const e = (AllocEntry *)(info + i * infoSize);
+
+        oss << (e->size * e->allocations)
+                << " bytes ( " << e->size << " bytes * " << e->allocations << " allocations )\n";
+        oss << backtrace_string(e->backtrace, backtraceSize) << "\n";
+    }
+    oss << "\n";
+    free_malloc_leak_info(info);
+    return oss.str();
 }
 
-#else
-// Does nothing
-void dumpMemoryAddresses(int fd __unused) {}
-
-#endif
 }  // namespace android
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index f0190c4..acba6d7 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -536,7 +536,9 @@
             }
         }
         if (dumpMem) {
-            dumpMemoryAddresses(fd);
+            result.append("\nDumping memory:\n");
+            std::string s = dumpMemoryAddresses(100 /* limit */);
+            result.append(s.c_str(), s.size());
         }
         if (unreachableMemory) {
             result.append("\nDumping unreachable memory:\n");
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index 6114af8..97ba76b 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -934,7 +934,9 @@
                 mOpPackageName,
                 sourceSampleRate,
                 mAudioChannels,
-                mSampleRate);
+                mSampleRate,
+                mClientUid,
+                mClientPid);
 
     status_t err = audioSource->initCheck();
 
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index 87d64cd..9f63027 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -2194,11 +2194,6 @@
                 mPausedForBuffering = true;
                 onPause();
             }
-            // fall-thru
-        }
-
-        case Source::kWhatBufferingStart:
-        {
             notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_START, 0);
             break;
         }
@@ -2216,11 +2211,6 @@
                     onResume();
                 }
             }
-            // fall-thru
-        }
-
-        case Source::kWhatBufferingEnd:
-        {
             notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_END, 0);
             break;
         }
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerSource.h b/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
index fba4540..0176eafa 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
@@ -46,8 +46,6 @@
         kWhatFlagsChanged,
         kWhatVideoSizeChanged,
         kWhatBufferingUpdate,
-        kWhatBufferingStart,
-        kWhatBufferingEnd,
         kWhatPauseOnBufferingStart,
         kWhatResumeOnBufferingEnd,
         kWhatCacheStats,
diff --git a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
index ba40876..1b7dff5 100644
--- a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
@@ -778,7 +778,7 @@
         mBuffering = true;
 
         sp<AMessage> notify = dupNotify();
-        notify->setInt32("what", kWhatBufferingStart);
+        notify->setInt32("what", kWhatPauseOnBufferingStart);
         notify->post();
     }
 }
@@ -794,7 +794,7 @@
         mBuffering = false;
 
         sp<AMessage> notify = dupNotify();
-        notify->setInt32("what", kWhatBufferingEnd);
+        notify->setInt32("what", kWhatResumeOnBufferingEnd);
         notify->post();
     }
 
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 99996ed..bb4497b 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -498,6 +498,7 @@
       mNode(0),
       mUsingNativeWindow(false),
       mNativeWindowUsageBits(0),
+      mLastNativeWindowDataSpace(HAL_DATASPACE_UNKNOWN),
       mIsVideo(false),
       mIsEncoder(false),
       mFatalError(false),
@@ -540,6 +541,8 @@
     mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
     mInputEOSResult = OK;
 
+    memset(&mLastNativeWindowCrop, 0, sizeof(mLastNativeWindowCrop));
+
     changeState(mUninitializedState);
 }
 
@@ -973,6 +976,9 @@
     usage |= kVideoGrallocUsage;
     *finalUsage = usage;
 
+    memset(&mLastNativeWindowCrop, 0, sizeof(mLastNativeWindowCrop));
+    mLastNativeWindowDataSpace = HAL_DATASPACE_UNKNOWN;
+
     ALOGV("gralloc usage: %#x(OMX) => %#x(ACodec)", omxUsage, usage);
     return setNativeWindowSizeFormatAndUsage(
             nativeWindow,
@@ -5999,6 +6005,10 @@
                 }
                 mCodec->addKeyFormatChangesToRenderBufferNotification(reply);
                 mCodec->sendFormatChange();
+            } else if (rangeLength > 0 && mCodec->mNativeWindow != NULL) {
+                // If potentially rendering onto a surface, always save key format data (crop &
+                // data space) so that we can set it if and once the buffer is rendered.
+                mCodec->addKeyFormatChangesToRenderBufferNotification(reply);
             }
 
             if (mCodec->usingMetadataOnEncoderOutput()) {
@@ -6099,15 +6109,19 @@
     }
 
     android_native_rect_t crop;
-    if (msg->findRect("crop", &crop.left, &crop.top, &crop.right, &crop.bottom)) {
+    if (msg->findRect("crop", &crop.left, &crop.top, &crop.right, &crop.bottom)
+            && memcmp(&crop, &mCodec->mLastNativeWindowCrop, sizeof(crop)) != 0) {
+        mCodec->mLastNativeWindowCrop = crop;
         status_t err = native_window_set_crop(mCodec->mNativeWindow.get(), &crop);
         ALOGW_IF(err != NO_ERROR, "failed to set crop: %d", err);
     }
 
     int32_t dataSpace;
-    if (msg->findInt32("dataspace", &dataSpace)) {
+    if (msg->findInt32("dataspace", &dataSpace)
+            && dataSpace != mCodec->mLastNativeWindowDataSpace) {
         status_t err = native_window_set_buffers_data_space(
                 mCodec->mNativeWindow.get(), (android_dataspace)dataSpace);
+        mCodec->mLastNativeWindowDataSpace = dataSpace;
         ALOGW_IF(err != NO_ERROR, "failed to set dataspace: %d", err);
     }
 
diff --git a/media/libstagefright/AudioSource.cpp b/media/libstagefright/AudioSource.cpp
index c8b61ca..790c6da 100644
--- a/media/libstagefright/AudioSource.cpp
+++ b/media/libstagefright/AudioSource.cpp
@@ -51,7 +51,8 @@
 
 AudioSource::AudioSource(
         audio_source_t inputSource, const String16 &opPackageName,
-        uint32_t sampleRate, uint32_t channelCount, uint32_t outSampleRate)
+        uint32_t sampleRate, uint32_t channelCount, uint32_t outSampleRate,
+        uid_t uid, pid_t pid)
     : mStarted(false),
       mSampleRate(sampleRate),
       mOutSampleRate(outSampleRate > 0 ? outSampleRate : sampleRate),
@@ -91,7 +92,12 @@
                     (size_t) (bufCount * frameCount),
                     AudioRecordCallbackFunction,
                     this,
-                    frameCount /*notificationFrames*/);
+                    frameCount /*notificationFrames*/,
+                    AUDIO_SESSION_ALLOCATE,
+                    AudioRecord::TRANSFER_DEFAULT,
+                    AUDIO_INPUT_FLAG_NONE,
+                    uid,
+                    pid);
         mInitCheck = mRecord->initCheck();
         if (mInitCheck != OK) {
             mRecord.clear();
diff --git a/media/libstagefright/HevcUtils.cpp b/media/libstagefright/HevcUtils.cpp
index 087c903..718710a 100644
--- a/media/libstagefright/HevcUtils.cpp
+++ b/media/libstagefright/HevcUtils.cpp
@@ -18,6 +18,7 @@
 #define LOG_TAG "HevcUtils"
 
 #include <cstring>
+#include <utility>
 
 #include "include/HevcUtils.h"
 #include "include/avc_utils.h"
@@ -39,7 +40,8 @@
     kHevcNalUnitTypeSuffixSei,
 };
 
-HevcParameterSets::HevcParameterSets() {
+HevcParameterSets::HevcParameterSets()
+    : mInfo(kInfoNone) {
 }
 
 status_t HevcParameterSets::addNalUnit(const uint8_t* data, size_t size) {
@@ -149,17 +151,21 @@
     // Skip reserved
     reader.skipBits(16);
 
-    mParams.add(kGeneralProfileSpace, reader.getBits(2));
-    mParams.add(kGeneralTierFlag, reader.getBits(1));
-    mParams.add(kGeneralProfileIdc, reader.getBits(5));
-    mParams.add(kGeneralProfileCompatibilityFlags, reader.getBits(32));
-    mParams.add(
-            kGeneralConstraintIndicatorFlags,
-            ((uint64_t)reader.getBits(16) << 32) | reader.getBits(32));
-    mParams.add(kGeneralLevelIdc, reader.getBits(8));
-    // 96 bits total for general profile.
+    if (reader.atLeastNumBitsLeft(96)) {
+        mParams.add(kGeneralProfileSpace, reader.getBits(2));
+        mParams.add(kGeneralTierFlag, reader.getBits(1));
+        mParams.add(kGeneralProfileIdc, reader.getBits(5));
+        mParams.add(kGeneralProfileCompatibilityFlags, reader.getBits(32));
+        mParams.add(
+                kGeneralConstraintIndicatorFlags,
+                ((uint64_t)reader.getBits(16) << 32) | reader.getBits(32));
+        mParams.add(kGeneralLevelIdc, reader.getBits(8));
+        // 96 bits total for general profile.
+    } else {
+        reader.skipBits(96);
+    }
 
-    return OK;
+    return reader.overRead() ? ERROR_MALFORMED : OK;
 }
 
 status_t HevcParameterSets::parseSps(const uint8_t* data, size_t size) {
@@ -167,7 +173,7 @@
     NALBitReader reader(data, size);
     // Skip sps_video_parameter_set_id
     reader.skipBits(4);
-    uint8_t maxSubLayersMinus1 = reader.getBits(3);
+    uint8_t maxSubLayersMinus1 = reader.getBitsWithFallback(3, 0);
     // Skip sps_temporal_id_nesting_flag;
     reader.skipBits(1);
     // Skip general profile
@@ -176,8 +182,8 @@
         bool subLayerProfilePresentFlag[8];
         bool subLayerLevelPresentFlag[8];
         for (int i = 0; i < maxSubLayersMinus1; ++i) {
-            subLayerProfilePresentFlag[i] = reader.getBits(1);
-            subLayerLevelPresentFlag[i] = reader.getBits(1);
+            subLayerProfilePresentFlag[i] = reader.getBitsWithFallback(1, 0);
+            subLayerLevelPresentFlag[i] = reader.getBitsWithFallback(1, 0);
         }
         // Skip reserved
         reader.skipBits(2 * (8 - maxSubLayersMinus1));
@@ -193,31 +199,152 @@
         }
     }
     // Skip sps_seq_parameter_set_id
-    parseUE(&reader);
-    uint8_t chromaFormatIdc = parseUE(&reader);
+    skipUE(&reader);
+    uint8_t chromaFormatIdc = parseUEWithFallback(&reader, 0);
     mParams.add(kChromaFormatIdc, chromaFormatIdc);
     if (chromaFormatIdc == 3) {
         // Skip separate_colour_plane_flag
         reader.skipBits(1);
     }
     // Skip pic_width_in_luma_samples
-    parseUE(&reader);
+    skipUE(&reader);
     // Skip pic_height_in_luma_samples
-    parseUE(&reader);
-    if (reader.getBits(1) /* i.e. conformance_window_flag */) {
+    skipUE(&reader);
+    if (reader.getBitsWithFallback(1, 0) /* i.e. conformance_window_flag */) {
         // Skip conf_win_left_offset
-        parseUE(&reader);
+        skipUE(&reader);
         // Skip conf_win_right_offset
-        parseUE(&reader);
+        skipUE(&reader);
         // Skip conf_win_top_offset
-        parseUE(&reader);
+        skipUE(&reader);
         // Skip conf_win_bottom_offset
-        parseUE(&reader);
+        skipUE(&reader);
     }
-    mParams.add(kBitDepthLumaMinus8, parseUE(&reader));
-    mParams.add(kBitDepthChromaMinus8, parseUE(&reader));
+    mParams.add(kBitDepthLumaMinus8, parseUEWithFallback(&reader, 0));
+    mParams.add(kBitDepthChromaMinus8, parseUEWithFallback(&reader, 0));
 
-    return OK;
+    // log2_max_pic_order_cnt_lsb_minus4
+    size_t log2MaxPicOrderCntLsb = parseUEWithFallback(&reader, 0) + (size_t)4;
+    bool spsSubLayerOrderingInfoPresentFlag = reader.getBitsWithFallback(1, 0);
+    for (uint32_t i = spsSubLayerOrderingInfoPresentFlag ? 0 : maxSubLayersMinus1;
+            i <= maxSubLayersMinus1; ++i) {
+        skipUE(&reader); // sps_max_dec_pic_buffering_minus1[i]
+        skipUE(&reader); // sps_max_num_reorder_pics[i]
+        skipUE(&reader); // sps_max_latency_increase_plus1[i]
+    }
+
+    skipUE(&reader); // log2_min_luma_coding_block_size_minus3
+    skipUE(&reader); // log2_diff_max_min_luma_coding_block_size
+    skipUE(&reader); // log2_min_luma_transform_block_size_minus2
+    skipUE(&reader); // log2_diff_max_min_luma_transform_block_size
+    skipUE(&reader); // max_transform_hierarchy_depth_inter
+    skipUE(&reader); // max_transform_hierarchy_depth_intra
+    if (reader.getBitsWithFallback(1, 0)) { // scaling_list_enabled_flag u(1)
+        // scaling_list_data
+        if (reader.getBitsWithFallback(1, 0)) { // sps_scaling_list_data_present_flag
+            for (uint32_t sizeId = 0; sizeId < 4; ++sizeId) {
+                for (uint32_t matrixId = 0; matrixId < 6; matrixId += (sizeId == 3) ? 3 : 1) {
+                    if (!reader.getBitsWithFallback(1, 1)) {
+                        // scaling_list_pred_mode_flag[sizeId][matrixId]
+                        skipUE(&reader); // scaling_list_pred_matrix_id_delta[sizeId][matrixId]
+                    } else {
+                        uint32_t coefNum = std::min(64, (1 << (4 + (sizeId << 1))));
+                        if (sizeId > 1) {
+                            skipSE(&reader); // scaling_list_dc_coef_minus8[sizeId − 2][matrixId]
+                        }
+                        for (uint32_t i = 0; i < coefNum; ++i) {
+                            skipSE(&reader); // scaling_list_delta_coef
+                        }
+                    }
+                }
+            }
+        }
+    }
+    reader.skipBits(1); // amp_enabled_flag
+    reader.skipBits(1); // sample_adaptive_offset_enabled_flag u(1)
+    if (reader.getBitsWithFallback(1, 0)) { // pcm_enabled_flag
+        reader.skipBits(4); // pcm_sample_bit_depth_luma_minus1
+        reader.skipBits(4); // pcm_sample_bit_depth_chroma_minus1 u(4)
+        skipUE(&reader); // log2_min_pcm_luma_coding_block_size_minus3
+        skipUE(&reader); // log2_diff_max_min_pcm_luma_coding_block_size
+        reader.skipBits(1); // pcm_loop_filter_disabled_flag
+    }
+    uint32_t numShortTermRefPicSets = parseUEWithFallback(&reader, 0);
+    uint32_t numPics = 0;
+    for (uint32_t i = 0; i < numShortTermRefPicSets; ++i) {
+        // st_ref_pic_set(i)
+        if (i != 0 && reader.getBitsWithFallback(1, 0)) { // inter_ref_pic_set_prediction_flag
+            reader.skipBits(1); // delta_rps_sign
+            skipUE(&reader); // abs_delta_rps_minus1
+            uint32_t nextNumPics = 0;
+            for (uint32_t j = 0; j <= numPics; ++j) {
+                if (reader.getBitsWithFallback(1, 0) // used_by_curr_pic_flag[j]
+                        || reader.getBitsWithFallback(1, 0)) { // use_delta_flag[j]
+                    ++nextNumPics;
+                }
+            }
+            numPics = nextNumPics;
+        } else {
+            uint32_t numNegativePics = parseUEWithFallback(&reader, 0);
+            uint32_t numPositivePics = parseUEWithFallback(&reader, 0);
+            if (numNegativePics > UINT32_MAX - numPositivePics) {
+                return ERROR_MALFORMED;
+            }
+            numPics = numNegativePics + numPositivePics;
+            for (uint32_t j = 0; j < numPics; ++j) {
+                skipUE(&reader); // delta_poc_s0|1_minus1[i]
+                reader.skipBits(1); // used_by_curr_pic_s0|1_flag[i]
+            }
+        }
+    }
+    if (reader.getBitsWithFallback(1, 0)) { // long_term_ref_pics_present_flag
+        uint32_t numLongTermRefPicSps = parseUEWithFallback(&reader, 0);
+        for (uint32_t i = 0; i < numLongTermRefPicSps; ++i) {
+            reader.skipBits(log2MaxPicOrderCntLsb); // lt_ref_pic_poc_lsb_sps[i]
+            reader.skipBits(1); // used_by_curr_pic_lt_sps_flag[i]
+        }
+    }
+    reader.skipBits(1); // sps_temporal_mvp_enabled_flag
+    reader.skipBits(1); // strong_intra_smoothing_enabled_flag
+    if (reader.getBitsWithFallback(1, 0)) { // vui_parameters_present_flag
+        if (reader.getBitsWithFallback(1, 0)) { // aspect_ratio_info_present_flag
+            uint32_t aspectRatioIdc = reader.getBitsWithFallback(8, 0);
+            if (aspectRatioIdc == 0xFF /* EXTENDED_SAR */) {
+                reader.skipBits(16); // sar_width
+                reader.skipBits(16); // sar_height
+            }
+        }
+        if (reader.getBitsWithFallback(1, 0)) { // overscan_info_present_flag
+            reader.skipBits(1); // overscan_appropriate_flag
+        }
+        if (reader.getBitsWithFallback(1, 0)) { // video_signal_type_present_flag
+            reader.skipBits(3); // video_format
+            uint32_t videoFullRangeFlag;
+            if (reader.getBitsGraceful(1, &videoFullRangeFlag)) {
+                mParams.add(kVideoFullRangeFlag, videoFullRangeFlag);
+            }
+            if (reader.getBitsWithFallback(1, 0)) { // colour_description_present_flag
+                mInfo = (Info)(mInfo | kInfoHasColorDescription);
+                uint32_t colourPrimaries, transferCharacteristics, matrixCoeffs;
+                if (reader.getBitsGraceful(8, &colourPrimaries)) {
+                    mParams.add(kColourPrimaries, colourPrimaries);
+                }
+                if (reader.getBitsGraceful(8, &transferCharacteristics)) {
+                    mParams.add(kTransferCharacteristics, transferCharacteristics);
+                    if (transferCharacteristics == 16 /* ST 2084 */
+                            || transferCharacteristics == 18 /* ARIB STD-B67 HLG */) {
+                        mInfo = (Info)(mInfo | kInfoIsHdr);
+                    }
+                }
+                if (reader.getBitsGraceful(8, &matrixCoeffs)) {
+                    mParams.add(kMatrixCoeffs, matrixCoeffs);
+                }
+            }
+            // skip rest of VUI
+        }
+    }
+
+    return reader.overRead() ? ERROR_MALFORMED : OK;
 }
 
 status_t HevcParameterSets::parsePps(
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index f29ec11..6a67fcf 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -1566,8 +1566,9 @@
 
                 const char *mime;
                 CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime));
-                if (!strcmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
-                    // AVC requires compression ratio of at least 2, and uses
+                if (!strcmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)
+                        || !strcmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC)) {
+                    // AVC & HEVC requires compression ratio of at least 2, and uses
                     // macroblocks
                     max_size = ((width + 15) / 16) * ((height + 15) / 16) * 192;
                 } else {
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index 46a32fb..cc5f7a0 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -1957,6 +1957,7 @@
             if (mProfileIdc != data[1] ||
                 mProfileCompatible != data[2] ||
                 mLevelIdc != data[3]) {
+                // COULD DO: set profile/level to the lowest required to support all SPSs
                 ALOGE("Inconsistent profile/level found in seq parameter sets");
                 return NULL;
             }
diff --git a/media/libstagefright/OMXClient.cpp b/media/libstagefright/OMXClient.cpp
index 7279f6c..e994069 100644
--- a/media/libstagefright/OMXClient.cpp
+++ b/media/libstagefright/OMXClient.cpp
@@ -207,12 +207,14 @@
 // static
 MuxOMX::node_location MuxOMX::getPreferredCodecLocation(const char *name) {
     if (sCodecProcessEnabled) {
+        // all codecs go to codec process unless excluded using system property, in which case
         // all non-secure decoders, OMX.google.* codecs and encoders can go in the codec process
         // (non-OMX.google.* encoders can be excluded using system property.)
         if ((strcasestr(name, "decoder")
                         && strcasestr(name, ".secure") != name + strlen(name) - 7)
                 || (strcasestr(name, "encoder")
                         && !property_get_bool("media.stagefright.legacyencoder", false))
+                || !property_get_bool("media.stagefright.less-secure", false)
                 || !strncasecmp(name, "OMX.google.", 11)) {
             return CODECPROCESS;
         }
diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp
index aa64d22..c343dee 100644
--- a/media/libstagefright/Utils.cpp
+++ b/media/libstagefright/Utils.cpp
@@ -21,15 +21,20 @@
 #include <stdio.h>
 #include <sys/stat.h>
 
+#include <utility>
+
 #include "include/ESDS.h"
 #include "include/HevcUtils.h"
 
 #include <arpa/inet.h>
 #include <cutils/properties.h>
 #include <media/openmax/OMX_Audio.h>
+#include <media/openmax/OMX_Video.h>
+#include <media/openmax/OMX_VideoExt.h>
 #include <media/stagefright/CodecBase.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/ALookup.h>
 #include <media/stagefright/foundation/AMessage.h>
 #include <media/stagefright/MetaData.h>
 #include <media/stagefright/MediaDefs.h>
@@ -91,6 +96,7 @@
     return OK;
 }
 
+#if 0
 static void convertMetaDataToMessageInt32(
         const sp<MetaData> &meta, sp<AMessage> &msg, uint32_t key, const char *name) {
     int32_t value;
@@ -98,6 +104,7 @@
         msg->setInt32(name, value);
     }
 }
+#endif
 
 static void convertMetaDataToMessageColorAspects(const sp<MetaData> &meta, sp<AMessage> &msg) {
     // 0 values are unspecified
@@ -134,6 +141,456 @@
     }
 }
 
+static bool isHdr(const sp<AMessage> &format) {
+    // if CSD specifies HDR transfer(s), we assume HDR. Otherwise, if it specifies non-HDR
+    // transfers, we must assume non-HDR. This is because CSD trumps any color-transfer key
+    // in the format.
+    int32_t isHdr;
+    if (format->findInt32("android._is-hdr", &isHdr)) {
+        return isHdr;
+    }
+
+    // if user/container supplied HDR static info without transfer set, assume true
+    if (format->contains("hdr-static-info") && !format->contains("color-transfer")) {
+        return true;
+    }
+    // otherwise, verify that an HDR transfer function is set
+    int32_t transfer;
+    if (format->findInt32("color-transfer", &transfer)) {
+        return transfer == ColorUtils::kColorTransferST2084
+                || transfer == ColorUtils::kColorTransferHLG;
+    }
+    return false;
+}
+
+static void parseAacProfileFromCsd(const sp<ABuffer> &csd, sp<AMessage> &format) {
+    if (csd->size() < 2) {
+        return;
+    }
+
+    uint16_t audioObjectType = U16_AT((uint8_t*)csd->data());
+    if ((audioObjectType & 0xF800) == 0xF800) {
+        audioObjectType = 32 + ((audioObjectType >> 5) & 0x3F);
+    } else {
+        audioObjectType >>= 11;
+    }
+
+    const static ALookup<uint16_t, OMX_AUDIO_AACPROFILETYPE> profiles {
+        { 1,  OMX_AUDIO_AACObjectMain     },
+        { 2,  OMX_AUDIO_AACObjectLC       },
+        { 3,  OMX_AUDIO_AACObjectSSR      },
+        { 4,  OMX_AUDIO_AACObjectLTP      },
+        { 5,  OMX_AUDIO_AACObjectHE       },
+        { 6,  OMX_AUDIO_AACObjectScalable },
+        { 17, OMX_AUDIO_AACObjectERLC     },
+        { 23, OMX_AUDIO_AACObjectLD       },
+        { 29, OMX_AUDIO_AACObjectHE_PS    },
+        { 39, OMX_AUDIO_AACObjectELD      },
+    };
+
+    OMX_AUDIO_AACPROFILETYPE profile;
+    if (profiles.map(audioObjectType, &profile)) {
+        format->setInt32("profile", profile);
+    }
+}
+
+static void parseAvcProfileLevelFromAvcc(const uint8_t *ptr, size_t size, sp<AMessage> &format) {
+    if (size < 4 || ptr[0] != 1) {  // configurationVersion == 1
+        return;
+    }
+    const uint8_t profile = ptr[1];
+    const uint8_t constraints = ptr[2];
+    const uint8_t level = ptr[3];
+
+    const static ALookup<uint8_t, OMX_VIDEO_AVCLEVELTYPE> levels {
+        {  9, OMX_VIDEO_AVCLevel1b }, // technically, 9 is only used for High+ profiles
+        { 10, OMX_VIDEO_AVCLevel1  },
+        { 11, OMX_VIDEO_AVCLevel11 }, // prefer level 1.1 for the value 11
+        { 11, OMX_VIDEO_AVCLevel1b },
+        { 12, OMX_VIDEO_AVCLevel12 },
+        { 13, OMX_VIDEO_AVCLevel13 },
+        { 20, OMX_VIDEO_AVCLevel2  },
+        { 21, OMX_VIDEO_AVCLevel21 },
+        { 22, OMX_VIDEO_AVCLevel22 },
+        { 30, OMX_VIDEO_AVCLevel3  },
+        { 31, OMX_VIDEO_AVCLevel31 },
+        { 32, OMX_VIDEO_AVCLevel32 },
+        { 40, OMX_VIDEO_AVCLevel4  },
+        { 41, OMX_VIDEO_AVCLevel41 },
+        { 42, OMX_VIDEO_AVCLevel42 },
+        { 50, OMX_VIDEO_AVCLevel5  },
+        { 51, OMX_VIDEO_AVCLevel51 },
+        { 52, OMX_VIDEO_AVCLevel52 },
+    };
+    const static ALookup<uint8_t, OMX_VIDEO_AVCPROFILETYPE> profiles {
+        { 66, OMX_VIDEO_AVCProfileBaseline },
+        { 77, OMX_VIDEO_AVCProfileMain     },
+        { 88, OMX_VIDEO_AVCProfileExtended },
+        { 100, OMX_VIDEO_AVCProfileHigh    },
+        { 110, OMX_VIDEO_AVCProfileHigh10  },
+        { 122, OMX_VIDEO_AVCProfileHigh422 },
+        { 244, OMX_VIDEO_AVCProfileHigh444 },
+    };
+
+    // set profile & level if they are recognized
+    OMX_VIDEO_AVCPROFILETYPE codecProfile;
+    OMX_VIDEO_AVCLEVELTYPE codecLevel;
+    if (profiles.map(profile, &codecProfile)) {
+        format->setInt32("profile", codecProfile);
+        if (levels.map(level, &codecLevel)) {
+            // for 9 && 11 decide level based on profile and constraint_set3 flag
+            if (level == 11 && (profile == 66 || profile == 77 || profile == 88)) {
+                codecLevel = (constraints & 0x10) ? OMX_VIDEO_AVCLevel1b : OMX_VIDEO_AVCLevel11;
+            }
+            format->setInt32("level", codecLevel);
+        }
+    }
+}
+
+static void parseH263ProfileLevelFromD263(const uint8_t *ptr, size_t size, sp<AMessage> &format) {
+    if (size < 7) {
+        return;
+    }
+
+    const uint8_t profile = ptr[6];
+    const uint8_t level = ptr[5];
+
+    const static ALookup<uint8_t, OMX_VIDEO_H263PROFILETYPE> profiles {
+        { 0, OMX_VIDEO_H263ProfileBaseline },
+        { 1, OMX_VIDEO_H263ProfileH320Coding },
+        { 2, OMX_VIDEO_H263ProfileBackwardCompatible },
+        { 3, OMX_VIDEO_H263ProfileISWV2 },
+        { 4, OMX_VIDEO_H263ProfileISWV3 },
+        { 5, OMX_VIDEO_H263ProfileHighCompression },
+        { 6, OMX_VIDEO_H263ProfileInternet },
+        { 7, OMX_VIDEO_H263ProfileInterlace },
+        { 8, OMX_VIDEO_H263ProfileHighLatency },
+    };
+
+    const static ALookup<uint8_t, OMX_VIDEO_H263LEVELTYPE> levels {
+        { 10, OMX_VIDEO_H263Level10 },
+        { 20, OMX_VIDEO_H263Level20 },
+        { 30, OMX_VIDEO_H263Level30 },
+        { 40, OMX_VIDEO_H263Level40 },
+        { 45, OMX_VIDEO_H263Level45 },
+        { 50, OMX_VIDEO_H263Level50 },
+        { 60, OMX_VIDEO_H263Level60 },
+        { 70, OMX_VIDEO_H263Level70 },
+    };
+
+    // set profile & level if they are recognized
+    OMX_VIDEO_H263PROFILETYPE codecProfile;
+    OMX_VIDEO_H263LEVELTYPE codecLevel;
+    if (profiles.map(profile, &codecProfile)) {
+        format->setInt32("profile", codecProfile);
+        if (levels.map(level, &codecLevel)) {
+            format->setInt32("level", codecLevel);
+        }
+    }
+}
+
+static void parseHevcProfileLevelFromHvcc(const uint8_t *ptr, size_t size, sp<AMessage> &format) {
+    if (size < 13 || ptr[0] != 1) {  // configurationVersion == 1
+        return;
+    }
+
+    const uint8_t profile = ptr[1] & 0x1F;
+    const uint8_t tier = (ptr[1] & 0x20) >> 5;
+    const uint8_t level = ptr[12];
+
+    const static ALookup<std::pair<uint8_t, uint8_t>, OMX_VIDEO_HEVCLEVELTYPE> levels {
+        { { 0, 30  }, OMX_VIDEO_HEVCMainTierLevel1  },
+        { { 0, 60  }, OMX_VIDEO_HEVCMainTierLevel2  },
+        { { 0, 63  }, OMX_VIDEO_HEVCMainTierLevel21 },
+        { { 0, 90  }, OMX_VIDEO_HEVCMainTierLevel3  },
+        { { 0, 93  }, OMX_VIDEO_HEVCMainTierLevel31 },
+        { { 0, 120 }, OMX_VIDEO_HEVCMainTierLevel4  },
+        { { 0, 123 }, OMX_VIDEO_HEVCMainTierLevel41 },
+        { { 0, 150 }, OMX_VIDEO_HEVCMainTierLevel5  },
+        { { 0, 153 }, OMX_VIDEO_HEVCMainTierLevel51 },
+        { { 0, 156 }, OMX_VIDEO_HEVCMainTierLevel52 },
+        { { 0, 180 }, OMX_VIDEO_HEVCMainTierLevel6  },
+        { { 0, 183 }, OMX_VIDEO_HEVCMainTierLevel61 },
+        { { 0, 186 }, OMX_VIDEO_HEVCMainTierLevel62 },
+        { { 1, 30  }, OMX_VIDEO_HEVCHighTierLevel1  },
+        { { 1, 60  }, OMX_VIDEO_HEVCHighTierLevel2  },
+        { { 1, 63  }, OMX_VIDEO_HEVCHighTierLevel21 },
+        { { 1, 90  }, OMX_VIDEO_HEVCHighTierLevel3  },
+        { { 1, 93  }, OMX_VIDEO_HEVCHighTierLevel31 },
+        { { 1, 120 }, OMX_VIDEO_HEVCHighTierLevel4  },
+        { { 1, 123 }, OMX_VIDEO_HEVCHighTierLevel41 },
+        { { 1, 150 }, OMX_VIDEO_HEVCHighTierLevel5  },
+        { { 1, 153 }, OMX_VIDEO_HEVCHighTierLevel51 },
+        { { 1, 156 }, OMX_VIDEO_HEVCHighTierLevel52 },
+        { { 1, 180 }, OMX_VIDEO_HEVCHighTierLevel6  },
+        { { 1, 183 }, OMX_VIDEO_HEVCHighTierLevel61 },
+        { { 1, 186 }, OMX_VIDEO_HEVCHighTierLevel62 },
+    };
+
+    const static ALookup<uint8_t, OMX_VIDEO_HEVCPROFILETYPE> profiles {
+        { 1, OMX_VIDEO_HEVCProfileMain   },
+        { 2, OMX_VIDEO_HEVCProfileMain10 },
+    };
+
+    // set profile & level if they are recognized
+    OMX_VIDEO_HEVCPROFILETYPE codecProfile;
+    OMX_VIDEO_HEVCLEVELTYPE codecLevel;
+    if (!profiles.map(profile, &codecProfile)) {
+        if (ptr[2] & 0x40 /* general compatibility flag 1 */) {
+            codecProfile = OMX_VIDEO_HEVCProfileMain;
+        } else if (ptr[2] & 0x20 /* general compatibility flag 2 */) {
+            codecProfile = OMX_VIDEO_HEVCProfileMain10;
+        } else {
+            return;
+        }
+    }
+
+    // bump to HDR profile
+    if (isHdr(format) && codecProfile == OMX_VIDEO_HEVCProfileMain10) {
+        codecProfile = OMX_VIDEO_HEVCProfileMain10HDR10;
+    }
+
+    format->setInt32("profile", codecProfile);
+    if (levels.map(std::make_pair(tier, level), &codecLevel)) {
+        format->setInt32("level", codecLevel);
+    }
+}
+
+static void parseMpeg2ProfileLevelFromHeader(
+        const uint8_t *data, size_t size, sp<AMessage> &format) {
+    // find sequence extension
+    const uint8_t *seq = (const uint8_t*)memmem(data, size, "\x00\x00\x01\xB5", 4);
+    if (seq != NULL && seq + 5 < data + size) {
+        const uint8_t start_code = seq[4] >> 4;
+        if (start_code != 1 /* sequence extension ID */) {
+            return;
+        }
+        const uint8_t indication = ((seq[4] & 0xF) << 4) | ((seq[5] & 0xF0) >> 4);
+
+        const static ALookup<uint8_t, OMX_VIDEO_MPEG2PROFILETYPE> profiles {
+            { 0x50, OMX_VIDEO_MPEG2ProfileSimple  },
+            { 0x40, OMX_VIDEO_MPEG2ProfileMain    },
+            { 0x30, OMX_VIDEO_MPEG2ProfileSNR     },
+            { 0x20, OMX_VIDEO_MPEG2ProfileSpatial },
+            { 0x10, OMX_VIDEO_MPEG2ProfileHigh    },
+        };
+
+        const static ALookup<uint8_t, OMX_VIDEO_MPEG2LEVELTYPE> levels {
+            { 0x0A, OMX_VIDEO_MPEG2LevelLL  },
+            { 0x08, OMX_VIDEO_MPEG2LevelML  },
+            { 0x06, OMX_VIDEO_MPEG2LevelH14 },
+            { 0x04, OMX_VIDEO_MPEG2LevelHL  },
+            { 0x02, OMX_VIDEO_MPEG2LevelHP  },
+        };
+
+        const static ALookup<uint8_t,
+                std::pair<OMX_VIDEO_MPEG2PROFILETYPE, OMX_VIDEO_MPEG2LEVELTYPE>> escapes {
+            /* unsupported
+            { 0x8E, { XXX_MPEG2ProfileMultiView, OMX_VIDEO_MPEG2LevelLL  } },
+            { 0x8D, { XXX_MPEG2ProfileMultiView, OMX_VIDEO_MPEG2LevelML  } },
+            { 0x8B, { XXX_MPEG2ProfileMultiView, OMX_VIDEO_MPEG2LevelH14 } },
+            { 0x8A, { XXX_MPEG2ProfileMultiView, OMX_VIDEO_MPEG2LevelHL  } }, */
+            { 0x85, { OMX_VIDEO_MPEG2Profile422, OMX_VIDEO_MPEG2LevelML  } },
+            { 0x82, { OMX_VIDEO_MPEG2Profile422, OMX_VIDEO_MPEG2LevelHL  } },
+        };
+
+        OMX_VIDEO_MPEG2PROFILETYPE profile;
+        OMX_VIDEO_MPEG2LEVELTYPE level;
+        std::pair<OMX_VIDEO_MPEG2PROFILETYPE, OMX_VIDEO_MPEG2LEVELTYPE> profileLevel;
+        if (escapes.map(indication, &profileLevel)) {
+            format->setInt32("profile", profileLevel.first);
+            format->setInt32("level", profileLevel.second);
+        } else if (profiles.map(indication & 0x70, &profile)) {
+            format->setInt32("profile", profile);
+            if (levels.map(indication & 0xF, &level)) {
+                format->setInt32("level", level);
+            }
+        }
+    }
+}
+
+static void parseMpeg2ProfileLevelFromEsds(ESDS &esds, sp<AMessage> &format) {
+    // esds seems to only contain the profile for MPEG-2
+    uint8_t objType;
+    if (esds.getObjectTypeIndication(&objType) == OK) {
+        const static ALookup<uint8_t, OMX_VIDEO_MPEG2PROFILETYPE> profiles{
+            { 0x60, OMX_VIDEO_MPEG2ProfileSimple  },
+            { 0x61, OMX_VIDEO_MPEG2ProfileMain    },
+            { 0x62, OMX_VIDEO_MPEG2ProfileSNR     },
+            { 0x63, OMX_VIDEO_MPEG2ProfileSpatial },
+            { 0x64, OMX_VIDEO_MPEG2ProfileHigh    },
+            { 0x65, OMX_VIDEO_MPEG2Profile422     },
+        };
+
+        OMX_VIDEO_MPEG2PROFILETYPE profile;
+        if (profiles.map(objType, &profile)) {
+            format->setInt32("profile", profile);
+        }
+    }
+}
+
+static void parseMpeg4ProfileLevelFromCsd(const sp<ABuffer> &csd, sp<AMessage> &format) {
+    const uint8_t *data = csd->data();
+    // find visual object sequence
+    const uint8_t *seq = (const uint8_t*)memmem(data, csd->size(), "\x00\x00\x01\xB0", 4);
+    if (seq != NULL && seq + 4 < data + csd->size()) {
+        const uint8_t indication = seq[4];
+
+        const static ALookup<uint8_t,
+                std::pair<OMX_VIDEO_MPEG4PROFILETYPE, OMX_VIDEO_MPEG4LEVELTYPE>> table {
+            { 0b00000001, { OMX_VIDEO_MPEG4ProfileSimple,            OMX_VIDEO_MPEG4Level1  } },
+            { 0b00000010, { OMX_VIDEO_MPEG4ProfileSimple,            OMX_VIDEO_MPEG4Level2  } },
+            { 0b00000011, { OMX_VIDEO_MPEG4ProfileSimple,            OMX_VIDEO_MPEG4Level3  } },
+            { 0b00000100, { OMX_VIDEO_MPEG4ProfileSimple,            OMX_VIDEO_MPEG4Level4a } },
+            { 0b00000101, { OMX_VIDEO_MPEG4ProfileSimple,            OMX_VIDEO_MPEG4Level5  } },
+            { 0b00000110, { OMX_VIDEO_MPEG4ProfileSimple,            OMX_VIDEO_MPEG4Level6  } },
+            { 0b00001000, { OMX_VIDEO_MPEG4ProfileSimple,            OMX_VIDEO_MPEG4Level0  } },
+            { 0b00001001, { OMX_VIDEO_MPEG4ProfileSimple,            OMX_VIDEO_MPEG4Level0b } },
+            { 0b00010000, { OMX_VIDEO_MPEG4ProfileSimpleScalable,    OMX_VIDEO_MPEG4Level0  } },
+            { 0b00010001, { OMX_VIDEO_MPEG4ProfileSimpleScalable,    OMX_VIDEO_MPEG4Level1  } },
+            { 0b00010010, { OMX_VIDEO_MPEG4ProfileSimpleScalable,    OMX_VIDEO_MPEG4Level2  } },
+            /* unsupported
+            { 0b00011101, { XXX_MPEG4ProfileSimpleScalableER,        OMX_VIDEO_MPEG4Level0  } },
+            { 0b00011110, { XXX_MPEG4ProfileSimpleScalableER,        OMX_VIDEO_MPEG4Level1  } },
+            { 0b00011111, { XXX_MPEG4ProfileSimpleScalableER,        OMX_VIDEO_MPEG4Level2  } }, */
+            { 0b00100001, { OMX_VIDEO_MPEG4ProfileCore,              OMX_VIDEO_MPEG4Level1  } },
+            { 0b00100010, { OMX_VIDEO_MPEG4ProfileCore,              OMX_VIDEO_MPEG4Level2  } },
+            { 0b00110010, { OMX_VIDEO_MPEG4ProfileMain,              OMX_VIDEO_MPEG4Level2  } },
+            { 0b00110011, { OMX_VIDEO_MPEG4ProfileMain,              OMX_VIDEO_MPEG4Level3  } },
+            { 0b00110100, { OMX_VIDEO_MPEG4ProfileMain,              OMX_VIDEO_MPEG4Level4  } },
+            /* deprecated
+            { 0b01000010, { OMX_VIDEO_MPEG4ProfileNbit,              OMX_VIDEO_MPEG4Level2  } }, */
+            { 0b01010001, { OMX_VIDEO_MPEG4ProfileScalableTexture,   OMX_VIDEO_MPEG4Level1  } },
+            { 0b01100001, { OMX_VIDEO_MPEG4ProfileSimpleFace,        OMX_VIDEO_MPEG4Level1  } },
+            { 0b01100010, { OMX_VIDEO_MPEG4ProfileSimpleFace,        OMX_VIDEO_MPEG4Level2  } },
+            { 0b01100011, { OMX_VIDEO_MPEG4ProfileSimpleFBA,         OMX_VIDEO_MPEG4Level1  } },
+            { 0b01100100, { OMX_VIDEO_MPEG4ProfileSimpleFBA,         OMX_VIDEO_MPEG4Level2  } },
+            { 0b01110001, { OMX_VIDEO_MPEG4ProfileBasicAnimated,     OMX_VIDEO_MPEG4Level1  } },
+            { 0b01110010, { OMX_VIDEO_MPEG4ProfileBasicAnimated,     OMX_VIDEO_MPEG4Level2  } },
+            { 0b10000001, { OMX_VIDEO_MPEG4ProfileHybrid,            OMX_VIDEO_MPEG4Level1  } },
+            { 0b10000010, { OMX_VIDEO_MPEG4ProfileHybrid,            OMX_VIDEO_MPEG4Level2  } },
+            { 0b10010001, { OMX_VIDEO_MPEG4ProfileAdvancedRealTime,  OMX_VIDEO_MPEG4Level1  } },
+            { 0b10010010, { OMX_VIDEO_MPEG4ProfileAdvancedRealTime,  OMX_VIDEO_MPEG4Level2  } },
+            { 0b10010011, { OMX_VIDEO_MPEG4ProfileAdvancedRealTime,  OMX_VIDEO_MPEG4Level3  } },
+            { 0b10010100, { OMX_VIDEO_MPEG4ProfileAdvancedRealTime,  OMX_VIDEO_MPEG4Level4  } },
+            { 0b10100001, { OMX_VIDEO_MPEG4ProfileCoreScalable,      OMX_VIDEO_MPEG4Level1  } },
+            { 0b10100010, { OMX_VIDEO_MPEG4ProfileCoreScalable,      OMX_VIDEO_MPEG4Level2  } },
+            { 0b10100011, { OMX_VIDEO_MPEG4ProfileCoreScalable,      OMX_VIDEO_MPEG4Level3  } },
+            { 0b10110001, { OMX_VIDEO_MPEG4ProfileAdvancedCoding,    OMX_VIDEO_MPEG4Level1  } },
+            { 0b10110010, { OMX_VIDEO_MPEG4ProfileAdvancedCoding,    OMX_VIDEO_MPEG4Level2  } },
+            { 0b10110011, { OMX_VIDEO_MPEG4ProfileAdvancedCoding,    OMX_VIDEO_MPEG4Level3  } },
+            { 0b10110100, { OMX_VIDEO_MPEG4ProfileAdvancedCoding,    OMX_VIDEO_MPEG4Level4  } },
+            { 0b11000001, { OMX_VIDEO_MPEG4ProfileAdvancedCore,      OMX_VIDEO_MPEG4Level1  } },
+            { 0b11000010, { OMX_VIDEO_MPEG4ProfileAdvancedCore,      OMX_VIDEO_MPEG4Level2  } },
+            { 0b11010001, { OMX_VIDEO_MPEG4ProfileAdvancedScalable,  OMX_VIDEO_MPEG4Level1  } },
+            { 0b11010010, { OMX_VIDEO_MPEG4ProfileAdvancedScalable,  OMX_VIDEO_MPEG4Level2  } },
+            { 0b11010011, { OMX_VIDEO_MPEG4ProfileAdvancedScalable,  OMX_VIDEO_MPEG4Level3  } },
+            /* unsupported
+            { 0b11100001, { XXX_MPEG4ProfileSimpleStudio,            OMX_VIDEO_MPEG4Level1  } },
+            { 0b11100010, { XXX_MPEG4ProfileSimpleStudio,            OMX_VIDEO_MPEG4Level2  } },
+            { 0b11100011, { XXX_MPEG4ProfileSimpleStudio,            OMX_VIDEO_MPEG4Level3  } },
+            { 0b11100100, { XXX_MPEG4ProfileSimpleStudio,            OMX_VIDEO_MPEG4Level4  } },
+            { 0b11100101, { XXX_MPEG4ProfileCoreStudio,              OMX_VIDEO_MPEG4Level1  } },
+            { 0b11100110, { XXX_MPEG4ProfileCoreStudio,              OMX_VIDEO_MPEG4Level2  } },
+            { 0b11100111, { XXX_MPEG4ProfileCoreStudio,              OMX_VIDEO_MPEG4Level3  } },
+            { 0b11101000, { XXX_MPEG4ProfileCoreStudio,              OMX_VIDEO_MPEG4Level4  } },
+            { 0b11101011, { XXX_MPEG4ProfileSimpleStudio,            OMX_VIDEO_MPEG4Level5  } },
+            { 0b11101100, { XXX_MPEG4ProfileSimpleStudio,            OMX_VIDEO_MPEG4Level6  } }, */
+            { 0b11110000, { OMX_VIDEO_MPEG4ProfileAdvancedSimple,    OMX_VIDEO_MPEG4Level0  } },
+            { 0b11110001, { OMX_VIDEO_MPEG4ProfileAdvancedSimple,    OMX_VIDEO_MPEG4Level1  } },
+            { 0b11110010, { OMX_VIDEO_MPEG4ProfileAdvancedSimple,    OMX_VIDEO_MPEG4Level2  } },
+            { 0b11110011, { OMX_VIDEO_MPEG4ProfileAdvancedSimple,    OMX_VIDEO_MPEG4Level3  } },
+            { 0b11110100, { OMX_VIDEO_MPEG4ProfileAdvancedSimple,    OMX_VIDEO_MPEG4Level4  } },
+            { 0b11110101, { OMX_VIDEO_MPEG4ProfileAdvancedSimple,    OMX_VIDEO_MPEG4Level5  } },
+            { 0b11110111, { OMX_VIDEO_MPEG4ProfileAdvancedSimple,    OMX_VIDEO_MPEG4Level3b } },
+            /* deprecated
+            { 0b11111000, { XXX_MPEG4ProfileFineGranularityScalable, OMX_VIDEO_MPEG4Level0  } },
+            { 0b11111001, { XXX_MPEG4ProfileFineGranularityScalable, OMX_VIDEO_MPEG4Level1  } },
+            { 0b11111010, { XXX_MPEG4ProfileFineGranularityScalable, OMX_VIDEO_MPEG4Level2  } },
+            { 0b11111011, { XXX_MPEG4ProfileFineGranularityScalable, OMX_VIDEO_MPEG4Level3  } },
+            { 0b11111100, { XXX_MPEG4ProfileFineGranularityScalable, OMX_VIDEO_MPEG4Level4  } },
+            { 0b11111101, { XXX_MPEG4ProfileFineGranularityScalable, OMX_VIDEO_MPEG4Level5  } }, */
+        };
+
+        std::pair<OMX_VIDEO_MPEG4PROFILETYPE, OMX_VIDEO_MPEG4LEVELTYPE> profileLevel;
+        if (table.map(indication, &profileLevel)) {
+            format->setInt32("profile", profileLevel.first);
+            format->setInt32("level", profileLevel.second);
+        }
+    }
+}
+
+static void parseVp9ProfileLevelFromCsd(const sp<ABuffer> &csd, sp<AMessage> &format) {
+    const uint8_t *data = csd->data();
+    size_t remaining = csd->size();
+
+    while (remaining >= 2) {
+        const uint8_t id = data[0];
+        const uint8_t length = data[1];
+        remaining -= 2;
+        data += 2;
+        if (length > remaining) {
+            break;
+        }
+        switch (id) {
+            case 1 /* profileId */:
+                if (length >= 1) {
+                    const static ALookup<uint8_t, OMX_VIDEO_VP9PROFILETYPE> profiles {
+                        { 0, OMX_VIDEO_VP9Profile0 },
+                        { 1, OMX_VIDEO_VP9Profile1 },
+                        { 2, OMX_VIDEO_VP9Profile2 },
+                        { 3, OMX_VIDEO_VP9Profile3 },
+                    };
+
+                    const static ALookup<OMX_VIDEO_VP9PROFILETYPE, OMX_VIDEO_VP9PROFILETYPE> toHdr {
+                        { OMX_VIDEO_VP9Profile2, OMX_VIDEO_VP9Profile2HDR },
+                        { OMX_VIDEO_VP9Profile3, OMX_VIDEO_VP9Profile3HDR },
+                    };
+
+                    OMX_VIDEO_VP9PROFILETYPE profile;
+                    if (profiles.map(data[0], &profile)) {
+                        // convert to HDR profile
+                        if (isHdr(format)) {
+                            toHdr.lookup(profile, &profile);
+                        }
+
+                        format->setInt32("profile", profile);
+                    }
+                }
+                break;
+            case 2 /* levelId */:
+                if (length >= 1) {
+                    const static ALookup<uint8_t, OMX_VIDEO_VP9LEVELTYPE> levels {
+                        { 10, OMX_VIDEO_VP9Level1  },
+                        { 11, OMX_VIDEO_VP9Level11 },
+                        { 20, OMX_VIDEO_VP9Level2  },
+                        { 21, OMX_VIDEO_VP9Level21 },
+                        { 30, OMX_VIDEO_VP9Level3  },
+                        { 31, OMX_VIDEO_VP9Level31 },
+                        { 40, OMX_VIDEO_VP9Level4  },
+                        { 41, OMX_VIDEO_VP9Level41 },
+                        { 50, OMX_VIDEO_VP9Level5  },
+                        { 51, OMX_VIDEO_VP9Level51 },
+                        { 52, OMX_VIDEO_VP9Level52 },
+                        { 60, OMX_VIDEO_VP9Level6  },
+                        { 61, OMX_VIDEO_VP9Level61 },
+                        { 62, OMX_VIDEO_VP9Level62 },
+                    };
+
+                    OMX_VIDEO_VP9LEVELTYPE level;
+                    if (levels.map(data[0], &level)) {
+                        format->setInt32("level", level);
+                    }
+                }
+                break;
+            default:
+                break;
+        }
+        remaining -= length;
+        data += length;
+    }
+}
+
 status_t convertMetaDataToMessage(
         const sp<MetaData> &meta, sp<AMessage> *format) {
 
@@ -157,13 +614,14 @@
         msg->setInt64("durationUs", durationUs);
     }
 
-    int32_t avgBitRate;
-    if (meta->findInt32(kKeyBitRate, &avgBitRate)) {
+    int32_t avgBitRate = 0;
+    if (meta->findInt32(kKeyBitRate, &avgBitRate) && avgBitRate > 0) {
         msg->setInt32("bitrate", avgBitRate);
     }
 
     int32_t maxBitRate;
-    if (meta->findInt32(kKeyMaxBitRate, &maxBitRate)) {
+    if (meta->findInt32(kKeyMaxBitRate, &maxBitRate)
+            && maxBitRate > 0 && maxBitRate >= avgBitRate) {
         msg->setInt32("max-bitrate", maxBitRate);
     }
 
@@ -214,8 +672,14 @@
             msg->setInt32("rotation-degrees", rotationDegrees);
         }
 
-        convertMetaDataToMessageInt32(meta, msg, kKeyMinLuminance, "min-luminance");
-        convertMetaDataToMessageInt32(meta, msg, kKeyMaxLuminance, "max-luminance");
+        uint32_t type;
+        const void *data;
+        size_t size;
+        if (meta->findData(kKeyHdrStaticInfo, &type, &data, &size)
+                && type == 'hdrS' && size == sizeof(HDRStaticInfo)) {
+            ColorUtils::setHDRStaticInfoIntoFormat(*(HDRStaticInfo*)data, msg);
+        }
+
         convertMetaDataToMessageColorAspects(meta, msg);
     } else if (!strncasecmp("audio/", mime, 6)) {
         int32_t numChannels, sampleRate;
@@ -294,8 +758,8 @@
             ALOGE("b/23680780");
             return BAD_VALUE;
         }
-        uint8_t profile __unused = ptr[1];
-        uint8_t level __unused = ptr[3];
+
+        parseAvcProfileLevelFromAvcc(ptr, size, msg);
 
         // There is decodable content out there that fails the following
         // assertion, let's be lenient for now...
@@ -391,12 +855,11 @@
             ALOGE("b/23680780");
             return BAD_VALUE;
         }
-        uint8_t profile __unused = ptr[1] & 31;
-        uint8_t level __unused = ptr[12];
+
+        const size_t dataSize = size; // save for later
         ptr += 22;
         size -= 22;
 
-
         size_t numofArrays = (char)ptr[0];
         ptr += 1;
         size -= 1;
@@ -408,6 +871,8 @@
         }
         buffer->setRange(0, 0);
 
+        HevcParameterSets hvcc;
+
         for (i = 0; i < numofArrays; i++) {
             if (size < 3) {
                 ALOGE("b/23680780");
@@ -439,6 +904,7 @@
                 if (err != OK) {
                     return err;
                 }
+                (void)hvcc.addNalUnit(ptr, length);
 
                 ptr += length;
                 size -= length;
@@ -448,6 +914,14 @@
         buffer->meta()->setInt64("timeUs", 0);
         msg->setBuffer("csd-0", buffer);
 
+        // if we saw VUI color information we know whether this is HDR because VUI trumps other
+        // format parameters for HEVC.
+        HevcParameterSets::Info info = hvcc.getInfo();
+        if (info & hvcc.kInfoHasColorDescription) {
+            msg->setInt32("android._is-hdr", (info & hvcc.kInfoIsHdr) != 0);
+        }
+
+        parseHevcProfileLevelFromHvcc((const uint8_t *)data, dataSize, msg);
     } else if (meta->findData(kKeyESDS, &type, &data, &size)) {
         ESDS esds((const char *)data, size);
         if (esds.InitCheck() != (status_t)OK) {
@@ -471,17 +945,33 @@
         buffer->meta()->setInt64("timeUs", 0);
         msg->setBuffer("csd-0", buffer);
 
+        if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4)) {
+            parseMpeg4ProfileLevelFromCsd(buffer, msg);
+        } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG2)) {
+            parseMpeg2ProfileLevelFromEsds(esds, msg);
+            if (meta->findData(kKeyStreamHeader, &type, &data, &size)) {
+                parseMpeg2ProfileLevelFromHeader((uint8_t*)data, size, msg);
+            }
+        } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
+            parseAacProfileFromCsd(buffer, msg);
+        }
+
         uint32_t maxBitrate, avgBitrate;
         if (esds.getBitRate(&maxBitrate, &avgBitrate) == OK) {
-            if (!meta->hasData(kKeyMaxBitRate)
-                    && maxBitrate > 0 && maxBitrate <= INT32_MAX) {
-                msg->setInt32("max-bitrate", (int32_t)maxBitrate);
-            }
             if (!meta->hasData(kKeyBitRate)
                     && avgBitrate > 0 && avgBitrate <= INT32_MAX) {
                 msg->setInt32("bitrate", (int32_t)avgBitrate);
+            } else {
+                (void)msg->findInt32("bitrate", (int32_t*)&avgBitrate);
+            }
+            if (!meta->hasData(kKeyMaxBitRate)
+                    && maxBitrate > 0 && maxBitrate <= INT32_MAX && maxBitrate >= avgBitrate) {
+                msg->setInt32("max-bitrate", (int32_t)maxBitrate);
             }
         }
+    } else if (meta->findData(kTypeD263, &type, &data, &size)) {
+        const uint8_t *ptr = (const uint8_t *)data;
+        parseH263ProfileLevelFromD263(ptr, size, msg);
     } else if (meta->findData(kKeyVorbisInfo, &type, &data, &size)) {
         sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
         if (buffer.get() == NULL || buffer->base() == NULL) {
@@ -554,6 +1044,8 @@
         buffer->meta()->setInt32("csd", true);
         buffer->meta()->setInt64("timeUs", 0);
         msg->setBuffer("csd-0", buffer);
+
+        parseVp9ProfileLevelFromCsd(buffer, msg);
     }
 
     // TODO expose "crypto-key"/kKeyCryptoKey through public api
@@ -622,7 +1114,7 @@
     int numpicparamsoffset = avccidx;
     avccidx++;
     do {
-        i = findNextNalStartCode(csd0->data() + i, csd0->size() - i) - csd0->data();
+        i = findNextNalStartCode(csd1->data() + i, csd1->size() - i) - csd1->data();
         ALOGV("block at %zu, last was %d", i, lastparamoffset);
         if (lastparamoffset > 0) {
             int size = i - lastparamoffset;
@@ -714,6 +1206,7 @@
     return size;
 }
 
+#if 0
 static void convertMessageToMetaDataInt32(
         const sp<AMessage> &msg, sp<MetaData> &meta, uint32_t key, const char *name) {
     int32_t value;
@@ -721,6 +1214,7 @@
         meta->setInt32(key, value);
     }
 }
+#endif
 
 static void convertMessageToMetaDataColorAspects(const sp<AMessage> &msg, sp<MetaData> &meta) {
     // 0 values are unspecified
@@ -769,6 +1263,15 @@
         meta->setInt32(kKeyIsSyncFrame, 1);
     }
 
+    int32_t avgBitrate = 0;
+    int32_t maxBitrate;
+    if (msg->findInt32("bitrate", &avgBitrate) && avgBitrate > 0) {
+        meta->setInt32(kKeyBitRate, avgBitrate);
+    }
+    if (msg->findInt32("max-bitrate", &maxBitrate) && maxBitrate > 0 && maxBitrate >= avgBitrate) {
+        meta->setInt32(kKeyMaxBitRate, maxBitrate);
+    }
+
     if (mime.startsWith("video/")) {
         int32_t width;
         int32_t height;
@@ -805,8 +1308,13 @@
             meta->setInt32(kKeyRotation, rotationDegrees);
         }
 
-        convertMessageToMetaDataInt32(msg, meta, kKeyMinLuminance, "min-luminance");
-        convertMessageToMetaDataInt32(msg, meta, kKeyMaxLuminance, "max-luminance");
+        if (msg->contains("hdr-static-info")) {
+            HDRStaticInfo info;
+            if (ColorUtils::getHDRStaticInfoFromFormat(msg, &info)) {
+                meta->setData(kKeyHdrStaticInfo, 'hdrS', &info, sizeof(info));
+            }
+        }
+
         convertMessageToMetaDataColorAspects(msg, meta);
     } else if (mime.startsWith("audio/")) {
         int32_t numChannels;
diff --git a/media/libstagefright/avc_utils.cpp b/media/libstagefright/avc_utils.cpp
index 8ef2dca..ccf3440 100644
--- a/media/libstagefright/avc_utils.cpp
+++ b/media/libstagefright/avc_utils.cpp
@@ -41,10 +41,37 @@
     return x + (1u << numZeroes) - 1;
 }
 
+unsigned parseUEWithFallback(ABitReader *br, unsigned fallback) {
+    unsigned numZeroes = 0;
+    while (br->getBitsWithFallback(1, 1) == 0) {
+        ++numZeroes;
+    }
+    uint32_t x;
+    if (numZeroes < 32) {
+        if (br->getBitsGraceful(numZeroes, &x)) {
+            return x + (1u << numZeroes) - 1;
+        } else {
+            return fallback;
+        }
+    } else {
+        br->skipBits(numZeroes);
+        return fallback;
+    }
+}
+
 signed parseSE(ABitReader *br) {
     unsigned codeNum = parseUE(br);
 
-    return (codeNum & 1) ? (codeNum + 1) / 2 : -(codeNum / 2);
+    return (codeNum & 1) ? (codeNum + 1) / 2 : -signed(codeNum / 2);
+}
+
+signed parseSEWithFallback(ABitReader *br, signed fallback) {
+    // NOTE: parseUE cannot normally return ~0 as the max supported value is 0xFFFE
+    unsigned codeNum = parseUEWithFallback(br, ~0U);
+    if (codeNum == ~0U) {
+        return fallback;
+    }
+    return (codeNum & 1) ? (codeNum + 1) / 2 : -signed(codeNum / 2);
 }
 
 static void skipScalingList(ABitReader *br, size_t sizeOfScalingList) {
diff --git a/media/libstagefright/foundation/ABitReader.cpp b/media/libstagefright/foundation/ABitReader.cpp
index 1582b67..c5db9e6 100644
--- a/media/libstagefright/foundation/ABitReader.cpp
+++ b/media/libstagefright/foundation/ABitReader.cpp
@@ -24,14 +24,18 @@
     : mData(data),
       mSize(size),
       mReservoir(0),
-      mNumBitsLeft(0) {
+      mNumBitsLeft(0),
+      mOverRead(false) {
 }
 
 ABitReader::~ABitReader() {
 }
 
-void ABitReader::fillReservoir() {
-    CHECK_GT(mSize, 0u);
+bool ABitReader::fillReservoir() {
+    if (mSize == 0) {
+        mOverRead = true;
+        return false;
+    }
 
     mReservoir = 0;
     size_t i;
@@ -44,15 +48,32 @@
 
     mNumBitsLeft = 8 * i;
     mReservoir <<= 32 - mNumBitsLeft;
+    return true;
 }
 
 uint32_t ABitReader::getBits(size_t n) {
-    CHECK_LE(n, 32u);
+    uint32_t ret;
+    CHECK(getBitsGraceful(n, &ret));
+    return ret;
+}
+
+uint32_t ABitReader::getBitsWithFallback(size_t n, uint32_t fallback) {
+    uint32_t ret = fallback;
+    (void)getBitsGraceful(n, &ret);
+    return ret;
+}
+
+bool ABitReader::getBitsGraceful(size_t n, uint32_t *out) {
+    if (n > 32) {
+        return false;
+    }
 
     uint32_t result = 0;
     while (n > 0) {
         if (mNumBitsLeft == 0) {
-            fillReservoir();
+            if (!fillReservoir()) {
+                return false;
+            }
         }
 
         size_t m = n;
@@ -67,21 +88,30 @@
         n -= m;
     }
 
-    return result;
+    *out = result;
+    return true;
 }
 
-void ABitReader::skipBits(size_t n) {
+bool ABitReader::skipBits(size_t n) {
+    uint32_t dummy;
     while (n > 32) {
-        getBits(32);
+        if (!getBitsGraceful(32, &dummy)) {
+            return false;
+        }
         n -= 32;
     }
 
     if (n > 0) {
-        getBits(n);
+        return getBitsGraceful(n, &dummy);
     }
+    return true;
 }
 
 void ABitReader::putBits(uint32_t x, size_t n) {
+    if (mOverRead) {
+        return;
+    }
+
     CHECK_LE(n, 32u);
 
     while (mNumBitsLeft + n > 32) {
@@ -139,8 +169,11 @@
     return (numBitsRemaining <= 0);
 }
 
-void NALBitReader::fillReservoir() {
-    CHECK_GT(mSize, 0u);
+bool NALBitReader::fillReservoir() {
+    if (mSize == 0) {
+        mOverRead = true;
+        return false;
+    }
 
     mReservoir = 0;
     size_t i = 0;
@@ -165,6 +198,7 @@
 
     mNumBitsLeft = 8 * i;
     mReservoir <<= 32 - mNumBitsLeft;
+    return true;
 }
 
 }  // namespace android
diff --git a/media/libstagefright/include/HevcUtils.h b/media/libstagefright/include/HevcUtils.h
index 0d7bb2f..0f59631 100644
--- a/media/libstagefright/include/HevcUtils.h
+++ b/media/libstagefright/include/HevcUtils.h
@@ -56,10 +56,24 @@
     kBitDepthLumaMinus8,
     // uint8_t
     kBitDepthChromaMinus8,
+    // uint8_t
+    kVideoFullRangeFlag,
+    // uint8_t
+    kColourPrimaries,
+    // uint8_t
+    kTransferCharacteristics,
+    // uint8_t
+    kMatrixCoeffs,
 };
 
 class HevcParameterSets {
 public:
+    enum Info : uint32_t {
+        kInfoNone                = 0,
+        kInfoIsHdr               = 1 << 0,
+        kInfoHasColorDescription = 1 << 1,
+    };
+
     HevcParameterSets();
 
     status_t addNalUnit(const uint8_t* data, size_t size);
@@ -77,6 +91,8 @@
     bool write(size_t index, uint8_t* dest, size_t size);
     status_t makeHvcc(uint8_t *hvcc, size_t *hvccSize, size_t nalSizeLength);
 
+    Info getInfo() const { return mInfo; }
+
 private:
     status_t parseVps(const uint8_t* data, size_t size);
     status_t parseSps(const uint8_t* data, size_t size);
@@ -84,6 +100,7 @@
 
     KeyedVector<uint32_t, uint64_t> mParams;
     Vector<sp<ABuffer>> mNalUnits;
+    Info mInfo;
 
     DISALLOW_EVIL_CONSTRUCTORS(HevcParameterSets);
 };
diff --git a/media/libstagefright/include/avc_utils.h b/media/libstagefright/include/avc_utils.h
index dafa07e..7465b35 100644
--- a/media/libstagefright/include/avc_utils.h
+++ b/media/libstagefright/include/avc_utils.h
@@ -47,8 +47,34 @@
         int32_t *width, int32_t *height,
         int32_t *sarWidth = NULL, int32_t *sarHeight = NULL);
 
+// Gets and returns an unsigned exp-golomb (ue) value from a bit reader |br|. Aborts if the value
+// is more than 64 bits long (>=0xFFFF (!)) or the bit reader overflows.
 unsigned parseUE(ABitReader *br);
 
+// Gets and returns a signed exp-golomb (se) value from a bit reader |br|. Aborts if the value is
+// more than 64 bits long (>0x7FFF || <-0x7FFF (!)) or the bit reader overflows.
+signed parseSE(ABitReader *br);
+
+// Gets an unsigned exp-golomb (ue) value from a bit reader |br|, and returns it if it was
+// successful. Returns |fallback| if it was unsuccessful. Note: if the value was longer that 64
+// bits, it reads past the value and still returns |fallback|.
+unsigned parseUEWithFallback(ABitReader *br, unsigned fallback);
+
+// Gets a signed exp-golomb (se) value from a bit reader |br|, and returns it if it was successful.
+// Returns |fallback| if it was unsuccessful. Note: if the value was longer that 64 bits, it reads
+// past the value and still returns |fallback|.
+signed parseSEWithFallback(ABitReader *br, signed fallback);
+
+// Skips an unsigned exp-golomb (ue) value from bit reader |br|.
+inline void skipUE(ABitReader *br) {
+    (void)parseUEWithFallback(br, 0U);
+}
+
+// Skips a signed exp-golomb (se) value from bit reader |br|.
+inline void skipSE(ABitReader *br) {
+    (void)parseSEWithFallback(br, 0);
+}
+
 status_t getNextNALUnit(
         const uint8_t **_data, size_t *_size,
         const uint8_t **nalStart, size_t *nalSize,
diff --git a/media/libstagefright/matroska/MatroskaExtractor.cpp b/media/libstagefright/matroska/MatroskaExtractor.cpp
index 434be86..383a0ad 100644
--- a/media/libstagefright/matroska/MatroskaExtractor.cpp
+++ b/media/libstagefright/matroska/MatroskaExtractor.cpp
@@ -24,6 +24,7 @@
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/AUtils.h>
 #include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/foundation/ColorUtils.h>
 #include <media/stagefright/foundation/hexdump.h>
 #include <media/stagefright/DataSource.h>
 #include <media/stagefright/MediaBuffer.h>
@@ -1058,6 +1059,109 @@
     return OK;
 }
 
+static inline bool isValidInt32ColourValue(long long value) {
+    return value != mkvparser::Colour::kValueNotPresent
+            && value >= INT32_MIN
+            && value <= INT32_MAX;
+}
+
+static inline bool isValidUint16ColourValue(long long value) {
+    return value != mkvparser::Colour::kValueNotPresent
+            && value >= 0
+            && value <= UINT16_MAX;
+}
+
+static inline bool isValidPrimary(const mkvparser::PrimaryChromaticity *primary) {
+    return primary != NULL && primary->x >= 0 && primary->x <= 1
+             && primary->y >= 0 && primary->y <= 1;
+}
+
+void MatroskaExtractor::getColorInformation(
+        const mkvparser::VideoTrack *vtrack, sp<MetaData> &meta) {
+    const mkvparser::Colour *color = vtrack->GetColour();
+    if (color == NULL) {
+        return;
+    }
+
+    // Color Aspects
+    {
+        int32_t primaries = 2; // ISO unspecified
+        int32_t transfer = 2; // ISO unspecified
+        int32_t coeffs = 2; // ISO unspecified
+        bool fullRange = false; // default
+        bool rangeSpecified = false;
+
+        if (isValidInt32ColourValue(color->primaries)) {
+            primaries = color->primaries;
+        }
+        if (isValidInt32ColourValue(color->transfer_characteristics)) {
+            transfer = color->transfer_characteristics;
+        }
+        if (isValidInt32ColourValue(color->matrix_coefficients)) {
+            coeffs = color->matrix_coefficients;
+        }
+        if (color->range != mkvparser::Colour::kValueNotPresent
+                && color->range != 0 /* MKV unspecified */) {
+            // We only support MKV broadcast range (== limited) and full range.
+            // We treat all other value as the default limited range.
+            fullRange = color->range == 2 /* MKV fullRange */;
+            rangeSpecified = true;
+        }
+
+        ColorAspects aspects;
+        ColorUtils::convertIsoColorAspectsToCodecAspects(
+                primaries, transfer, coeffs, fullRange, aspects);
+        meta->setInt32(kKeyColorPrimaries, aspects.mPrimaries);
+        meta->setInt32(kKeyTransferFunction, aspects.mTransfer);
+        meta->setInt32(kKeyColorMatrix, aspects.mMatrixCoeffs);
+        meta->setInt32(
+                kKeyColorRange, rangeSpecified ? aspects.mRange : ColorAspects::RangeUnspecified);
+    }
+
+    // HDR Static Info
+    {
+        HDRStaticInfo info, nullInfo; // nullInfo is a fully unspecified static info
+        memset(&info, 0, sizeof(info));
+        memset(&nullInfo, 0, sizeof(nullInfo));
+        if (isValidUint16ColourValue(color->max_cll)) {
+            info.sType1.mMaxContentLightLevel = color->max_cll;
+        }
+        if (isValidUint16ColourValue(color->max_fall)) {
+            info.sType1.mMaxFrameAverageLightLevel = color->max_fall;
+        }
+        const mkvparser::MasteringMetadata *mastering = color->mastering_metadata;
+        if (mastering != NULL) {
+            // Convert matroska values to HDRStaticInfo equivalent values for each fully specified
+            // group. See CTA-681.3 section 3.2.1 for more info.
+            if (mastering->luminance_max >= 0.5 && mastering->luminance_max < 65535.5) {
+                info.sType1.mMaxDisplayLuminance = (uint16_t)(mastering->luminance_max + 0.5);
+            }
+            if (mastering->luminance_min >= 0.00005 && mastering->luminance_min < 6.55355) {
+                info.sType1.mMinDisplayLuminance =
+                    (uint16_t)(10000 * mastering->luminance_min + 0.5);
+            }
+            if (isValidPrimary(mastering->white_point)) {
+                info.sType1.mW.x = (uint16_t)(50000 * mastering->white_point->x + 0.5);
+                info.sType1.mW.y = (uint16_t)(50000 * mastering->white_point->y + 0.5);
+            }
+            if (isValidPrimary(mastering->r) && isValidPrimary(mastering->g)
+                    && isValidPrimary(mastering->b)) {
+                info.sType1.mR.x = (uint16_t)(50000 * mastering->r->x + 0.5);
+                info.sType1.mR.y = (uint16_t)(50000 * mastering->r->y + 0.5);
+                info.sType1.mG.x = (uint16_t)(50000 * mastering->g->x + 0.5);
+                info.sType1.mG.y = (uint16_t)(50000 * mastering->g->y + 0.5);
+                info.sType1.mB.x = (uint16_t)(50000 * mastering->b->x + 0.5);
+                info.sType1.mB.y = (uint16_t)(50000 * mastering->b->y + 0.5);
+            }
+        }
+        // Only advertise static info if at least one of the groups have been specified.
+        if (memcmp(&info, &nullInfo, sizeof(info)) != 0) {
+            info.mID = HDRStaticInfo::kType1;
+            meta->setData(kKeyHdrStaticInfo, 'hdrS', &info, sizeof(info));
+        }
+    }
+}
+
 void MatroskaExtractor::addTracks() {
     const mkvparser::Tracks *tracks = mSegment->GetTracks();
 
@@ -1127,6 +1231,9 @@
 
                 meta->setInt32(kKeyWidth, vtrack->GetWidth());
                 meta->setInt32(kKeyHeight, vtrack->GetHeight());
+
+                getColorInformation(vtrack, meta);
+
                 break;
             }
 
diff --git a/media/libstagefright/matroska/MatroskaExtractor.h b/media/libstagefright/matroska/MatroskaExtractor.h
index 9406829..665e68e 100644
--- a/media/libstagefright/matroska/MatroskaExtractor.h
+++ b/media/libstagefright/matroska/MatroskaExtractor.h
@@ -29,6 +29,7 @@
 struct AMessage;
 class String8;
 
+class MetaData;
 struct DataSourceReader;
 struct MatroskaSource;
 
@@ -80,7 +81,7 @@
     status_t synthesizeAVCC(TrackInfo *trackInfo, size_t index);
     void addTracks();
     void findThumbnails();
-
+    void getColorInformation(const mkvparser::VideoTrack *vtrack, sp<MetaData> &meta);
     bool isLiveStreaming() const;
 
     MatroskaExtractor(const MatroskaExtractor &);
diff --git a/media/libstagefright/webm/WebmConstants.h b/media/libstagefright/webm/WebmConstants.h
index c53f458..cf6404f 100644
--- a/media/libstagefright/webm/WebmConstants.h
+++ b/media/libstagefright/webm/WebmConstants.h
@@ -98,6 +98,24 @@
     kMkvDisplayHeight = 0x54BA,
     kMkvDisplayUnit = 0x54B2,
     kMkvAspectRatioType = 0x54B3,
+    kMkvColour = 0x55B0,
+    kMkvColourMatrixCoefficients = 0x55B1,
+    kMkvColourRange = 0x55B9,
+    kMkvColourTransferCharacteristics = 0x55BA,
+    kMkvColourPrimaries = 0x55BB,
+    kMkvColourMaxCll = 0x55BC,
+    kMkvColourMaxFall = 0x55BD,
+    kMkvMasteringMetadata = 0x55D0,
+    kMkvMasteringPrimaryRChromaticityX = 0x55D1,
+    kMkvMasteringPrimaryRChromaticityY = 0x55D2,
+    kMkvMasteringPrimaryGChromaticityX = 0x55D3,
+    kMkvMasteringPrimaryGChromaticityY = 0x55D4,
+    kMkvMasteringPrimaryBChromaticityX = 0x55D5,
+    kMkvMasteringPrimaryBChromaticityY = 0x55D6,
+    kMkvMasteringWhitePointChromaticityX = 0x55D7,
+    kMkvMasteringWhitePointChromaticityY = 0x55D8,
+    kMkvMasteringLuminanceMax = 0x55D9,
+    kMkvMasteringLuminanceMin = 0x55DA,
     kMkvFrameRate = 0x2383E3,
     kMkvAudio = 0xE1,
     kMkvSamplingFrequency = 0xB5,
diff --git a/media/libstagefright/webm/WebmElement.cpp b/media/libstagefright/webm/WebmElement.cpp
index f454bf6..6a7da12 100644
--- a/media/libstagefright/webm/WebmElement.cpp
+++ b/media/libstagefright/webm/WebmElement.cpp
@@ -22,6 +22,8 @@
 #include "WebmConstants.h"
 
 #include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/ColorUtils.h>
+#include <media/stagefright/MetaData.h>
 #include <utils/Log.h>
 
 #include <string.h>
@@ -341,6 +343,7 @@
         const char *codec,
         uint64_t width,
         uint64_t height,
+        const sp<MetaData> &meta,
         uint64_t uid,
         bool lacing,
         const char *lang) {
@@ -362,6 +365,97 @@
     videoInfo.push_back(new WebmUnsigned(kMkvPixelWidth, width));
     videoInfo.push_back(new WebmUnsigned(kMkvPixelHeight, height));
 
+    // Color aspects
+    {
+        List<sp<WebmElement> > colorInfo;
+
+        ColorAspects aspects;
+        aspects.mPrimaries = ColorAspects::PrimariesUnspecified;
+        aspects.mTransfer = ColorAspects::TransferUnspecified;
+        aspects.mMatrixCoeffs = ColorAspects::MatrixUnspecified;
+        aspects.mRange = ColorAspects::RangeUnspecified;
+        bool havePrimaries = meta->findInt32(kKeyColorPrimaries, (int32_t*)&aspects.mPrimaries);
+        bool haveTransfer = meta->findInt32(kKeyTransferFunction, (int32_t*)&aspects.mTransfer);
+        bool haveCoeffs = meta->findInt32(kKeyColorMatrix, (int32_t*)&aspects.mMatrixCoeffs);
+        bool haveRange = meta->findInt32(kKeyColorRange, (int32_t*)&aspects.mRange);
+
+        int32_t primaries, transfer, coeffs;
+        bool fullRange;
+        ColorUtils::convertCodecColorAspectsToIsoAspects(
+                aspects, &primaries, &transfer, &coeffs, &fullRange);
+        if (havePrimaries) {
+            colorInfo.push_back(new WebmUnsigned(kMkvColourPrimaries, primaries));
+        }
+        if (haveTransfer) {
+            colorInfo.push_back(new WebmUnsigned(kMkvColourTransferCharacteristics, transfer));
+        }
+        if (haveCoeffs) {
+            colorInfo.push_back(new WebmUnsigned(kMkvColourMatrixCoefficients, coeffs));
+        }
+        if (haveRange) {
+            colorInfo.push_back(new WebmUnsigned(kMkvColourRange, fullRange ? 2 : 1));
+        }
+
+        // Also add HDR static info, some of which goes to MasteringMetadata element
+
+        const HDRStaticInfo *info;
+        uint32_t type;
+        const void *data;
+        size_t size;
+        if (meta->findData(kKeyHdrStaticInfo, &type, &data, &size)
+                && type == 'hdrS' && size == sizeof(*info)) {
+            info = (const HDRStaticInfo*)data;
+            if (info->mID == HDRStaticInfo::kType1) {
+                List<sp<WebmElement> > masteringInfo;
+
+                // convert HDRStaticInfo values to matroska equivalent values for each non-0 group
+                if (info->sType1.mMaxFrameAverageLightLevel) {
+                    colorInfo.push_back(new WebmUnsigned(
+                            kMkvColourMaxFall, info->sType1.mMaxFrameAverageLightLevel));
+                }
+                if (info->sType1.mMaxContentLightLevel) {
+                    colorInfo.push_back(new WebmUnsigned(
+                            kMkvColourMaxCll, info->sType1.mMaxContentLightLevel));
+                }
+                if (info->sType1.mMinDisplayLuminance) {
+                    masteringInfo.push_back(new WebmFloat(
+                            kMkvMasteringLuminanceMin, info->sType1.mMinDisplayLuminance * 0.0001));
+                }
+                if (info->sType1.mMaxDisplayLuminance) {
+                    masteringInfo.push_back(new WebmFloat(
+                            kMkvMasteringLuminanceMax, (float)info->sType1.mMaxDisplayLuminance));
+                }
+                if (info->sType1.mW.x || info->sType1.mW.y) {
+                    masteringInfo.push_back(new WebmFloat(
+                            kMkvMasteringWhitePointChromaticityX, info->sType1.mW.x * 0.00002));
+                    masteringInfo.push_back(new WebmFloat(
+                            kMkvMasteringWhitePointChromaticityY, info->sType1.mW.y * 0.00002));
+                }
+                if (info->sType1.mR.x || info->sType1.mR.x || info->sType1.mG.x
+                        || info->sType1.mG.y || info->sType1.mB.x || info->sType1.mB.y) {
+                    masteringInfo.push_back(new WebmFloat(
+                            kMkvMasteringPrimaryRChromaticityX, info->sType1.mR.x * 0.00002));
+                    masteringInfo.push_back(new WebmFloat(
+                            kMkvMasteringPrimaryRChromaticityY, info->sType1.mR.y * 0.00002));
+                    masteringInfo.push_back(new WebmFloat(
+                            kMkvMasteringPrimaryGChromaticityX, info->sType1.mG.x * 0.00002));
+                    masteringInfo.push_back(new WebmFloat(
+                            kMkvMasteringPrimaryGChromaticityY, info->sType1.mG.y * 0.00002));
+                    masteringInfo.push_back(new WebmFloat(
+                            kMkvMasteringPrimaryBChromaticityX, info->sType1.mB.x * 0.00002));
+                    masteringInfo.push_back(new WebmFloat(
+                            kMkvMasteringPrimaryBChromaticityY, info->sType1.mB.y * 0.00002));
+                }
+                if (masteringInfo.size()) {
+                    colorInfo.push_back(new WebmMaster(kMkvMasteringMetadata, masteringInfo));
+                }
+            }
+        }
+        if (colorInfo.size()) {
+            videoInfo.push_back(new WebmMaster(kMkvColour, colorInfo));
+        }
+    }
+
     trackEntryFields.push_back(new WebmMaster(kMkvVideo, videoInfo));
     return new WebmMaster(kMkvTrackEntry, trackEntryFields);
 }
diff --git a/media/libstagefright/webm/WebmElement.h b/media/libstagefright/webm/WebmElement.h
index 456c3c7..4e90793 100644
--- a/media/libstagefright/webm/WebmElement.h
+++ b/media/libstagefright/webm/WebmElement.h
@@ -24,6 +24,8 @@
 
 namespace android {
 
+class MetaData;
+
 struct WebmElement : public LightRefBase<WebmElement> {
     const uint64_t mId, mSize;
 
@@ -60,6 +62,7 @@
             const char *codec,
             uint64_t width,
             uint64_t height,
+            const sp<MetaData> &md,
             uint64_t uid = 0,
             bool lacing = false,
             const char *lang = "und");
diff --git a/media/libstagefright/webm/WebmWriter.cpp b/media/libstagefright/webm/WebmWriter.cpp
index 511260a..a1ac253 100644
--- a/media/libstagefright/webm/WebmWriter.cpp
+++ b/media/libstagefright/webm/WebmWriter.cpp
@@ -101,7 +101,7 @@
     } else {
         CHECK(!"Unsupported codec");
     }
-    return WebmElement::VideoTrackEntry(codec, width, height);
+    return WebmElement::VideoTrackEntry(codec, width, height, md);
 }
 
 // static
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 2b0d4c8..d2fee81 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -58,7 +58,7 @@
 #include <powermanager/PowerManager.h>
 
 #include <media/IMediaLogService.h>
-
+#include <media/MemoryLeakTrackUtil.h>
 #include <media/nbaio/Pipe.h>
 #include <media/nbaio/PipeReader.h>
 #include <media/AudioParameter.h>
@@ -471,17 +471,25 @@
         }
 
         // check for optional arguments
+        bool dumpMem = false;
         bool unreachableMemory = false;
         for (const auto &arg : args) {
-            if (arg == String16("--unreachable")) {
+            if (arg == String16("-m")) {
+                dumpMem = true;
+            } else if (arg == String16("--unreachable")) {
                 unreachableMemory = true;
             }
         }
 
+        if (dumpMem) {
+            dprintf(fd, "\nDumping memory:\n");
+            std::string s = dumpMemoryAddresses(100 /* limit */);
+            write(fd, s.c_str(), s.size());
+        }
         if (unreachableMemory) {
             dprintf(fd, "\nDumping unreachable memory:\n");
             // TODO - should limit be an argument parameter?
-            std::string s = GetUnreachableMemoryString(true /* contents */, 10000 /* limit */);
+            std::string s = GetUnreachableMemoryString(true /* contents */, 100 /* limit */);
             write(fd, s.c_str(), s.size());
         }
     }
@@ -571,6 +579,7 @@
         IAudioFlinger::track_flags_t *flags,
         const sp<IMemory>& sharedBuffer,
         audio_io_handle_t output,
+        pid_t pid,
         pid_t tid,
         audio_session_t *sessionId,
         int clientUid,
@@ -582,6 +591,15 @@
     status_t lStatus;
     audio_session_t lSessionId;
 
+    const uid_t callingUid = IPCThreadState::self()->getCallingUid();
+    if (pid == -1 || !isTrustedCallingUid(callingUid)) {
+        const pid_t callingPid = IPCThreadState::self()->getCallingPid();
+        ALOGW_IF(pid != -1 && pid != callingPid,
+                 "%s uid %d pid %d tried to pass itself off as pid %d",
+                 __func__, callingUid, callingPid, pid);
+        pid = callingPid;
+    }
+
     // client AudioTrack::set already implements AUDIO_STREAM_DEFAULT => AUDIO_STREAM_MUSIC,
     // but if someone uses binder directly they could bypass that and cause us to crash
     if (uint32_t(streamType) >= AUDIO_STREAM_CNT) {
@@ -626,7 +644,6 @@
             goto Exit;
         }
 
-        pid_t pid = IPCThreadState::self()->getCallingPid();
         client = registerPid(pid);
 
         PlaybackThread *effectThread = NULL;
@@ -1447,6 +1464,7 @@
         const String16& opPackageName,
         size_t *frameCount,
         IAudioFlinger::track_flags_t *flags,
+        pid_t pid,
         pid_t tid,
         int clientUid,
         audio_session_t *sessionId,
@@ -1464,11 +1482,21 @@
     cblk.clear();
     buffers.clear();
 
+    bool updatePid = (pid == -1);
     const uid_t callingUid = IPCThreadState::self()->getCallingUid();
     if (!isTrustedCallingUid(callingUid)) {
         ALOGW_IF((uid_t)clientUid != callingUid,
                 "%s uid %d tried to pass itself off as %d", __FUNCTION__, callingUid, clientUid);
         clientUid = callingUid;
+        updatePid = true;
+    }
+
+    if (updatePid) {
+        const pid_t callingPid = IPCThreadState::self()->getCallingPid();
+        ALOGW_IF(pid != -1 && pid != callingPid,
+                 "%s uid %d pid %d tried to pass itself off as pid %d",
+                 __func__, callingUid, callingPid, pid);
+        pid = callingPid;
     }
 
     // check calling permissions
@@ -1508,7 +1536,6 @@
             goto Exit;
         }
 
-        pid_t pid = IPCThreadState::self()->getCallingPid();
         client = registerPid(pid);
 
         if (sessionId != NULL && *sessionId != AUDIO_SESSION_ALLOCATE) {
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 96d38d0..59ad688 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -107,6 +107,7 @@
                                 IAudioFlinger::track_flags_t *flags,
                                 const sp<IMemory>& sharedBuffer,
                                 audio_io_handle_t output,
+                                pid_t pid,
                                 pid_t tid,
                                 audio_session_t *sessionId,
                                 int clientUid,
@@ -120,6 +121,7 @@
                                 const String16& opPackageName,
                                 size_t *pFrameCount,
                                 IAudioFlinger::track_flags_t *flags,
+                                pid_t pid,
                                 pid_t tid,
                                 int clientUid,
                                 audio_session_t *sessionId,
diff --git a/services/audioflinger/PatchPanel.cpp b/services/audioflinger/PatchPanel.cpp
index 89de68e..f8671b5 100644
--- a/services/audioflinger/PatchPanel.cpp
+++ b/services/audioflinger/PatchPanel.cpp
@@ -168,6 +168,12 @@
                 ALOGV("createAudioPatch() removing patch handle %d", *handle);
                 halHandle = mPatches[index]->mHalHandle;
                 Patch *removedPatch = mPatches[index];
+                if ((removedPatch->mRecordPatchHandle
+                        != AUDIO_PATCH_HANDLE_NONE) ||
+                        (removedPatch->mPlaybackPatchHandle !=
+                                AUDIO_PATCH_HANDLE_NONE)) {
+                    clearPatchConnections(removedPatch);
+                }
                 mPatches.removeAt(index);
                 delete removedPatch;
                 break;
diff --git a/services/audioflinger/ServiceUtilities.cpp b/services/audioflinger/ServiceUtilities.cpp
index afc2440..3c73543 100644
--- a/services/audioflinger/ServiceUtilities.cpp
+++ b/services/audioflinger/ServiceUtilities.cpp
@@ -105,11 +105,10 @@
     return true;
 }
 
-bool captureAudioOutputAllowed() {
+bool captureAudioOutputAllowed(pid_t pid, uid_t uid) {
     if (getpid_cached == IPCThreadState::self()->getCallingPid()) return true;
     static const String16 sCaptureAudioOutput("android.permission.CAPTURE_AUDIO_OUTPUT");
-    // IMPORTANT: Use PermissionCache - not a runtime permission and may not change.
-    bool ok = PermissionCache::checkCallingPermission(sCaptureAudioOutput);
+    bool ok = checkPermission(sCaptureAudioOutput, pid, uid);
     if (!ok) ALOGE("Request requires android.permission.CAPTURE_AUDIO_OUTPUT");
     return ok;
 }
diff --git a/services/audioflinger/ServiceUtilities.h b/services/audioflinger/ServiceUtilities.h
index 1e79553..8b1bc00 100644
--- a/services/audioflinger/ServiceUtilities.h
+++ b/services/audioflinger/ServiceUtilities.h
@@ -21,7 +21,7 @@
 extern pid_t getpid_cached;
 bool isTrustedCallingUid(uid_t uid);
 bool recordingAllowed(const String16& opPackageName, pid_t pid, uid_t uid);
-bool captureAudioOutputAllowed();
+bool captureAudioOutputAllowed(pid_t pid, uid_t uid);
 bool captureHotwordAllowed();
 bool settingsAllowed();
 bool modifyAudioRoutingAllowed();
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 9fe61702..3759424 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -1576,7 +1576,7 @@
         mActiveTracksGeneration(0),
         // mStreamTypes[] initialized in constructor body
         mOutput(output),
-        mLastWriteTime(0), mNumWrites(0), mNumDelayedWrites(0), mInWrite(false),
+        mLastWriteTime(-1), mNumWrites(0), mNumDelayedWrites(0), mInWrite(false),
         mMixerStatus(MIXER_IDLE),
         mMixerStatusIgnoringFastTracks(MIXER_IDLE),
         mStandbyDelayNs(AudioFlinger::mStandbyTimeInNsecs),
@@ -2537,8 +2537,6 @@
 // shared by MIXER and DIRECT, overridden by DUPLICATING
 ssize_t AudioFlinger::PlaybackThread::threadLoop_write()
 {
-    // FIXME rewrite to reduce number of system calls
-    mLastWriteTime = systemTime();
     mInWrite = true;
     ssize_t bytesWritten;
     const size_t offset = mCurrentWriteLength - mBytesRemaining;
@@ -2834,6 +2832,8 @@
     Vector< sp<Track> > tracksToRemove;
 
     mStandbyTimeNs = systemTime();
+    nsecs_t lastWriteFinished = -1; // time last server write completed
+    int64_t lastFramesWritten = -1; // track changes in timestamp server frames written
 
     // MIXER
     nsecs_t lastWarning = 0;
@@ -2884,10 +2884,11 @@
             // Gather the framesReleased counters for all active tracks,
             // and associate with the sink frames written out.  We need
             // this to convert the sink timestamp to the track timestamp.
+            bool kernelLocationUpdate = false;
             if (mNormalSink != 0) {
                 // Note: The DuplicatingThread may not have a mNormalSink.
                 // We always fetch the timestamp here because often the downstream
-                // sink will block whie writing.
+                // sink will block while writing.
                 ExtendedTimestamp timestamp; // use private copy to fetch
                 (void) mNormalSink->getTimestamp(timestamp);
 
@@ -2904,6 +2905,10 @@
                             mTimestamp.mPosition[ExtendedTimestamp::LOCATION_SERVER];
                     mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_SERVER_LASTKERNELOK] =
                             mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_SERVER];
+                }
+
+                if (timestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL] >= 0) {
+                    kernelLocationUpdate = true;
                 } else {
                     ALOGV("getTimestamp error - no valid kernel position");
                 }
@@ -2917,16 +2922,33 @@
             // mFramesWritten for non-offloaded tracks are contiguous
             // even after standby() is called. This is useful for the track frame
             // to sink frame mapping.
-            mTimestamp.mPosition[ExtendedTimestamp::LOCATION_SERVER] = mFramesWritten;
-            mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_SERVER] = systemTime();
-            const size_t size = mActiveTracks.size();
-            for (size_t i = 0; i < size; ++i) {
-                sp<Track> t = mActiveTracks[i].promote();
-                if (t != 0 && !t->isFastTrack()) {
-                    t->updateTrackFrameInfo(
-                            t->mAudioTrackServerProxy->framesReleased(),
-                            mFramesWritten,
-                            mTimestamp);
+            bool serverLocationUpdate = false;
+            if (mFramesWritten != lastFramesWritten) {
+                serverLocationUpdate = true;
+                lastFramesWritten = mFramesWritten;
+            }
+            // Only update timestamps if there is a meaningful change.
+            // Either the kernel timestamp must be valid or we have written something.
+            if (kernelLocationUpdate || serverLocationUpdate) {
+                if (serverLocationUpdate) {
+                    // use the time before we called the HAL write - it is a bit more accurate
+                    // to when the server last read data than the current time here.
+                    //
+                    // If we haven't written anything, mLastWriteTime will be -1
+                    // and we use systemTime().
+                    mTimestamp.mPosition[ExtendedTimestamp::LOCATION_SERVER] = mFramesWritten;
+                    mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_SERVER] = mLastWriteTime == -1
+                            ? systemTime() : mLastWriteTime;
+                }
+                const size_t size = mActiveTracks.size();
+                for (size_t i = 0; i < size; ++i) {
+                    sp<Track> t = mActiveTracks[i].promote();
+                    if (t != 0 && !t->isFastTrack()) {
+                        t->updateTrackFrameInfo(
+                                t->mAudioTrackServerProxy->framesReleased(),
+                                mFramesWritten,
+                                mTimestamp);
+                    }
                 }
             }
 
@@ -3104,8 +3126,17 @@
             // mSleepTimeUs == 0 means we must write to audio hardware
             if (mSleepTimeUs == 0) {
                 ssize_t ret = 0;
+                // We save lastWriteFinished here, as previousLastWriteFinished,
+                // for throttling. On thread start, previousLastWriteFinished will be
+                // set to -1, which properly results in no throttling after the first write.
+                nsecs_t previousLastWriteFinished = lastWriteFinished;
+                nsecs_t delta = 0;
                 if (mBytesRemaining) {
+                    // FIXME rewrite to reduce number of system calls
+                    mLastWriteTime = systemTime();  // also used for dumpsys
                     ret = threadLoop_write();
+                    lastWriteFinished = systemTime();
+                    delta = lastWriteFinished - mLastWriteTime;
                     if (ret < 0) {
                         mBytesRemaining = 0;
                     } else {
@@ -3119,15 +3150,13 @@
                 }
                 if (mType == MIXER && !mStandby) {
                     // write blocked detection
-                    nsecs_t now = systemTime();
-                    nsecs_t delta = now - mLastWriteTime;
                     if (delta > maxPeriod) {
                         mNumDelayedWrites++;
-                        if ((now - lastWarning) > kWarningThrottleNs) {
+                        if ((lastWriteFinished - lastWarning) > kWarningThrottleNs) {
                             ATRACE_NAME("underrun");
                             ALOGW("write blocked for %llu msecs, %d delayed writes, thread %p",
                                     (unsigned long long) ns2ms(delta), mNumDelayedWrites, this);
-                            lastWarning = now;
+                            lastWarning = lastWriteFinished;
                         }
                     }
 
@@ -3147,7 +3176,9 @@
                         // (2) minimum buffer sized tracks (even if the track is full,
                         //     the app won't fill fast enough to handle the sudden draw).
 
-                        const int32_t deltaMs = delta / 1000000;
+                        // it's OK if deltaMs is an overestimate.
+                        const int32_t deltaMs =
+                                (lastWriteFinished - previousLastWriteFinished) / 1000000;
                         const int32_t throttleMs = mHalfBufferMs - deltaMs;
                         if ((signed)mHalfBufferMs >= throttleMs && throttleMs > 0) {
                             usleep(throttleMs * 1000);
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/example/Android.mk b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Android.mk
similarity index 62%
rename from services/audiopolicy/engineconfigurable/parameter-framework/example/Android.mk
rename to services/audiopolicy/engineconfigurable/parameter-framework/examples/Android.mk
index 5775556..baaefd2 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/example/Android.mk
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Android.mk
@@ -107,4 +107,56 @@
 include $(BUILD_PREBUILT)
 endif # pfw_rebuild_settings
 
+######### Policy PFW Settings - No Output #########
+include $(CLEAR_VARS)
+LOCAL_MODULE := parameter-framework.policy.no-output
+LOCAL_MODULE_STEM := PolicyConfigurableDomains-NoOutputDevice.xml
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Settings/Policy
+LOCAL_ADDITIONAL_DEPENDENCIES := \
+        PolicyClass.xml \
+        PolicySubsystem.xml \
+        ParameterFrameworkConfigurationPolicy.xml
+
+PFW_TOPLEVEL_FILE := $(TARGET_OUT_ETC)/parameter-framework/ParameterFrameworkConfigurationPolicy.xml
+PFW_CRITERIA_FILE := $(LOCAL_PATH)/policy_criteria.txt
+PFW_EDD_FILES := \
+        $(LOCAL_PATH)/SettingsNoOutput/device_for_strategies.pfw \
+        $(LOCAL_PATH)/Settings/strategy_for_stream.pfw \
+        $(LOCAL_PATH)/Settings/strategy_for_usage.pfw \
+        $(LOCAL_PATH)/Settings/device_for_input_source.pfw \
+        $(LOCAL_PATH)/Settings/volumes.pfw
+
+include $(BUILD_PFW_SETTINGS)
+
+######### Policy PFW Settings - No Input #########
+include $(CLEAR_VARS)
+LOCAL_MODULE := parameter-framework.policy.no-input
+LOCAL_MODULE_STEM := PolicyConfigurableDomains-NoInputDevice.xml
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Settings/Policy
+LOCAL_ADDITIONAL_DEPENDENCIES := \
+        PolicyClass.xml \
+        PolicySubsystem.xml \
+        ParameterFrameworkConfigurationPolicy.xml
+
+PFW_TOPLEVEL_FILE := $(TARGET_OUT_ETC)/parameter-framework/ParameterFrameworkConfigurationPolicy.xml
+PFW_CRITERIA_FILE := $(LOCAL_PATH)/policy_criteria.txt
+PFW_EDD_FILES := \
+        $(LOCAL_PATH)/Settings/device_for_strategy_media.pfw \
+        $(LOCAL_PATH)/Settings/device_for_strategy_phone.pfw \
+        $(LOCAL_PATH)/Settings/device_for_strategy_sonification.pfw \
+        $(LOCAL_PATH)/Settings/device_for_strategy_sonification_respectful.pfw \
+        $(LOCAL_PATH)/Settings/device_for_strategy_dtmf.pfw \
+        $(LOCAL_PATH)/Settings/device_for_strategy_enforced_audible.pfw \
+        $(LOCAL_PATH)/Settings/device_for_strategy_transmitted_through_speaker.pfw \
+        $(LOCAL_PATH)/Settings/device_for_strategy_accessibility.pfw \
+        $(LOCAL_PATH)/Settings/device_for_strategy_rerouting.pfw \
+        $(LOCAL_PATH)/Settings/strategy_for_stream.pfw \
+        $(LOCAL_PATH)/Settings/strategy_for_usage.pfw \
+        $(LOCAL_PATH)/SettingsNoInput/device_for_input_source.pfw \
+        $(LOCAL_PATH)/Settings/volumes.pfw
+
+include $(BUILD_PFW_SETTINGS)
+
 endif # ifeq (1, 0)
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/example/ParameterFrameworkConfigurationPolicy.xml.in b/services/audiopolicy/engineconfigurable/parameter-framework/examples/ParameterFrameworkConfigurationPolicy.xml.in
similarity index 100%
rename from services/audiopolicy/engineconfigurable/parameter-framework/example/ParameterFrameworkConfigurationPolicy.xml.in
rename to services/audiopolicy/engineconfigurable/parameter-framework/examples/ParameterFrameworkConfigurationPolicy.xml.in
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/example/README.md b/services/audiopolicy/engineconfigurable/parameter-framework/examples/README.md
similarity index 100%
rename from services/audiopolicy/engineconfigurable/parameter-framework/example/README.md
rename to services/audiopolicy/engineconfigurable/parameter-framework/examples/README.md
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/PolicyConfigurableDomains.xml b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/PolicyConfigurableDomains.xml
similarity index 96%
rename from services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/PolicyConfigurableDomains.xml
rename to services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/PolicyConfigurableDomains.xml
index bc7ad6b..aa2af0f 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/PolicyConfigurableDomains.xml
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/PolicyConfigurableDomains.xml
@@ -15,6 +15,9 @@
       <ConfigurableElement Path="/Policy/policy/strategies/media/selected_output_devices/mask/bluetooth_sco_headset"/>
       <ConfigurableElement Path="/Policy/policy/strategies/media/selected_output_devices/mask/bluetooth_sco_carkit"/>
       <ConfigurableElement Path="/Policy/policy/strategies/media/selected_output_devices/mask/telephony_tx"/>
+      <ConfigurableElement Path="/Policy/policy/strategies/media/selected_output_devices/mask/ip"/>
+      <ConfigurableElement Path="/Policy/policy/strategies/media/selected_output_devices/mask/bus"/>
+      <ConfigurableElement Path="/Policy/policy/strategies/media/selected_output_devices/mask/stub"/>
     </ConfigurableElements>
     <Settings>
       <Configuration Name="Calibration">
@@ -39,6 +42,15 @@
         <ConfigurableElement Path="/Policy/policy/strategies/media/selected_output_devices/mask/telephony_tx">
           <BitParameter Name="telephony_tx">0</BitParameter>
         </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/media/selected_output_devices/mask/ip">
+          <BitParameter Name="ip">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/media/selected_output_devices/mask/bus">
+          <BitParameter Name="bus">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/media/selected_output_devices/mask/stub">
+          <BitParameter Name="stub">0</BitParameter>
+        </ConfigurableElement>
       </Configuration>
     </Settings>
   </ConfigurableDomain>
@@ -856,6 +868,9 @@
       <ConfigurableElement Path="/Policy/policy/strategies/phone/selected_output_devices/mask/spdif"/>
       <ConfigurableElement Path="/Policy/policy/strategies/phone/selected_output_devices/mask/fm"/>
       <ConfigurableElement Path="/Policy/policy/strategies/phone/selected_output_devices/mask/speaker_safe"/>
+      <ConfigurableElement Path="/Policy/policy/strategies/phone/selected_output_devices/mask/ip"/>
+      <ConfigurableElement Path="/Policy/policy/strategies/phone/selected_output_devices/mask/bus"/>
+      <ConfigurableElement Path="/Policy/policy/strategies/phone/selected_output_devices/mask/stub"/>
     </ConfigurableElements>
     <Settings>
       <Configuration Name="Calibration">
@@ -877,6 +892,15 @@
         <ConfigurableElement Path="/Policy/policy/strategies/phone/selected_output_devices/mask/speaker_safe">
           <BitParameter Name="speaker_safe">0</BitParameter>
         </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/phone/selected_output_devices/mask/ip">
+          <BitParameter Name="ip">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/phone/selected_output_devices/mask/bus">
+          <BitParameter Name="bus">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/phone/selected_output_devices/mask/stub">
+          <BitParameter Name="stub">0</BitParameter>
+        </ConfigurableElement>
       </Configuration>
     </Settings>
   </ConfigurableDomain>
@@ -1941,6 +1965,9 @@
       <ConfigurableElement Path="/Policy/policy/strategies/sonification/selected_output_devices/mask/speaker_safe"/>
       <ConfigurableElement Path="/Policy/policy/strategies/sonification/selected_output_devices/mask/aux_line"/>
       <ConfigurableElement Path="/Policy/policy/strategies/sonification/selected_output_devices/mask/hdmi"/>
+      <ConfigurableElement Path="/Policy/policy/strategies/sonification/selected_output_devices/mask/ip"/>
+      <ConfigurableElement Path="/Policy/policy/strategies/sonification/selected_output_devices/mask/bus"/>
+      <ConfigurableElement Path="/Policy/policy/strategies/sonification/selected_output_devices/mask/stub"/>
     </ConfigurableElements>
     <Settings>
       <Configuration Name="Calibration">
@@ -1965,6 +1992,15 @@
         <ConfigurableElement Path="/Policy/policy/strategies/sonification/selected_output_devices/mask/hdmi">
           <BitParameter Name="hdmi">0</BitParameter>
         </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/sonification/selected_output_devices/mask/ip">
+          <BitParameter Name="ip">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/sonification/selected_output_devices/mask/bus">
+          <BitParameter Name="bus">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/sonification/selected_output_devices/mask/stub">
+          <BitParameter Name="stub">0</BitParameter>
+        </ConfigurableElement>
       </Configuration>
     </Settings>
   </ConfigurableDomain>
@@ -2920,6 +2956,9 @@
       <ConfigurableElement Path="/Policy/policy/strategies/sonification_respectful/selected_output_devices/mask/spdif"/>
       <ConfigurableElement Path="/Policy/policy/strategies/sonification_respectful/selected_output_devices/mask/fm"/>
       <ConfigurableElement Path="/Policy/policy/strategies/sonification_respectful/selected_output_devices/mask/telephony_tx"/>
+      <ConfigurableElement Path="/Policy/policy/strategies/sonification_respectful/selected_output_devices/mask/ip"/>
+      <ConfigurableElement Path="/Policy/policy/strategies/sonification_respectful/selected_output_devices/mask/bus"/>
+      <ConfigurableElement Path="/Policy/policy/strategies/sonification_respectful/selected_output_devices/mask/stub"/>
     </ConfigurableElements>
     <Settings>
       <Configuration Name="Calibration">
@@ -2941,6 +2980,15 @@
         <ConfigurableElement Path="/Policy/policy/strategies/sonification_respectful/selected_output_devices/mask/telephony_tx">
           <BitParameter Name="telephony_tx">0</BitParameter>
         </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/sonification_respectful/selected_output_devices/mask/ip">
+          <BitParameter Name="ip">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/sonification_respectful/selected_output_devices/mask/bus">
+          <BitParameter Name="bus">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/sonification_respectful/selected_output_devices/mask/stub">
+          <BitParameter Name="stub">0</BitParameter>
+        </ConfigurableElement>
       </Configuration>
     </Settings>
   </ConfigurableDomain>
@@ -3922,6 +3970,9 @@
       <ConfigurableElement Path="/Policy/policy/strategies/dtmf/selected_output_devices/mask/fm"/>
       <ConfigurableElement Path="/Policy/policy/strategies/dtmf/selected_output_devices/mask/speaker_safe"/>
       <ConfigurableElement Path="/Policy/policy/strategies/dtmf/selected_output_devices/mask/bluetooth_sco_carkit"/>
+      <ConfigurableElement Path="/Policy/policy/strategies/dtmf/selected_output_devices/mask/ip"/>
+      <ConfigurableElement Path="/Policy/policy/strategies/dtmf/selected_output_devices/mask/bus"/>
+      <ConfigurableElement Path="/Policy/policy/strategies/dtmf/selected_output_devices/mask/stub"/>
     </ConfigurableElements>
     <Settings>
       <Configuration Name="Calibration">
@@ -3934,6 +3985,15 @@
         <ConfigurableElement Path="/Policy/policy/strategies/dtmf/selected_output_devices/mask/bluetooth_sco_carkit">
           <BitParameter Name="bluetooth_sco_carkit">0</BitParameter>
         </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/dtmf/selected_output_devices/mask/ip">
+          <BitParameter Name="ip">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/dtmf/selected_output_devices/mask/bus">
+          <BitParameter Name="bus">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/dtmf/selected_output_devices/mask/stub">
+          <BitParameter Name="stub">0</BitParameter>
+        </ConfigurableElement>
       </Configuration>
     </Settings>
   </ConfigurableDomain>
@@ -5210,6 +5270,10 @@
       <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/spdif"/>
       <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/aux_line"/>
       <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/speaker_safe"/>
+      <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/ip"/>
+      <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/bus"/>
+      <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/fm"/>
+      <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/stub"/>
     </ConfigurableElements>
     <Settings>
       <Configuration Name="Calibration">
@@ -5225,6 +5289,18 @@
         <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/speaker_safe">
           <BitParameter Name="speaker_safe">0</BitParameter>
         </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/ip">
+          <BitParameter Name="ip">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/bus">
+          <BitParameter Name="bus">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/fm">
+          <BitParameter Name="fm">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/stub">
+          <BitParameter Name="stub">0</BitParameter>
+        </ConfigurableElement>
       </Configuration>
     </Settings>
   </ConfigurableDomain>
@@ -5356,6 +5432,9 @@
           <SelectionCriterionRule SelectionCriterion="AvailableOutputDevices" MatchesWhen="Includes" Value="AnlgDockHeadset"/>
         </CompoundRule>
       </Configuration>
+      <Configuration Name="NoDevice">
+        <CompoundRule Type="All"/>
+      </Configuration>
     </Configurations>
     <ConfigurableElements>
       <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/remote_submix"/>
@@ -5375,7 +5454,6 @@
       <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/usb_device"/>
       <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/telephony_tx"/>
       <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/line"/>
-      <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/fm"/>
     </ConfigurableElements>
     <Settings>
       <Configuration Name="RemoteSubmix">
@@ -5430,9 +5508,6 @@
         <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/line">
           <BitParameter Name="line">0</BitParameter>
         </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/fm">
-          <BitParameter Name="fm">0</BitParameter>
-        </ConfigurableElement>
       </Configuration>
       <Configuration Name="BluetoothA2dp">
         <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/remote_submix">
@@ -5486,9 +5561,6 @@
         <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/line">
           <BitParameter Name="line">0</BitParameter>
         </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/fm">
-          <BitParameter Name="fm">0</BitParameter>
-        </ConfigurableElement>
       </Configuration>
       <Configuration Name="BluetoothA2dpHeadphones">
         <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/remote_submix">
@@ -5542,9 +5614,6 @@
         <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/line">
           <BitParameter Name="line">0</BitParameter>
         </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/fm">
-          <BitParameter Name="fm">0</BitParameter>
-        </ConfigurableElement>
       </Configuration>
       <Configuration Name="BluetoothA2dpSpeaker">
         <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/remote_submix">
@@ -5598,9 +5667,6 @@
         <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/line">
           <BitParameter Name="line">0</BitParameter>
         </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/fm">
-          <BitParameter Name="fm">0</BitParameter>
-        </ConfigurableElement>
       </Configuration>
       <Configuration Name="WiredHeadphone">
         <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/remote_submix">
@@ -5654,9 +5720,6 @@
         <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/line">
           <BitParameter Name="line">0</BitParameter>
         </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/fm">
-          <BitParameter Name="fm">0</BitParameter>
-        </ConfigurableElement>
       </Configuration>
       <Configuration Name="Line">
         <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/remote_submix">
@@ -5710,9 +5773,6 @@
         <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/line">
           <BitParameter Name="line">1</BitParameter>
         </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/fm">
-          <BitParameter Name="fm">0</BitParameter>
-        </ConfigurableElement>
       </Configuration>
       <Configuration Name="WiredHeadset">
         <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/remote_submix">
@@ -5766,9 +5826,6 @@
         <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/line">
           <BitParameter Name="line">0</BitParameter>
         </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/fm">
-          <BitParameter Name="fm">0</BitParameter>
-        </ConfigurableElement>
       </Configuration>
       <Configuration Name="UsbAccessory">
         <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/remote_submix">
@@ -5822,9 +5879,6 @@
         <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/line">
           <BitParameter Name="line">0</BitParameter>
         </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/fm">
-          <BitParameter Name="fm">0</BitParameter>
-        </ConfigurableElement>
       </Configuration>
       <Configuration Name="UsbDevice">
         <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/remote_submix">
@@ -5878,9 +5932,6 @@
         <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/line">
           <BitParameter Name="line">0</BitParameter>
         </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/fm">
-          <BitParameter Name="fm">0</BitParameter>
-        </ConfigurableElement>
       </Configuration>
       <Configuration Name="DgtlDockHeadset">
         <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/remote_submix">
@@ -5934,9 +5985,6 @@
         <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/line">
           <BitParameter Name="line">0</BitParameter>
         </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/fm">
-          <BitParameter Name="fm">0</BitParameter>
-        </ConfigurableElement>
       </Configuration>
       <Configuration Name="Hdmi">
         <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/remote_submix">
@@ -5990,9 +6038,6 @@
         <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/line">
           <BitParameter Name="line">0</BitParameter>
         </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/fm">
-          <BitParameter Name="fm">0</BitParameter>
-        </ConfigurableElement>
       </Configuration>
       <Configuration Name="AnlgDockHeadset">
         <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/remote_submix">
@@ -6046,8 +6091,58 @@
         <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/line">
           <BitParameter Name="line">0</BitParameter>
         </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/fm">
-          <BitParameter Name="fm">0</BitParameter>
+      </Configuration>
+      <Configuration Name="NoDevice">
+        <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/remote_submix">
+          <BitParameter Name="remote_submix">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/earpiece">
+          <BitParameter Name="earpiece">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/wired_headset">
+          <BitParameter Name="wired_headset">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/wired_headphone">
+          <BitParameter Name="wired_headphone">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/bluetooth_sco">
+          <BitParameter Name="bluetooth_sco">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/bluetooth_sco_headset">
+          <BitParameter Name="bluetooth_sco_headset">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/bluetooth_sco_carkit">
+          <BitParameter Name="bluetooth_sco_carkit">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/bluetooth_a2dp">
+          <BitParameter Name="bluetooth_a2dp">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/bluetooth_a2dp_headphones">
+          <BitParameter Name="bluetooth_a2dp_headphones">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/bluetooth_a2dp_speaker">
+          <BitParameter Name="bluetooth_a2dp_speaker">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/hdmi">
+          <BitParameter Name="hdmi">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/angl_dock_headset">
+          <BitParameter Name="angl_dock_headset">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/dgtl_dock_headset">
+          <BitParameter Name="dgtl_dock_headset">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/usb_accessory">
+          <BitParameter Name="usb_accessory">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/usb_device">
+          <BitParameter Name="usb_device">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/telephony_tx">
+          <BitParameter Name="telephony_tx">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/line">
+          <BitParameter Name="line">0</BitParameter>
         </ConfigurableElement>
       </Configuration>
     </Settings>
@@ -6081,6 +6176,9 @@
       <ConfigurableElement Path="/Policy/policy/strategies/transmitted_through_speaker/selected_output_devices/mask/usb_device"/>
       <ConfigurableElement Path="/Policy/policy/strategies/transmitted_through_speaker/selected_output_devices/mask/telephony_tx"/>
       <ConfigurableElement Path="/Policy/policy/strategies/transmitted_through_speaker/selected_output_devices/mask/line"/>
+      <ConfigurableElement Path="/Policy/policy/strategies/transmitted_through_speaker/selected_output_devices/mask/ip"/>
+      <ConfigurableElement Path="/Policy/policy/strategies/transmitted_through_speaker/selected_output_devices/mask/bus"/>
+      <ConfigurableElement Path="/Policy/policy/strategies/transmitted_through_speaker/selected_output_devices/mask/stub"/>
     </ConfigurableElements>
     <Settings>
       <Configuration Name="Calibration">
@@ -6150,6 +6248,15 @@
         <ConfigurableElement Path="/Policy/policy/strategies/transmitted_through_speaker/selected_output_devices/mask/line">
           <BitParameter Name="line">0</BitParameter>
         </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/transmitted_through_speaker/selected_output_devices/mask/ip">
+          <BitParameter Name="ip">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/transmitted_through_speaker/selected_output_devices/mask/bus">
+          <BitParameter Name="bus">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/transmitted_through_speaker/selected_output_devices/mask/stub">
+          <BitParameter Name="stub">0</BitParameter>
+        </ConfigurableElement>
       </Configuration>
     </Settings>
   </ConfigurableDomain>
@@ -6193,6 +6300,9 @@
       <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/fm"/>
       <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/speaker_safe"/>
       <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/telephony_tx"/>
+      <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/ip"/>
+      <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bus"/>
+      <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/stub"/>
     </ConfigurableElements>
     <Settings>
       <Configuration Name="Calibration">
@@ -6214,6 +6324,15 @@
         <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/telephony_tx">
           <BitParameter Name="telephony_tx">0</BitParameter>
         </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/ip">
+          <BitParameter Name="ip">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/bus">
+          <BitParameter Name="bus">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/accessibility/selected_output_devices/mask/stub">
+          <BitParameter Name="stub">0</BitParameter>
+        </ConfigurableElement>
       </Configuration>
     </Settings>
   </ConfigurableDomain>
@@ -7453,6 +7572,9 @@
       <ConfigurableElement Path="/Policy/policy/strategies/rerouting/selected_output_devices/mask/bluetooth_sco_headset"/>
       <ConfigurableElement Path="/Policy/policy/strategies/rerouting/selected_output_devices/mask/bluetooth_sco_carkit"/>
       <ConfigurableElement Path="/Policy/policy/strategies/rerouting/selected_output_devices/mask/telephony_tx"/>
+      <ConfigurableElement Path="/Policy/policy/strategies/rerouting/selected_output_devices/mask/ip"/>
+      <ConfigurableElement Path="/Policy/policy/strategies/rerouting/selected_output_devices/mask/bus"/>
+      <ConfigurableElement Path="/Policy/policy/strategies/rerouting/selected_output_devices/mask/stub"/>
     </ConfigurableElements>
     <Settings>
       <Configuration Name="Calibration">
@@ -7486,6 +7608,15 @@
         <ConfigurableElement Path="/Policy/policy/strategies/rerouting/selected_output_devices/mask/telephony_tx">
           <BitParameter Name="telephony_tx">0</BitParameter>
         </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/rerouting/selected_output_devices/mask/ip">
+          <BitParameter Name="ip">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/rerouting/selected_output_devices/mask/bus">
+          <BitParameter Name="bus">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/strategies/rerouting/selected_output_devices/mask/stub">
+          <BitParameter Name="stub">0</BitParameter>
+        </ConfigurableElement>
       </Configuration>
     </Settings>
   </ConfigurableDomain>
@@ -8378,7 +8509,6 @@
       </Configuration>
     </Configurations>
     <ConfigurableElements>
-      <ConfigurableElement Path="/Policy/policy/input_sources/default/applicable_input_device/mask/in"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/default/applicable_input_device/mask/communication"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/default/applicable_input_device/mask/ambient"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/default/applicable_input_device/mask/hdmi"/>
@@ -8393,7 +8523,9 @@
       <ConfigurableElement Path="/Policy/policy/input_sources/default/applicable_input_device/mask/line"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/default/applicable_input_device/mask/spdif"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/default/applicable_input_device/mask/loopback"/>
-      <ConfigurableElement Path="/Policy/policy/input_sources/mic/applicable_input_device/mask/in"/>
+      <ConfigurableElement Path="/Policy/policy/input_sources/default/applicable_input_device/mask/ip"/>
+      <ConfigurableElement Path="/Policy/policy/input_sources/default/applicable_input_device/mask/bus"/>
+      <ConfigurableElement Path="/Policy/policy/input_sources/default/applicable_input_device/mask/stub"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/mic/applicable_input_device/mask/communication"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/mic/applicable_input_device/mask/ambient"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/mic/applicable_input_device/mask/hdmi"/>
@@ -8408,7 +8540,9 @@
       <ConfigurableElement Path="/Policy/policy/input_sources/mic/applicable_input_device/mask/line"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/mic/applicable_input_device/mask/spdif"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/mic/applicable_input_device/mask/loopback"/>
-      <ConfigurableElement Path="/Policy/policy/input_sources/voice_downlink/applicable_input_device/mask/in"/>
+      <ConfigurableElement Path="/Policy/policy/input_sources/mic/applicable_input_device/mask/ip"/>
+      <ConfigurableElement Path="/Policy/policy/input_sources/mic/applicable_input_device/mask/bus"/>
+      <ConfigurableElement Path="/Policy/policy/input_sources/mic/applicable_input_device/mask/stub"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/voice_downlink/applicable_input_device/mask/communication"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/voice_downlink/applicable_input_device/mask/ambient"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/voice_downlink/applicable_input_device/mask/builtin_mic"/>
@@ -8427,7 +8561,9 @@
       <ConfigurableElement Path="/Policy/policy/input_sources/voice_downlink/applicable_input_device/mask/spdif"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/voice_downlink/applicable_input_device/mask/bluetooth_a2dp"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/voice_downlink/applicable_input_device/mask/loopback"/>
-      <ConfigurableElement Path="/Policy/policy/input_sources/voice_call/applicable_input_device/mask/in"/>
+      <ConfigurableElement Path="/Policy/policy/input_sources/voice_downlink/applicable_input_device/mask/ip"/>
+      <ConfigurableElement Path="/Policy/policy/input_sources/voice_downlink/applicable_input_device/mask/bus"/>
+      <ConfigurableElement Path="/Policy/policy/input_sources/voice_downlink/applicable_input_device/mask/stub"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/voice_call/applicable_input_device/mask/communication"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/voice_call/applicable_input_device/mask/ambient"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/voice_call/applicable_input_device/mask/builtin_mic"/>
@@ -8446,7 +8582,9 @@
       <ConfigurableElement Path="/Policy/policy/input_sources/voice_call/applicable_input_device/mask/spdif"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/voice_call/applicable_input_device/mask/bluetooth_a2dp"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/voice_call/applicable_input_device/mask/loopback"/>
-      <ConfigurableElement Path="/Policy/policy/input_sources/voice_uplink/applicable_input_device/mask/in"/>
+      <ConfigurableElement Path="/Policy/policy/input_sources/voice_call/applicable_input_device/mask/ip"/>
+      <ConfigurableElement Path="/Policy/policy/input_sources/voice_call/applicable_input_device/mask/bus"/>
+      <ConfigurableElement Path="/Policy/policy/input_sources/voice_call/applicable_input_device/mask/stub"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/voice_uplink/applicable_input_device/mask/communication"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/voice_uplink/applicable_input_device/mask/ambient"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/voice_uplink/applicable_input_device/mask/builtin_mic"/>
@@ -8465,7 +8603,9 @@
       <ConfigurableElement Path="/Policy/policy/input_sources/voice_uplink/applicable_input_device/mask/spdif"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/voice_uplink/applicable_input_device/mask/bluetooth_a2dp"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/voice_uplink/applicable_input_device/mask/loopback"/>
-      <ConfigurableElement Path="/Policy/policy/input_sources/camcorder/applicable_input_device/mask/in"/>
+      <ConfigurableElement Path="/Policy/policy/input_sources/voice_uplink/applicable_input_device/mask/ip"/>
+      <ConfigurableElement Path="/Policy/policy/input_sources/voice_uplink/applicable_input_device/mask/bus"/>
+      <ConfigurableElement Path="/Policy/policy/input_sources/voice_uplink/applicable_input_device/mask/stub"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/camcorder/applicable_input_device/mask/communication"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/camcorder/applicable_input_device/mask/ambient"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/camcorder/applicable_input_device/mask/bluetooth_sco_headset"/>
@@ -8483,7 +8623,9 @@
       <ConfigurableElement Path="/Policy/policy/input_sources/camcorder/applicable_input_device/mask/spdif"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/camcorder/applicable_input_device/mask/bluetooth_a2dp"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/camcorder/applicable_input_device/mask/loopback"/>
-      <ConfigurableElement Path="/Policy/policy/input_sources/voice_recognition/applicable_input_device/mask/in"/>
+      <ConfigurableElement Path="/Policy/policy/input_sources/camcorder/applicable_input_device/mask/ip"/>
+      <ConfigurableElement Path="/Policy/policy/input_sources/camcorder/applicable_input_device/mask/bus"/>
+      <ConfigurableElement Path="/Policy/policy/input_sources/camcorder/applicable_input_device/mask/stub"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/voice_recognition/applicable_input_device/mask/communication"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/voice_recognition/applicable_input_device/mask/ambient"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/voice_recognition/applicable_input_device/mask/hdmi"/>
@@ -8499,7 +8641,9 @@
       <ConfigurableElement Path="/Policy/policy/input_sources/voice_recognition/applicable_input_device/mask/spdif"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/voice_recognition/applicable_input_device/mask/bluetooth_a2dp"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/voice_recognition/applicable_input_device/mask/loopback"/>
-      <ConfigurableElement Path="/Policy/policy/input_sources/voice_communication/applicable_input_device/mask/in"/>
+      <ConfigurableElement Path="/Policy/policy/input_sources/voice_recognition/applicable_input_device/mask/ip"/>
+      <ConfigurableElement Path="/Policy/policy/input_sources/voice_recognition/applicable_input_device/mask/bus"/>
+      <ConfigurableElement Path="/Policy/policy/input_sources/voice_recognition/applicable_input_device/mask/stub"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/voice_communication/applicable_input_device/mask/communication"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/voice_communication/applicable_input_device/mask/ambient"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/voice_communication/applicable_input_device/mask/hdmi"/>
@@ -8514,7 +8658,9 @@
       <ConfigurableElement Path="/Policy/policy/input_sources/voice_communication/applicable_input_device/mask/spdif"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/voice_communication/applicable_input_device/mask/bluetooth_a2dp"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/voice_communication/applicable_input_device/mask/loopback"/>
-      <ConfigurableElement Path="/Policy/policy/input_sources/remote_submix/applicable_input_device/mask/in"/>
+      <ConfigurableElement Path="/Policy/policy/input_sources/voice_communication/applicable_input_device/mask/ip"/>
+      <ConfigurableElement Path="/Policy/policy/input_sources/voice_communication/applicable_input_device/mask/bus"/>
+      <ConfigurableElement Path="/Policy/policy/input_sources/voice_communication/applicable_input_device/mask/stub"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/remote_submix/applicable_input_device/mask/communication"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/remote_submix/applicable_input_device/mask/ambient"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/remote_submix/applicable_input_device/mask/builtin_mic"/>
@@ -8533,7 +8679,9 @@
       <ConfigurableElement Path="/Policy/policy/input_sources/remote_submix/applicable_input_device/mask/spdif"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/remote_submix/applicable_input_device/mask/bluetooth_a2dp"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/remote_submix/applicable_input_device/mask/loopback"/>
-      <ConfigurableElement Path="/Policy/policy/input_sources/hotword/applicable_input_device/mask/in"/>
+      <ConfigurableElement Path="/Policy/policy/input_sources/remote_submix/applicable_input_device/mask/ip"/>
+      <ConfigurableElement Path="/Policy/policy/input_sources/remote_submix/applicable_input_device/mask/bus"/>
+      <ConfigurableElement Path="/Policy/policy/input_sources/remote_submix/applicable_input_device/mask/stub"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/hotword/applicable_input_device/mask/communication"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/hotword/applicable_input_device/mask/ambient"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/hotword/applicable_input_device/mask/hdmi"/>
@@ -8549,7 +8697,9 @@
       <ConfigurableElement Path="/Policy/policy/input_sources/hotword/applicable_input_device/mask/spdif"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/hotword/applicable_input_device/mask/bluetooth_a2dp"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/hotword/applicable_input_device/mask/loopback"/>
-      <ConfigurableElement Path="/Policy/policy/input_sources/unprocessed/applicable_input_device/mask/in"/>
+      <ConfigurableElement Path="/Policy/policy/input_sources/hotword/applicable_input_device/mask/ip"/>
+      <ConfigurableElement Path="/Policy/policy/input_sources/hotword/applicable_input_device/mask/bus"/>
+      <ConfigurableElement Path="/Policy/policy/input_sources/hotword/applicable_input_device/mask/stub"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/unprocessed/applicable_input_device/mask/communication"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/unprocessed/applicable_input_device/mask/ambient"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/unprocessed/applicable_input_device/mask/hdmi"/>
@@ -8565,7 +8715,9 @@
       <ConfigurableElement Path="/Policy/policy/input_sources/unprocessed/applicable_input_device/mask/spdif"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/unprocessed/applicable_input_device/mask/bluetooth_a2dp"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/unprocessed/applicable_input_device/mask/loopback"/>
-      <ConfigurableElement Path="/Policy/policy/input_sources/fm_tuner/applicable_input_device/mask/in"/>
+      <ConfigurableElement Path="/Policy/policy/input_sources/unprocessed/applicable_input_device/mask/ip"/>
+      <ConfigurableElement Path="/Policy/policy/input_sources/unprocessed/applicable_input_device/mask/bus"/>
+      <ConfigurableElement Path="/Policy/policy/input_sources/unprocessed/applicable_input_device/mask/stub"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/fm_tuner/applicable_input_device/mask/communication"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/fm_tuner/applicable_input_device/mask/ambient"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/fm_tuner/applicable_input_device/mask/bluetooth_sco_headset"/>
@@ -8584,12 +8736,11 @@
       <ConfigurableElement Path="/Policy/policy/input_sources/fm_tuner/applicable_input_device/mask/spdif"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/fm_tuner/applicable_input_device/mask/bluetooth_a2dp"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/fm_tuner/applicable_input_device/mask/loopback"/>
+      <ConfigurableElement Path="/Policy/policy/input_sources/fm_tuner/applicable_input_device/mask/ip"/>
+      <ConfigurableElement Path="/Policy/policy/input_sources/fm_tuner/applicable_input_device/mask/bus"/>
     </ConfigurableElements>
     <Settings>
       <Configuration Name="Calibration">
-        <ConfigurableElement Path="/Policy/policy/input_sources/default/applicable_input_device/mask/in">
-          <BitParameter Name="in">1</BitParameter>
-        </ConfigurableElement>
         <ConfigurableElement Path="/Policy/policy/input_sources/default/applicable_input_device/mask/communication">
           <BitParameter Name="communication">0</BitParameter>
         </ConfigurableElement>
@@ -8632,8 +8783,14 @@
         <ConfigurableElement Path="/Policy/policy/input_sources/default/applicable_input_device/mask/loopback">
           <BitParameter Name="loopback">0</BitParameter>
         </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/input_sources/mic/applicable_input_device/mask/in">
-          <BitParameter Name="in">1</BitParameter>
+        <ConfigurableElement Path="/Policy/policy/input_sources/default/applicable_input_device/mask/ip">
+          <BitParameter Name="ip">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/input_sources/default/applicable_input_device/mask/bus">
+          <BitParameter Name="bus">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/input_sources/default/applicable_input_device/mask/stub">
+          <BitParameter Name="stub">0</BitParameter>
         </ConfigurableElement>
         <ConfigurableElement Path="/Policy/policy/input_sources/mic/applicable_input_device/mask/communication">
           <BitParameter Name="communication">0</BitParameter>
@@ -8677,8 +8834,14 @@
         <ConfigurableElement Path="/Policy/policy/input_sources/mic/applicable_input_device/mask/loopback">
           <BitParameter Name="loopback">0</BitParameter>
         </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/input_sources/voice_downlink/applicable_input_device/mask/in">
-          <BitParameter Name="in">1</BitParameter>
+        <ConfigurableElement Path="/Policy/policy/input_sources/mic/applicable_input_device/mask/ip">
+          <BitParameter Name="ip">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/input_sources/mic/applicable_input_device/mask/bus">
+          <BitParameter Name="bus">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/input_sources/mic/applicable_input_device/mask/stub">
+          <BitParameter Name="stub">0</BitParameter>
         </ConfigurableElement>
         <ConfigurableElement Path="/Policy/policy/input_sources/voice_downlink/applicable_input_device/mask/communication">
           <BitParameter Name="communication">0</BitParameter>
@@ -8734,8 +8897,14 @@
         <ConfigurableElement Path="/Policy/policy/input_sources/voice_downlink/applicable_input_device/mask/loopback">
           <BitParameter Name="loopback">0</BitParameter>
         </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/input_sources/voice_call/applicable_input_device/mask/in">
-          <BitParameter Name="in">1</BitParameter>
+        <ConfigurableElement Path="/Policy/policy/input_sources/voice_downlink/applicable_input_device/mask/ip">
+          <BitParameter Name="ip">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/input_sources/voice_downlink/applicable_input_device/mask/bus">
+          <BitParameter Name="bus">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/input_sources/voice_downlink/applicable_input_device/mask/stub">
+          <BitParameter Name="stub">0</BitParameter>
         </ConfigurableElement>
         <ConfigurableElement Path="/Policy/policy/input_sources/voice_call/applicable_input_device/mask/communication">
           <BitParameter Name="communication">0</BitParameter>
@@ -8791,8 +8960,14 @@
         <ConfigurableElement Path="/Policy/policy/input_sources/voice_call/applicable_input_device/mask/loopback">
           <BitParameter Name="loopback">0</BitParameter>
         </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/input_sources/voice_uplink/applicable_input_device/mask/in">
-          <BitParameter Name="in">1</BitParameter>
+        <ConfigurableElement Path="/Policy/policy/input_sources/voice_call/applicable_input_device/mask/ip">
+          <BitParameter Name="ip">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/input_sources/voice_call/applicable_input_device/mask/bus">
+          <BitParameter Name="bus">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/input_sources/voice_call/applicable_input_device/mask/stub">
+          <BitParameter Name="stub">0</BitParameter>
         </ConfigurableElement>
         <ConfigurableElement Path="/Policy/policy/input_sources/voice_uplink/applicable_input_device/mask/communication">
           <BitParameter Name="communication">0</BitParameter>
@@ -8848,8 +9023,14 @@
         <ConfigurableElement Path="/Policy/policy/input_sources/voice_uplink/applicable_input_device/mask/loopback">
           <BitParameter Name="loopback">0</BitParameter>
         </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/input_sources/camcorder/applicable_input_device/mask/in">
-          <BitParameter Name="in">1</BitParameter>
+        <ConfigurableElement Path="/Policy/policy/input_sources/voice_uplink/applicable_input_device/mask/ip">
+          <BitParameter Name="ip">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/input_sources/voice_uplink/applicable_input_device/mask/bus">
+          <BitParameter Name="bus">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/input_sources/voice_uplink/applicable_input_device/mask/stub">
+          <BitParameter Name="stub">0</BitParameter>
         </ConfigurableElement>
         <ConfigurableElement Path="/Policy/policy/input_sources/camcorder/applicable_input_device/mask/communication">
           <BitParameter Name="communication">0</BitParameter>
@@ -8902,8 +9083,14 @@
         <ConfigurableElement Path="/Policy/policy/input_sources/camcorder/applicable_input_device/mask/loopback">
           <BitParameter Name="loopback">0</BitParameter>
         </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/input_sources/voice_recognition/applicable_input_device/mask/in">
-          <BitParameter Name="in">1</BitParameter>
+        <ConfigurableElement Path="/Policy/policy/input_sources/camcorder/applicable_input_device/mask/ip">
+          <BitParameter Name="ip">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/input_sources/camcorder/applicable_input_device/mask/bus">
+          <BitParameter Name="bus">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/input_sources/camcorder/applicable_input_device/mask/stub">
+          <BitParameter Name="stub">0</BitParameter>
         </ConfigurableElement>
         <ConfigurableElement Path="/Policy/policy/input_sources/voice_recognition/applicable_input_device/mask/communication">
           <BitParameter Name="communication">0</BitParameter>
@@ -8950,8 +9137,14 @@
         <ConfigurableElement Path="/Policy/policy/input_sources/voice_recognition/applicable_input_device/mask/loopback">
           <BitParameter Name="loopback">0</BitParameter>
         </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/input_sources/voice_communication/applicable_input_device/mask/in">
-          <BitParameter Name="in">1</BitParameter>
+        <ConfigurableElement Path="/Policy/policy/input_sources/voice_recognition/applicable_input_device/mask/ip">
+          <BitParameter Name="ip">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/input_sources/voice_recognition/applicable_input_device/mask/bus">
+          <BitParameter Name="bus">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/input_sources/voice_recognition/applicable_input_device/mask/stub">
+          <BitParameter Name="stub">0</BitParameter>
         </ConfigurableElement>
         <ConfigurableElement Path="/Policy/policy/input_sources/voice_communication/applicable_input_device/mask/communication">
           <BitParameter Name="communication">0</BitParameter>
@@ -8995,8 +9188,14 @@
         <ConfigurableElement Path="/Policy/policy/input_sources/voice_communication/applicable_input_device/mask/loopback">
           <BitParameter Name="loopback">0</BitParameter>
         </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/input_sources/remote_submix/applicable_input_device/mask/in">
-          <BitParameter Name="in">1</BitParameter>
+        <ConfigurableElement Path="/Policy/policy/input_sources/voice_communication/applicable_input_device/mask/ip">
+          <BitParameter Name="ip">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/input_sources/voice_communication/applicable_input_device/mask/bus">
+          <BitParameter Name="bus">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/input_sources/voice_communication/applicable_input_device/mask/stub">
+          <BitParameter Name="stub">0</BitParameter>
         </ConfigurableElement>
         <ConfigurableElement Path="/Policy/policy/input_sources/remote_submix/applicable_input_device/mask/communication">
           <BitParameter Name="communication">0</BitParameter>
@@ -9052,8 +9251,14 @@
         <ConfigurableElement Path="/Policy/policy/input_sources/remote_submix/applicable_input_device/mask/loopback">
           <BitParameter Name="loopback">0</BitParameter>
         </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/input_sources/hotword/applicable_input_device/mask/in">
-          <BitParameter Name="in">1</BitParameter>
+        <ConfigurableElement Path="/Policy/policy/input_sources/remote_submix/applicable_input_device/mask/ip">
+          <BitParameter Name="ip">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/input_sources/remote_submix/applicable_input_device/mask/bus">
+          <BitParameter Name="bus">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/input_sources/remote_submix/applicable_input_device/mask/stub">
+          <BitParameter Name="stub">0</BitParameter>
         </ConfigurableElement>
         <ConfigurableElement Path="/Policy/policy/input_sources/hotword/applicable_input_device/mask/communication">
           <BitParameter Name="communication">0</BitParameter>
@@ -9100,8 +9305,14 @@
         <ConfigurableElement Path="/Policy/policy/input_sources/hotword/applicable_input_device/mask/loopback">
           <BitParameter Name="loopback">0</BitParameter>
         </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/input_sources/unprocessed/applicable_input_device/mask/in">
-          <BitParameter Name="in">1</BitParameter>
+        <ConfigurableElement Path="/Policy/policy/input_sources/hotword/applicable_input_device/mask/ip">
+          <BitParameter Name="ip">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/input_sources/hotword/applicable_input_device/mask/bus">
+          <BitParameter Name="bus">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/input_sources/hotword/applicable_input_device/mask/stub">
+          <BitParameter Name="stub">0</BitParameter>
         </ConfigurableElement>
         <ConfigurableElement Path="/Policy/policy/input_sources/unprocessed/applicable_input_device/mask/communication">
           <BitParameter Name="communication">0</BitParameter>
@@ -9148,8 +9359,14 @@
         <ConfigurableElement Path="/Policy/policy/input_sources/unprocessed/applicable_input_device/mask/loopback">
           <BitParameter Name="loopback">0</BitParameter>
         </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/input_sources/fm_tuner/applicable_input_device/mask/in">
-          <BitParameter Name="in">1</BitParameter>
+        <ConfigurableElement Path="/Policy/policy/input_sources/unprocessed/applicable_input_device/mask/ip">
+          <BitParameter Name="ip">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/input_sources/unprocessed/applicable_input_device/mask/bus">
+          <BitParameter Name="bus">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/input_sources/unprocessed/applicable_input_device/mask/stub">
+          <BitParameter Name="stub">0</BitParameter>
         </ConfigurableElement>
         <ConfigurableElement Path="/Policy/policy/input_sources/fm_tuner/applicable_input_device/mask/communication">
           <BitParameter Name="communication">0</BitParameter>
@@ -9205,6 +9422,12 @@
         <ConfigurableElement Path="/Policy/policy/input_sources/fm_tuner/applicable_input_device/mask/loopback">
           <BitParameter Name="loopback">0</BitParameter>
         </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/input_sources/fm_tuner/applicable_input_device/mask/ip">
+          <BitParameter Name="ip">0</BitParameter>
+        </ConfigurableElement>
+        <ConfigurableElement Path="/Policy/policy/input_sources/fm_tuner/applicable_input_device/mask/bus">
+          <BitParameter Name="bus">0</BitParameter>
+        </ConfigurableElement>
       </Configuration>
     </Settings>
   </ConfigurableDomain>
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_input_source.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_input_source.pfw
similarity index 96%
rename from services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_input_source.pfw
rename to services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_input_source.pfw
index 16bcb01..9fd459a 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_input_source.pfw
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_input_source.pfw
@@ -1,12 +1,7 @@
 supDomain: DeviceForInputSource
 	domain: Calibration
 		conf: Calibration
-			#
-			# Note that ALL input devices must have the sign bit set to 1.
-			# As the devices is a mask, use the "in" bit as a direction indicator.
-			#
 			component: /Policy/policy/input_sources/default/applicable_input_device/mask
-				in = 1
 				communication = 0
 				ambient = 0
 				hdmi = 0
@@ -21,8 +16,10 @@
 				line = 0
 				spdif = 0
 				loopback = 0
+				ip = 0
+				bus = 0
+				stub = 0
 			component: /Policy/policy/input_sources/mic/applicable_input_device/mask
-				in = 1
 				communication = 0
 				ambient = 0
 				hdmi = 0
@@ -37,8 +34,10 @@
 				line = 0
 				spdif = 0
 				loopback = 0
+				ip = 0
+				bus = 0
+				stub = 0
 			component: /Policy/policy/input_sources/voice_downlink/applicable_input_device/mask
-				in = 1
 				communication = 0
 				ambient = 0
 				builtin_mic = 0
@@ -57,8 +56,10 @@
 				spdif = 0
 				bluetooth_a2dp = 0
 				loopback = 0
+				ip = 0
+				bus = 0
+				stub = 0
 			component: /Policy/policy/input_sources/voice_call/applicable_input_device/mask
-				in = 1
 				communication = 0
 				ambient = 0
 				builtin_mic = 0
@@ -77,8 +78,10 @@
 				spdif = 0
 				bluetooth_a2dp = 0
 				loopback = 0
+				ip = 0
+				bus = 0
+				stub = 0
 			component: /Policy/policy/input_sources/voice_uplink/applicable_input_device/mask
-				in = 1
 				communication = 0
 				ambient = 0
 				builtin_mic = 0
@@ -97,8 +100,10 @@
 				spdif = 0
 				bluetooth_a2dp = 0
 				loopback = 0
+				ip = 0
+				bus = 0
+				stub = 0
 			component: /Policy/policy/input_sources/camcorder/applicable_input_device/mask
-				in = 1
 				communication = 0
 				ambient = 0
 				bluetooth_sco_headset = 0
@@ -116,8 +121,10 @@
 				spdif = 0
 				bluetooth_a2dp = 0
 				loopback = 0
+				ip = 0
+				bus = 0
+				stub = 0
 			component: /Policy/policy/input_sources/voice_recognition/applicable_input_device/mask
-				in = 1
 				communication = 0
 				ambient = 0
 				hdmi = 0
@@ -133,8 +140,10 @@
 				spdif = 0
 				bluetooth_a2dp = 0
 				loopback = 0
+				ip = 0
+				bus = 0
+				stub = 0
 			component: /Policy/policy/input_sources/voice_communication/applicable_input_device/mask
-				in = 1
 				communication = 0
 				ambient = 0
 				hdmi = 0
@@ -149,8 +158,10 @@
 				spdif = 0
 				bluetooth_a2dp = 0
 				loopback = 0
+				ip = 0
+				bus = 0
+				stub = 0
 			component: /Policy/policy/input_sources/remote_submix/applicable_input_device/mask
-				in = 1
 				communication = 0
 				ambient = 0
 				builtin_mic = 0
@@ -169,8 +180,10 @@
 				spdif = 0
 				bluetooth_a2dp = 0
 				loopback = 0
+				ip = 0
+				bus = 0
+				stub = 0
 			component: /Policy/policy/input_sources/hotword/applicable_input_device/mask
-				in = 1
 				communication = 0
 				ambient = 0
 				hdmi = 0
@@ -186,8 +199,10 @@
 				spdif = 0
 				bluetooth_a2dp = 0
 				loopback = 0
+				ip = 0
+				bus = 0
+				stub = 0
 			component: /Policy/policy/input_sources/unprocessed/applicable_input_device/mask
-				in = 1
 				communication = 0
 				ambient = 0
 				hdmi = 0
@@ -203,8 +218,10 @@
 				spdif = 0
 				bluetooth_a2dp = 0
 				loopback = 0
+				ip = 0
+				bus = 0
+				stub = 0
 			component: /Policy/policy/input_sources/fm_tuner/applicable_input_device/mask
-				in = 1
 				communication = 0
 				ambient = 0
 				bluetooth_sco_headset = 0
@@ -223,6 +240,8 @@
 				spdif = 0
 				bluetooth_a2dp = 0
 				loopback = 0
+				ip = 0
+				bus = 0
 
 	domain: DefaultAndMic
 		conf: A2dp
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_accessibility.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_accessibility.pfw
similarity index 99%
rename from services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_accessibility.pfw
rename to services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_accessibility.pfw
index dacf5b2..ecd56b0 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_accessibility.pfw
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_accessibility.pfw
@@ -16,6 +16,9 @@
 					fm = 0
 					speaker_safe = 0
 					telephony_tx = 0
+					ip = 0
+					bus = 0
+					stub = 0
 
 		domain: Device
 			conf: RemoteSubmix
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_dtmf.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_dtmf.pfw
similarity index 99%
rename from services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_dtmf.pfw
rename to services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_dtmf.pfw
index d9469c0..883c741 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_dtmf.pfw
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_dtmf.pfw
@@ -8,6 +8,9 @@
 					fm = 0
 					speaker_safe = 0
 					bluetooth_sco_carkit = 0
+					ip = 0
+					bus = 0
+					stub = 0
 
 		domain: Device2
 			conf: RemoteSubmix
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_enforced_audible.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_enforced_audible.pfw
similarity index 94%
rename from services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_enforced_audible.pfw
rename to services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_enforced_audible.pfw
index 593ef64..f504631 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_enforced_audible.pfw
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_enforced_audible.pfw
@@ -10,6 +10,10 @@
 					spdif = 0
 					aux_line = 0
 					speaker_safe = 0
+					ip = 0
+					bus = 0
+					fm = 0
+					stub = 0
 
 		domain: Speaker
 			conf: Selected
@@ -76,7 +80,6 @@
 					usb_device = 0
 					telephony_tx = 0
 					line = 0
-					fm = 0
 
 			conf: BluetoothA2dp
 				AvailableOutputDevices Includes BluetoothA2dp
@@ -100,7 +103,6 @@
 					usb_device = 0
 					telephony_tx = 0
 					line = 0
-					fm = 0
 
 			conf: BluetoothA2dpHeadphones
 				AvailableOutputDevices Includes BluetoothA2dpHeadphones
@@ -124,7 +126,6 @@
 					usb_device = 0
 					telephony_tx = 0
 					line = 0
-					fm = 0
 
 			conf: BluetoothA2dpSpeaker
 				AvailableOutputDevices Includes BluetoothA2dpSpeaker
@@ -148,7 +149,6 @@
 					usb_device = 0
 					telephony_tx = 0
 					line = 0
-					fm = 0
 
 			conf: WiredHeadphone
 				ForceUseForMedia IsNot ForceSpeaker
@@ -172,7 +172,6 @@
 					usb_device = 0
 					telephony_tx = 0
 					line = 0
-					fm = 0
 
 			conf: Line
 				ForceUseForMedia IsNot ForceSpeaker
@@ -196,7 +195,6 @@
 					usb_device = 0
 					telephony_tx = 0
 					line = 1
-					fm = 0
 
 			conf: WiredHeadset
 				ForceUseForMedia IsNot ForceSpeaker
@@ -220,7 +218,6 @@
 					usb_device = 0
 					telephony_tx = 0
 					line = 0
-					fm = 0
 
 			conf: UsbAccessory
 				ForceUseForMedia IsNot ForceSpeaker
@@ -244,7 +241,6 @@
 					usb_device = 0
 					telephony_tx = 0
 					line = 0
-					fm = 0
 
 			conf: UsbDevice
 				ForceUseForMedia IsNot ForceSpeaker
@@ -268,7 +264,6 @@
 					usb_device = 1
 					telephony_tx = 0
 					line = 0
-					fm = 0
 
 			conf: DgtlDockHeadset
 				ForceUseForMedia IsNot ForceSpeaker
@@ -292,7 +287,6 @@
 					usb_device = 0
 					telephony_tx = 0
 					line = 0
-					fm = 0
 
 			conf: Hdmi
 				ForceUseForMedia IsNot ForceSpeaker
@@ -316,7 +310,6 @@
 					usb_device = 0
 					telephony_tx = 0
 					line = 0
-					fm = 0
 
 			conf: AnlgDockHeadset
 				ForceUseForMedia IsNot ForceSpeaker
@@ -341,5 +334,25 @@
 					usb_device = 0
 					telephony_tx = 0
 					line = 0
-					fm = 0
+
+			conf: NoDevice
+				component: /Policy/policy/strategies/enforced_audible/selected_output_devices/mask
+					remote_submix = 0
+					earpiece = 0
+					wired_headset = 0
+					wired_headphone = 0
+					bluetooth_sco = 0
+					bluetooth_sco_headset = 0
+					bluetooth_sco_carkit = 0
+					bluetooth_a2dp = 0
+					bluetooth_a2dp_headphones = 0
+					bluetooth_a2dp_speaker = 0
+					hdmi = 0
+					angl_dock_headset = 0
+					dgtl_dock_headset = 0
+					usb_accessory = 0
+					usb_device = 0
+					telephony_tx = 0
+					line = 0
+
 
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_media.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_media.pfw
similarity index 99%
rename from services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_media.pfw
rename to services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_media.pfw
index 006ac60..bdb6ae0 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_media.pfw
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_media.pfw
@@ -12,6 +12,9 @@
 					bluetooth_sco_headset = 0
 					bluetooth_sco_carkit = 0
 					telephony_tx = 0
+					ip = 0
+					bus = 0
+					stub = 0
 
 		domain: Device2
 			conf: RemoteSubmix
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_phone.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_phone.pfw
similarity index 99%
rename from services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_phone.pfw
rename to services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_phone.pfw
index 0dad830..d371ad9 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_phone.pfw
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_phone.pfw
@@ -12,6 +12,9 @@
 					spdif = 0
 					fm = 0
 					speaker_safe = 0
+					ip = 0
+					bus = 0
+					stub = 0
 
 		domain: Device
 			conf: ScoCarkit
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_rerouting.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_rerouting.pfw
similarity index 99%
rename from services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_rerouting.pfw
rename to services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_rerouting.pfw
index d390a33..04e62f7 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_rerouting.pfw
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_rerouting.pfw
@@ -17,6 +17,9 @@
 					bluetooth_sco_headset = 0
 					bluetooth_sco_carkit = 0
 					telephony_tx = 0
+					ip = 0
+					bus = 0
+					stub = 0
 
 		domain: Device2
 			conf: RemoteSubmix
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_sonification.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_sonification.pfw
similarity index 99%
rename from services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_sonification.pfw
rename to services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_sonification.pfw
index 96723f6..70740d1 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_sonification.pfw
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_sonification.pfw
@@ -16,6 +16,9 @@
 					# Sonification follows phone strategy if in call but HDMI is not reachable
 					#
 					hdmi = 0
+					ip = 0
+					bus = 0
+					stub = 0
 
 		domain: Speaker
 
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_sonification_respectful.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_sonification_respectful.pfw
similarity index 99%
rename from services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_sonification_respectful.pfw
rename to services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_sonification_respectful.pfw
index 7626944..b30aa4c 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_sonification_respectful.pfw
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_sonification_respectful.pfw
@@ -22,6 +22,9 @@
 					spdif = 0
 					fm = 0
 					telephony_tx = 0
+					ip = 0
+					bus = 0
+					stub = 0
 
 		domain: Speakers
 
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_transmitted_through_speaker.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_transmitted_through_speaker.pfw
similarity index 96%
rename from services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_transmitted_through_speaker.pfw
rename to services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_transmitted_through_speaker.pfw
index e5ae9d9..9f9c211 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_transmitted_through_speaker.pfw
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/device_for_strategy_transmitted_through_speaker.pfw
@@ -26,6 +26,9 @@
 					usb_device = 0
 					telephony_tx = 0
 					line = 0
+					ip = 0
+					bus = 0
+					stub = 0
 
 		domain: Speaker
 			conf: Selected
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/strategy_for_stream.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/strategy_for_stream.pfw
similarity index 100%
rename from services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/strategy_for_stream.pfw
rename to services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/strategy_for_stream.pfw
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/strategy_for_usage.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/strategy_for_usage.pfw
similarity index 100%
rename from services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/strategy_for_usage.pfw
rename to services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/strategy_for_usage.pfw
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/volumes.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/volumes.pfw
similarity index 100%
rename from services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/volumes.pfw
rename to services/audiopolicy/engineconfigurable/parameter-framework/examples/Settings/volumes.pfw
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/SettingsNoInput/device_for_input_source.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/SettingsNoInput/device_for_input_source.pfw
new file mode 100644
index 0000000..611d8f5
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/SettingsNoInput/device_for_input_source.pfw
@@ -0,0 +1,285 @@
+supDomain: DeviceForInputSource
+	domain: Calibration
+		conf: Calibration
+			#
+			# Note that ALL input devices must have the sign bit set to 1.
+			# As the devices is a mask, use the "in" bit as a direction indicator.
+			#
+			component: /Policy/policy/input_sources/default/applicable_input_device/mask
+				communication = 0
+				ambient = 0
+				builtin_mic = 0
+				bluetooth_sco_headset = 0
+				wired_headset = 0
+				hdmi = 0
+				telephony_rx = 0
+				back_mic = 0
+				remote_submix = 0
+				anlg_dock_headset = 0
+				dgtl_dock_headset = 0>
+				usb_accessory = 0
+				usb_device = 0
+				fm_tuner = 0
+				tv_tuner = 0
+				line = 0
+				spdif = 0
+				bluetooth_a2dp = 0
+				loopback = 0
+				ip = 0
+				bus = 0
+				stub = 1
+			component: /Policy/policy/input_sources/mic/applicable_input_device/mask
+				communication = 0
+				ambient = 0
+				builtin_mic = 0
+				bluetooth_sco_headset = 0
+				wired_headset = 0
+				hdmi = 0
+				telephony_rx = 0
+				back_mic = 0
+				remote_submix = 0
+				anlg_dock_headset = 0
+				dgtl_dock_headset = 0>
+				usb_accessory = 0
+				usb_device = 0
+				fm_tuner = 0
+				tv_tuner = 0
+				line = 0
+				spdif = 0
+				bluetooth_a2dp = 0
+				loopback = 0
+				ip = 0
+				bus = 0
+				stub = 1
+			component: /Policy/policy/input_sources/voice_downlink/applicable_input_device/mask
+				communication = 0
+				ambient = 0
+				builtin_mic = 0
+				bluetooth_sco_headset = 0
+				wired_headset = 0
+				hdmi = 0
+				telephony_rx = 0
+				back_mic = 0
+				remote_submix = 0
+				anlg_dock_headset = 0
+				dgtl_dock_headset = 0>
+				usb_accessory = 0
+				usb_device = 0
+				fm_tuner = 0
+				tv_tuner = 0
+				line = 0
+				spdif = 0
+				bluetooth_a2dp = 0
+				loopback = 0
+				ip = 0
+				bus = 0
+				stub = 1
+			component: /Policy/policy/input_sources/voice_call/applicable_input_device/mask
+				communication = 0
+				ambient = 0
+				builtin_mic = 0
+				bluetooth_sco_headset = 0
+				wired_headset = 0
+				hdmi = 0
+				telephony_rx = 0
+				back_mic = 0
+				remote_submix = 0
+				anlg_dock_headset = 0
+				dgtl_dock_headset = 0>
+				usb_accessory = 0
+				usb_device = 0
+				fm_tuner = 0
+				tv_tuner = 0
+				line = 0
+				spdif = 0
+				bluetooth_a2dp = 0
+				loopback = 0
+				ip = 0
+				bus = 0
+				stub = 1
+			component: /Policy/policy/input_sources/voice_uplink/applicable_input_device/mask
+				communication = 0
+				ambient = 0
+				builtin_mic = 0
+				bluetooth_sco_headset = 0
+				wired_headset = 0
+				hdmi = 0
+				telephony_rx = 0
+				back_mic = 0
+				remote_submix = 0
+				anlg_dock_headset = 0
+				dgtl_dock_headset = 0>
+				usb_accessory = 0
+				usb_device = 0
+				fm_tuner = 0
+				tv_tuner = 0
+				line = 0
+				spdif = 0
+				bluetooth_a2dp = 0
+				loopback = 0
+				ip = 0
+				bus = 0
+				stub = 1
+			component: /Policy/policy/input_sources/camcorder/applicable_input_device/mask
+				communication = 0
+				ambient = 0
+				builtin_mic = 0
+				bluetooth_sco_headset = 0
+				wired_headset = 0
+				hdmi = 0
+				telephony_rx = 0
+				back_mic = 0
+				remote_submix = 0
+				anlg_dock_headset = 0
+				dgtl_dock_headset = 0>
+				usb_accessory = 0
+				usb_device = 0
+				fm_tuner = 0
+				tv_tuner = 0
+				line = 0
+				spdif = 0
+				bluetooth_a2dp = 0
+				loopback = 0
+				ip = 0
+				bus = 0
+				stub = 1
+			component: /Policy/policy/input_sources/voice_recognition/applicable_input_device/mask
+				communication = 0
+				ambient = 0
+				builtin_mic = 0
+				bluetooth_sco_headset = 0
+				wired_headset = 0
+				hdmi = 0
+				telephony_rx = 0
+				back_mic = 0
+				remote_submix = 0
+				anlg_dock_headset = 0
+				dgtl_dock_headset = 0>
+				usb_accessory = 0
+				usb_device = 0
+				fm_tuner = 0
+				tv_tuner = 0
+				line = 0
+				spdif = 0
+				bluetooth_a2dp = 0
+				loopback = 0
+				ip = 0
+				bus = 0
+				stub = 1
+			component: /Policy/policy/input_sources/voice_communication/applicable_input_device/mask
+				communication = 0
+				ambient = 0
+				builtin_mic = 0
+				bluetooth_sco_headset = 0
+				wired_headset = 0
+				hdmi = 0
+				telephony_rx = 0
+				back_mic = 0
+				remote_submix = 0
+				anlg_dock_headset = 0
+				dgtl_dock_headset = 0>
+				usb_accessory = 0
+				usb_device = 0
+				fm_tuner = 0
+				tv_tuner = 0
+				line = 0
+				spdif = 0
+				bluetooth_a2dp = 0
+				loopback = 0
+				ip = 0
+				bus = 0
+				stub = 1
+			component: /Policy/policy/input_sources/remote_submix/applicable_input_device/mask
+				communication = 0
+				ambient = 0
+				builtin_mic = 0
+				bluetooth_sco_headset = 0
+				wired_headset = 0
+				hdmi = 0
+				telephony_rx = 0
+				back_mic = 0
+				remote_submix = 0
+				anlg_dock_headset = 0
+				dgtl_dock_headset = 0>
+				usb_accessory = 0
+				usb_device = 0
+				fm_tuner = 0
+				tv_tuner = 0
+				line = 0
+				spdif = 0
+				bluetooth_a2dp = 0
+				loopback = 0
+				ip = 0
+				bus = 0
+				stub = 1
+			component: /Policy/policy/input_sources/hotword/applicable_input_device/mask
+				communication = 0
+				ambient = 0
+				builtin_mic = 0
+				bluetooth_sco_headset = 0
+				wired_headset = 0
+				hdmi = 0
+				telephony_rx = 0
+				back_mic = 0
+				remote_submix = 0
+				anlg_dock_headset = 0
+				dgtl_dock_headset = 0>
+				usb_accessory = 0
+				usb_device = 0
+				fm_tuner = 0
+				tv_tuner = 0
+				line = 0
+				spdif = 0
+				bluetooth_a2dp = 0
+				loopback = 0
+				ip = 0
+				bus = 0
+				stub = 1
+			component: /Policy/policy/input_sources/unprocessed/applicable_input_device/mask
+				communication = 0
+				ambient = 0
+				builtin_mic = 0
+				bluetooth_sco_headset = 0
+				wired_headset = 0
+				hdmi = 0
+				telephony_rx = 0
+				back_mic = 0
+				remote_submix = 0
+				anlg_dock_headset = 0
+				dgtl_dock_headset = 0>
+				usb_accessory = 0
+				usb_device = 0
+				fm_tuner = 0
+				tv_tuner = 0
+				line = 0
+				spdif = 0
+				bluetooth_a2dp = 0
+				loopback = 0
+				ip = 0
+				bus = 0
+				stub = 1
+			component: /Policy/policy/input_sources/fm_tuner/applicable_input_device/mask
+				communication = 0
+				ambient = 0
+				builtin_mic = 0
+				bluetooth_sco_headset = 0
+				wired_headset = 0
+				hdmi = 0
+				telephony_rx = 0
+				back_mic = 0
+				remote_submix = 0
+				anlg_dock_headset = 0
+				dgtl_dock_headset = 0>
+				usb_accessory = 0
+				usb_device = 0
+				fm_tuner = 0
+				tv_tuner = 0
+				line = 0
+				spdif = 0
+				bluetooth_a2dp = 0
+				loopback = 0
+				ip = 0
+				bus = 0
+				stub = 1
+
+
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/SettingsNoOutput/device_for_strategies.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/examples/SettingsNoOutput/device_for_strategies.pfw
new file mode 100644
index 0000000..917d4a7
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/SettingsNoOutput/device_for_strategies.pfw
@@ -0,0 +1,255 @@
+domain: DeviceForStrategy
+	conf: Calibration
+		component: /Policy/policy/strategies
+			component: media/selected_output_devices/mask
+				earpiece = 0
+				speaker = 0
+				wired_headset = 0
+				wired_headphone = 0
+				bluetooth_sco = 0
+				bluetooth_sco_headset = 0
+				bluetooth_sco_carkit = 0
+				bluetooth_a2dp = 0>
+				bluetooth_a2dp_headphones = 0
+				bluetooth_a2dp_speaker = 0
+				hdmi = 0
+				angl_dock_headset = 0
+				dgtl_dock_headset = 0
+				usb_accessory = 0
+				usb_device = 0
+				remote_submix = 0
+				telephony_tx = 0
+				line = 0
+				hdmi_arc = 0
+				spdif = 0
+				fm = 0
+				aux_line = 0
+				speaker_safe = 0
+				ip = 0
+				bus = 0
+				stub = 1
+
+			component: phone/selected_output_devices/mask
+				earpiece = 0
+				speaker = 0
+				wired_headset = 0
+				wired_headphone = 0
+				bluetooth_sco = 0
+				bluetooth_sco_headset = 0
+				bluetooth_sco_carkit = 0
+				bluetooth_a2dp = 0>
+				bluetooth_a2dp_headphones = 0
+				bluetooth_a2dp_speaker = 0
+				hdmi = 0
+				angl_dock_headset = 0
+				dgtl_dock_headset = 0
+				usb_accessory = 0
+				usb_device = 0
+				remote_submix = 0
+				telephony_tx = 0
+				line = 0
+				hdmi_arc = 0
+				spdif = 0
+				fm = 0
+				aux_line = 0
+				speaker_safe = 0
+				ip = 0
+				bus = 0
+				stub = 1
+
+			component: sonification/selected_output_devices/mask
+				earpiece = 0
+				speaker = 0
+				wired_headset = 0
+				wired_headphone = 0
+				bluetooth_sco = 0
+				bluetooth_sco_headset = 0
+				bluetooth_sco_carkit = 0
+				bluetooth_a2dp = 0>
+				bluetooth_a2dp_headphones = 0
+				bluetooth_a2dp_speaker = 0
+				hdmi = 0
+				angl_dock_headset = 0
+				dgtl_dock_headset = 0
+				usb_accessory = 0
+				usb_device = 0
+				remote_submix = 0
+				telephony_tx = 0
+				line = 0
+				hdmi_arc = 0
+				spdif = 0
+				fm = 0
+				aux_line = 0
+				speaker_safe = 0
+				ip = 0
+				bus = 0
+				stub = 1
+
+			component: sonification_respectful/selected_output_devices/mask
+				earpiece = 0
+				speaker = 0
+				wired_headset = 0
+				wired_headphone = 0
+				bluetooth_sco = 0
+				bluetooth_sco_headset = 0
+				bluetooth_sco_carkit = 0
+				bluetooth_a2dp = 0>
+				bluetooth_a2dp_headphones = 0
+				bluetooth_a2dp_speaker = 0
+				hdmi = 0
+				angl_dock_headset = 0
+				dgtl_dock_headset = 0
+				usb_accessory = 0
+				usb_device = 0
+				remote_submix = 0
+				telephony_tx = 0
+				line = 0
+				hdmi_arc = 0
+				spdif = 0
+				fm = 0
+				aux_line = 0
+				speaker_safe = 0
+				ip = 0
+				bus = 0
+				stub = 1
+
+			component: dtmf/selected_output_devices/mask
+				earpiece = 0
+				speaker = 0
+				wired_headset = 0
+				wired_headphone = 0
+				bluetooth_sco = 0
+				bluetooth_sco_headset = 0
+				bluetooth_sco_carkit = 0
+				bluetooth_a2dp = 0>
+				bluetooth_a2dp_headphones = 0
+				bluetooth_a2dp_speaker = 0
+				hdmi = 0
+				angl_dock_headset = 0
+				dgtl_dock_headset = 0
+				usb_accessory = 0
+				usb_device = 0
+				remote_submix = 0
+				telephony_tx = 0
+				line = 0
+				hdmi_arc = 0
+				spdif = 0
+				fm = 0
+				aux_line = 0
+				speaker_safe = 0
+				ip = 0
+				bus = 0
+				stub = 1
+
+			component: enforced_audible/selected_output_devices/mask
+				earpiece = 0
+				speaker = 0
+				wired_headset = 0
+				wired_headphone = 0
+				bluetooth_sco = 0
+				bluetooth_sco_headset = 0
+				bluetooth_sco_carkit = 0
+				bluetooth_a2dp = 0>
+				bluetooth_a2dp_headphones = 0
+				bluetooth_a2dp_speaker = 0
+				hdmi = 0
+				angl_dock_headset = 0
+				dgtl_dock_headset = 0
+				usb_accessory = 0
+				usb_device = 0
+				remote_submix = 0
+				telephony_tx = 0
+				line = 0
+				hdmi_arc = 0
+				spdif = 0
+				fm = 0
+				aux_line = 0
+				speaker_safe = 0
+				ip = 0
+				bus = 0
+				stub = 1
+
+			component: transmitted_through_speaker/selected_output_devices/mask
+				earpiece = 0
+				speaker = 0
+				wired_headset = 0
+				wired_headphone = 0
+				bluetooth_sco = 0
+				bluetooth_sco_headset = 0
+				bluetooth_sco_carkit = 0
+				bluetooth_a2dp = 0>
+				bluetooth_a2dp_headphones = 0
+				bluetooth_a2dp_speaker = 0
+				hdmi = 0
+				angl_dock_headset = 0
+				dgtl_dock_headset = 0
+				usb_accessory = 0
+				usb_device = 0
+				remote_submix = 0
+				telephony_tx = 0
+				line = 0
+				hdmi_arc = 0
+				spdif = 0
+				fm = 0
+				aux_line = 0
+				speaker_safe = 0
+				ip = 0
+				bus = 0
+				stub = 1
+
+			component: accessibility/selected_output_devices/mask
+				earpiece = 0
+				speaker = 0
+				wired_headset = 0
+				wired_headphone = 0
+				bluetooth_sco = 0
+				bluetooth_sco_headset = 0
+				bluetooth_sco_carkit = 0
+				bluetooth_a2dp = 0>
+				bluetooth_a2dp_headphones = 0
+				bluetooth_a2dp_speaker = 0
+				hdmi = 0
+				angl_dock_headset = 0
+				dgtl_dock_headset = 0
+				usb_accessory = 0
+				usb_device = 0
+				remote_submix = 0
+				telephony_tx = 0
+				line = 0
+				hdmi_arc = 0
+				spdif = 0
+				fm = 0
+				aux_line = 0
+				speaker_safe = 0
+				ip = 0
+				bus = 0
+				stub = 1
+
+			component: rerouting/selected_output_devices/mask
+				earpiece = 0
+				speaker = 0
+				wired_headset = 0
+				wired_headphone = 0
+				bluetooth_sco = 0
+				bluetooth_sco_headset = 0
+				bluetooth_sco_carkit = 0
+				bluetooth_a2dp = 0>
+				bluetooth_a2dp_headphones = 0
+				bluetooth_a2dp_speaker = 0
+				hdmi = 0
+				angl_dock_headset = 0
+				dgtl_dock_headset = 0
+				usb_accessory = 0
+				usb_device = 0
+				remote_submix = 0
+				telephony_tx = 0
+				line = 0
+				hdmi_arc = 0
+				spdif = 0
+				fm = 0
+				aux_line = 0
+				speaker_safe = 0
+				ip = 0
+				bus = 0
+				stub = 1
+
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/example/Structure/PolicyClass.xml b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Structure/PolicyClass.xml
similarity index 100%
rename from services/audiopolicy/engineconfigurable/parameter-framework/example/Structure/PolicyClass.xml
rename to services/audiopolicy/engineconfigurable/parameter-framework/examples/Structure/PolicyClass.xml
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/example/Structure/PolicySubsystem-CommonTypes.xml b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Structure/PolicySubsystem-CommonTypes.xml
similarity index 93%
rename from services/audiopolicy/engineconfigurable/parameter-framework/example/Structure/PolicySubsystem-CommonTypes.xml
rename to services/audiopolicy/engineconfigurable/parameter-framework/examples/Structure/PolicySubsystem-CommonTypes.xml
index 6d6145a..461e44a 100755
--- a/services/audiopolicy/engineconfigurable/parameter-framework/example/Structure/PolicySubsystem-CommonTypes.xml
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Structure/PolicySubsystem-CommonTypes.xml
@@ -35,6 +35,9 @@
             <BitParameter Name="fm" Size="1" Pos="20"/>
             <BitParameter Name="aux_line" Size="1" Pos="21"/>
             <BitParameter Name="speaker_safe" Size="1" Pos="22"/>
+            <BitParameter Name="ip" Size="1" Pos="23"/>
+            <BitParameter Name="bus" Size="1" Pos="24"/>
+            <BitParameter Name="stub" Size="1" Pos="30"/>
         </BitParameterBlock>
     </ComponentType>
 
@@ -62,7 +65,9 @@
             <BitParameter Name="spdif" Size="1" Pos="16"/>
             <BitParameter Name="bluetooth_a2dp" Size="1" Pos="17"/>
             <BitParameter Name="loopback" Size="1" Pos="18"/>
-            <BitParameter Name="in" Size="1" Pos="31"/>
+            <BitParameter Name="ip" Size="1" Pos="19"/>
+            <BitParameter Name="bus" Size="1" Pos="20"/>
+            <BitParameter Name="stub" Size="1" Pos="30"/>
         </BitParameterBlock>
     </ComponentType>
 
@@ -83,6 +88,10 @@
             <BitParameter Name="compress_offload" Size="1" Pos="4"/>
             <BitParameter Name="non_blocking" Size="1" Pos="5"/>
             <BitParameter Name="hw_av_sync" Size="1" Pos="6"/>
+            <BitParameter Name="tts" Size="1" Pos="7"/>
+            <BitParameter Name="raw" Size="1" Pos="8"/>
+            <BitParameter Name="sync" Size="1" Pos="9"/>
+            <BitParameter Name="iec958_nonaudio" Size="1" Pos="10"/>
         </BitParameterBlock>
     </ComponentType>
 
@@ -94,6 +103,8 @@
         <BitParameterBlock Name="mask" Size="32">
             <BitParameter Name="fast" Size="1" Pos="0"/>
             <BitParameter Name="hw_hotword" Size="1" Pos="2"/>
+            <BitParameter Name="raw" Size="1" Pos="3"/>
+            <BitParameter Name="sync" Size="1" Pos="4"/>
         </BitParameterBlock>
     </ComponentType>
 
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/example/Structure/PolicySubsystem.xml b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Structure/PolicySubsystem.xml
similarity index 100%
rename from services/audiopolicy/engineconfigurable/parameter-framework/example/Structure/PolicySubsystem.xml
rename to services/audiopolicy/engineconfigurable/parameter-framework/examples/Structure/PolicySubsystem.xml
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/example/policy_criteria.txt b/services/audiopolicy/engineconfigurable/parameter-framework/examples/policy_criteria.txt
similarity index 96%
rename from services/audiopolicy/engineconfigurable/parameter-framework/example/policy_criteria.txt
rename to services/audiopolicy/engineconfigurable/parameter-framework/examples/policy_criteria.txt
index 28a7ef1..480cbe1 100755
--- a/services/audiopolicy/engineconfigurable/parameter-framework/example/policy_criteria.txt
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/policy_criteria.txt
@@ -1,6 +1,6 @@
 ExclusiveCriterion TelephonyMode                :   Normal          RingTone                InCall              InCommunication
-InclusiveCriterion AvailableInputDevices        :   Communication Ambient BuiltinMic BluetoothScoHeadset WiredHeadset Hdmi TelephonyRx BackMic RemoteSubmix AnlgDockHeadset DgtlDockHeadset UsbAccessory UsbDevice FmTuner TvTuner Line Spdif BluetoothA2dp Loopback
-InclusiveCriterion AvailableOutputDevices       :   Earpiece Speaker WiredSpeaker WiredHeadset WiredHeadphone BluetoothSco BluetoothScoHeadset BluetoothScoCarkit BluetoothA2dp BluetoothA2dpHeadphones BluetoothA2dpSpeaker Hdmi AnlgDockHeadset DgtlDockHeadset UsbAccessory UsbDevice RemoteSubmix TelephonyTx Line HdmiArc Spdif Fm AuxLine SpeakerSafe
+InclusiveCriterion AvailableInputDevices        :   Communication Ambient BuiltinMic BluetoothScoHeadset WiredHeadset Hdmi TelephonyRx BackMic RemoteSubmix AnlgDockHeadset DgtlDockHeadset UsbAccessory UsbDevice FmTuner TvTuner Line Spdif BluetoothA2dp Loopback Ip Bus Stub
+InclusiveCriterion AvailableOutputDevices       :   Earpiece Speaker WiredSpeaker WiredHeadset WiredHeadphone BluetoothSco BluetoothScoHeadset BluetoothScoCarkit BluetoothA2dp BluetoothA2dpHeadphones BluetoothA2dpSpeaker Hdmi AnlgDockHeadset DgtlDockHeadset UsbAccessory UsbDevice RemoteSubmix TelephonyTx Line HdmiArc Spdif Fm AuxLine SpeakerSafe Ip Bus Stub
 ExclusiveCriterion ForceUseForCommunication     :   ForceNone       ForceSpeaker            ForceBtSco
 ExclusiveCriterion ForceUseForMedia             :   ForceNone       ForceSpeaker			ForceHeadphones         ForceBtA2dp         ForceWiredAccessory ForceAnalogDock ForceDigitalDock    ForceNoBtA2dp       ForceSystemEnforced
 ExclusiveCriterion ForceUseForRecord            :   ForceNone       ForceBtSco              ForceWiredAccessory
diff --git a/services/audiopolicy/engineconfigurable/src/InputSource.cpp b/services/audiopolicy/engineconfigurable/src/InputSource.cpp
index 9ff1538..ae39fef 100755
--- a/services/audiopolicy/engineconfigurable/src/InputSource.cpp
+++ b/services/audiopolicy/engineconfigurable/src/InputSource.cpp
@@ -36,8 +36,7 @@
 
 /**
 * Set the device associated to this source.
-* It checks if the input device is valid but allows to set a NONE device
-* (i.e. only the IN BIT is set).
+* It checks if the input device is valid.
 *
 * @param[in] devices selected for the given input source.
 * @tparam audio_devices_t: Applicable input device for this input source.
@@ -47,7 +46,10 @@
 template <>
 status_t Element<audio_source_t>::set(audio_devices_t devices)
 {
-    if (!audio_is_input_device(devices) && devices != AUDIO_DEVICE_BIT_IN) {
+    if (devices != AUDIO_DEVICE_NONE) {
+        devices |= AUDIO_DEVICE_BIT_IN;
+    }
+    if (!audio_is_input_device(devices)) {
         ALOGE("%s: trying to set an invalid device 0x%X for input source %s",
               __FUNCTION__, devices, getName().c_str());
         return BAD_VALUE;
diff --git a/services/audiopolicy/engineconfigurable/src/Strategy.cpp b/services/audiopolicy/engineconfigurable/src/Strategy.cpp
index 847443a..a539914 100755
--- a/services/audiopolicy/engineconfigurable/src/Strategy.cpp
+++ b/services/audiopolicy/engineconfigurable/src/Strategy.cpp
@@ -37,7 +37,7 @@
 
 /**
  * Set the device associated to this strategy.
- * It checks if the output device is valid but allows to set a NONE device
+ * It checks if the output device is valid.
  *
  * @param[in] devices selected for the given strategy.
  *
@@ -46,7 +46,7 @@
 template <>
 status_t Element<routing_strategy>::set<audio_devices_t>(audio_devices_t devices)
 {
-    if (!audio_is_output_devices(devices) && devices != AUDIO_DEVICE_NONE) {
+    if (!audio_is_output_devices(devices) || devices == AUDIO_DEVICE_NONE) {
         ALOGE("%s: trying to set an invalid device 0x%X for strategy %s",
               __FUNCTION__, devices, getName().c_str());
         return BAD_VALUE;
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 21ce8c9..00fd05a 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -4898,7 +4898,7 @@
                                         int index,
                                         audio_devices_t device)
 {
-    float volumeDb = mVolumeCurves->volIndexToDb(stream, Volume::getDeviceCategory(device), index);
+    float volumeDB = mVolumeCurves->volIndexToDb(stream, Volume::getDeviceCategory(device), index);
     // if a headset is connected, apply the following rules to ring tones and notifications
     // to avoid sound level bursts in user's ears:
     // - always attenuate notifications volume by 6dB
@@ -4922,7 +4922,7 @@
         // just stopped
         if (isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY) ||
                 mLimitRingtoneVolume) {
-            volumeDb += SONIFICATION_HEADSET_VOLUME_FACTOR_DB;
+            volumeDB += SONIFICATION_HEADSET_VOLUME_FACTOR_DB;
             audio_devices_t musicDevice = getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/);
             float musicVolDB = computeVolume(AUDIO_STREAM_MUSIC,
                                              mVolumeCurves->getVolumeIndex(AUDIO_STREAM_MUSIC,
@@ -4930,17 +4930,29 @@
                                              musicDevice);
             float minVolDB = (musicVolDB > SONIFICATION_HEADSET_VOLUME_MIN_DB) ?
                     musicVolDB : SONIFICATION_HEADSET_VOLUME_MIN_DB;
-            if (volumeDb > minVolDB) {
-                volumeDb = minVolDB;
+            if (volumeDB > minVolDB) {
+                volumeDB = minVolDB;
                 ALOGV("computeVolume limiting volume to %f musicVol %f", minVolDB, musicVolDB);
             }
+            if (device & (AUDIO_DEVICE_OUT_BLUETOOTH_A2DP |
+                    AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES)) {
+                // on A2DP, also ensure notification volume is not too low compared to media when
+                // intended to be played
+                if ((volumeDB > -96.0f) &&
+                        (musicVolDB - SONIFICATION_A2DP_MAX_MEDIA_DIFF_DB > volumeDB)) {
+                    ALOGV("computeVolume increasing volume for stream=%d device=0x%X from %f to %f",
+                            stream, device,
+                            volumeDB, musicVolDB - SONIFICATION_A2DP_MAX_MEDIA_DIFF_DB);
+                    volumeDB = musicVolDB - SONIFICATION_A2DP_MAX_MEDIA_DIFF_DB;
+                }
+            }
         } else if ((Volume::getDeviceForVolume(device) != AUDIO_DEVICE_OUT_SPEAKER) ||
                 stream_strategy != STRATEGY_SONIFICATION) {
-            volumeDb += SONIFICATION_HEADSET_VOLUME_FACTOR_DB;
+            volumeDB += SONIFICATION_HEADSET_VOLUME_FACTOR_DB;
         }
     }
 
-    return volumeDb;
+    return volumeDB;
 }
 
 status_t AudioPolicyManager::checkAndSetVolume(audio_stream_type_t stream,
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 2d6a873..6c3e416 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -52,6 +52,8 @@
 #define SONIFICATION_HEADSET_VOLUME_FACTOR_DB (-6)
 // Min volume for STRATEGY_SONIFICATION streams when limited by music volume: -36dB
 #define SONIFICATION_HEADSET_VOLUME_MIN_DB  (-36)
+// Max volume difference on A2DP between playing media and STRATEGY_SONIFICATION streams: 12dB
+#define SONIFICATION_A2DP_MAX_MEDIA_DIFF_DB (12)
 
 // Time in milliseconds during which we consider that music is still active after a music
 // track was stopped - see computeVolume()
diff --git a/services/audiopolicy/service/AudioPolicyClientImplLegacy.cpp b/services/audiopolicy/service/AudioPolicyClientImplLegacy.cpp
index 09a931f..151d066 100644
--- a/services/audiopolicy/service/AudioPolicyClientImplLegacy.cpp
+++ b/services/audiopolicy/service/AudioPolicyClientImplLegacy.cpp
@@ -190,7 +190,8 @@
     }
 
     if (((*pDevices & AUDIO_DEVICE_IN_REMOTE_SUBMIX) == AUDIO_DEVICE_IN_REMOTE_SUBMIX)
-            && !captureAudioOutputAllowed()) {
+            && !captureAudioOutputAllowed(IPCThreadState::self()->getCallingPid(),
+                                          IPCThreadState::self()->getCallingUid())) {
         ALOGE("open_input() permission denied: capture not allowed");
         return AUDIO_IO_HANDLE_NONE;
     }
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 92a1285..c9b3abc 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -260,6 +260,7 @@
 status_t AudioPolicyService::getInputForAttr(const audio_attributes_t *attr,
                                              audio_io_handle_t *input,
                                              audio_session_t session,
+                                             pid_t pid,
                                              uid_t uid,
                                              uint32_t samplingRate,
                                              audio_format_t format,
@@ -282,11 +283,22 @@
     sp<AudioPolicyEffects>audioPolicyEffects;
     status_t status;
     AudioPolicyInterface::input_type_t inputType;
+
+    bool updatePid = (pid == -1);
     const uid_t callingUid = IPCThreadState::self()->getCallingUid();
-    if (!isTrustedCallingUid(callingUid) || uid == (uid_t)-1) {
+    if (!isTrustedCallingUid(callingUid)) {
         ALOGW_IF(uid != (uid_t)-1 && uid != callingUid,
                 "%s uid %d tried to pass itself off as %d", __FUNCTION__, callingUid, uid);
         uid = callingUid;
+        updatePid = true;
+    }
+
+    if (updatePid) {
+        const pid_t callingPid = IPCThreadState::self()->getCallingPid();
+        ALOGW_IF(pid != (pid_t)-1 && pid != callingPid,
+                 "%s uid %d pid %d tried to pass itself off as pid %d",
+                 __func__, callingUid, callingPid, pid);
+        pid = callingPid;
     }
 
     {
@@ -306,7 +318,7 @@
             case AudioPolicyInterface::API_INPUT_TELEPHONY_RX:
                 // FIXME: use the same permission as for remote submix for now.
             case AudioPolicyInterface::API_INPUT_MIX_CAPTURE:
-                if (!captureAudioOutputAllowed()) {
+                if (!captureAudioOutputAllowed(pid, uid)) {
                     ALOGE("getInputForAttr() permission denied: capture not allowed");
                     status = PERMISSION_DENIED;
                 }
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp
index c830454..7c9315d 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp
@@ -234,6 +234,7 @@
 status_t AudioPolicyService::getInputForAttr(const audio_attributes_t *attr,
                                              audio_io_handle_t *input,
                                              audio_session_t session,
+                                             pid_t pid __unused,
                                              uid_t uid __unused,
                                              uint32_t samplingRate,
                                              audio_format_t format,
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index 2710ac7..0b2cb35 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -99,6 +99,7 @@
     virtual status_t getInputForAttr(const audio_attributes_t *attr,
                                      audio_io_handle_t *input,
                                      audio_session_t session,
+                                     pid_t pid,
                                      uid_t uid,
                                      uint32_t samplingRate,
                                      audio_format_t format,
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 0e4e244..c0de95a 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -2967,19 +2967,28 @@
 }
 
 void Camera3Device::RequestThread::checkAndStopRepeatingRequest() {
-    Mutex::Autolock l(mRequestLock);
-    // Check all streams needed by repeating requests are still valid. Otherwise, stop
-    // repeating requests.
-    for (const auto& request : mRepeatingRequests) {
-        for (const auto& s : request->mOutputStreams) {
-            if (s->isAbandoned()) {
-                int64_t lastFrameNumber = 0;
-                clearRepeatingRequestsLocked(&lastFrameNumber);
-                mListener->notifyRepeatingRequestError(lastFrameNumber);
-                return;
+    bool surfaceAbandoned = false;
+    int64_t lastFrameNumber = 0;
+    {
+        Mutex::Autolock l(mRequestLock);
+        // Check all streams needed by repeating requests are still valid. Otherwise, stop
+        // repeating requests.
+        for (const auto& request : mRepeatingRequests) {
+            for (const auto& s : request->mOutputStreams) {
+                if (s->isAbandoned()) {
+                    surfaceAbandoned = true;
+                    clearRepeatingRequestsLocked(&lastFrameNumber);
+                    break;
+                }
+            }
+            if (surfaceAbandoned) {
+                break;
             }
         }
     }
+    if (surfaceAbandoned) {
+        mListener->notifyRepeatingRequestError(lastFrameNumber);
+    }
 }
 
 bool Camera3Device::RequestThread::threadLoop() {