Merge "media: changed resource type from String8 to enum." into nyc-dev
diff --git a/camera/CameraMetadata.cpp b/camera/CameraMetadata.cpp
index fad57ba..c78fc5d 100644
--- a/camera/CameraMetadata.cpp
+++ b/camera/CameraMetadata.cpp
@@ -79,7 +79,7 @@
     return mBuffer;
 }
 
-status_t CameraMetadata::unlock(const camera_metadata_t *buffer) {
+status_t CameraMetadata::unlock(const camera_metadata_t *buffer) const {
     if (!mLocked) {
         ALOGE("%s: Can't unlock a non-locked CameraMetadata!", __FUNCTION__);
         return INVALID_OPERATION;
diff --git a/camera/ndk/Android.mk b/camera/ndk/Android.mk
index ebd473d..40dbeef 100644
--- a/camera/ndk/Android.mk
+++ b/camera/ndk/Android.mk
@@ -49,6 +49,7 @@
     libcamera_client \
     libstagefright_foundation \
     libcutils \
+    libcamera_metadata
 
 LOCAL_CLANG := true
 
diff --git a/camera/ndk/NdkCameraMetadata.cpp b/camera/ndk/NdkCameraMetadata.cpp
index 18718d3..85fe75b 100644
--- a/camera/ndk/NdkCameraMetadata.cpp
+++ b/camera/ndk/NdkCameraMetadata.cpp
@@ -39,6 +39,18 @@
 }
 
 EXPORT
+camera_status_t ACameraMetadata_getAllTags(
+        const ACameraMetadata* acm, /*out*/int32_t* numTags, /*out*/const uint32_t** tags) {
+    ATRACE_CALL();
+    if (acm == nullptr || numTags == nullptr || tags == nullptr) {
+        ALOGE("%s: invalid argument! metadata %p, numTags %p, tags %p",
+               __FUNCTION__, acm, numTags, tags);
+        return ACAMERA_ERROR_INVALID_PARAMETER;
+    }
+    return acm->getTags(numTags, tags);
+}
+
+EXPORT
 ACameraMetadata* ACameraMetadata_copy(const ACameraMetadata* src) {
     ATRACE_CALL();
     if (src == nullptr) {
diff --git a/camera/ndk/NdkCaptureRequest.cpp b/camera/ndk/NdkCaptureRequest.cpp
index 4fee09c..77b9a33 100644
--- a/camera/ndk/NdkCaptureRequest.cpp
+++ b/camera/ndk/NdkCaptureRequest.cpp
@@ -87,6 +87,18 @@
     return req->settings->getConstEntry(tag, entry);
 }
 
+EXPORT
+camera_status_t ACaptureRequest_getAllTags(
+        const ACaptureRequest* req, /*out*/int32_t* numTags, /*out*/const uint32_t** tags) {
+    ATRACE_CALL();
+    if (req == nullptr || numTags == nullptr || tags == nullptr) {
+        ALOGE("%s: invalid argument! request %p, numTags %p, tags %p",
+               __FUNCTION__, req, numTags, tags);
+        return ACAMERA_ERROR_INVALID_PARAMETER;
+    }
+    return req->settings->getTags(numTags, tags);
+}
+
 #define SET_ENTRY(NAME,NDK_TYPE)                                                        \
 EXPORT                                                                                  \
 camera_status_t ACaptureRequest_setEntry_##NAME(                                        \
diff --git a/camera/ndk/impl/ACameraCaptureSession.cpp b/camera/ndk/impl/ACameraCaptureSession.cpp
index 7f1b75d..b741e46 100644
--- a/camera/ndk/impl/ACameraCaptureSession.cpp
+++ b/camera/ndk/impl/ACameraCaptureSession.cpp
@@ -39,6 +39,15 @@
 
 void
 ACameraCaptureSession::closeByApp() {
+    {
+        Mutex::Autolock _l(mSessionLock);
+        if (mClosedByApp) {
+            // Do not close twice
+            return;
+        }
+        mClosedByApp = true;
+    }
+
     sp<CameraDevice> dev = getDeviceSp();
     if (dev != nullptr) {
         dev->lockDeviceForSessionOps();
diff --git a/camera/ndk/impl/ACameraCaptureSession.h b/camera/ndk/impl/ACameraCaptureSession.h
index 1db1b21..f20b324 100644
--- a/camera/ndk/impl/ACameraCaptureSession.h
+++ b/camera/ndk/impl/ACameraCaptureSession.h
@@ -103,6 +103,7 @@
     const ACameraCaptureSession_stateCallbacks mUserSessionCallback;
     const wp<CameraDevice> mDevice;
     bool  mIsClosed = false;
+    bool  mClosedByApp = false;
     bool  mIdle = true;
     Mutex mSessionLock;
 };
diff --git a/camera/ndk/impl/ACameraDevice.cpp b/camera/ndk/impl/ACameraDevice.cpp
index 880befe..6bca692 100644
--- a/camera/ndk/impl/ACameraDevice.cpp
+++ b/camera/ndk/impl/ACameraDevice.cpp
@@ -76,8 +76,8 @@
     mHandler = new CallbackHandler();
     mCbLooper->registerHandler(mHandler);
 
-    CameraMetadata metadata = mChars->mData;
-    camera_metadata_entry entry = metadata.find(ANDROID_REQUEST_PARTIAL_RESULT_COUNT);
+    const CameraMetadata& metadata = mChars->getInternalData();
+    camera_metadata_ro_entry entry = metadata.find(ANDROID_REQUEST_PARTIAL_RESULT_COUNT);
     if (entry.count != 1) {
         ALOGW("%s: bad count %zu for partial result count", __FUNCTION__, entry.count);
         mPartialResultCount = 1;
@@ -279,7 +279,7 @@
         const ACaptureRequest* request, /*out*/sp<CaptureRequest>& outReq) {
     camera_status_t ret;
     sp<CaptureRequest> req(new CaptureRequest());
-    req->mMetadata = request->settings->mData;
+    req->mMetadata = request->settings->getInternalData();
     req->mIsReprocess = false; // NDK does not support reprocessing yet
 
     for (auto outputTarget : request->targets->mOutputs) {
diff --git a/camera/ndk/impl/ACameraMetadata.cpp b/camera/ndk/impl/ACameraMetadata.cpp
index fbc8d19..8366ade 100644
--- a/camera/ndk/impl/ACameraMetadata.cpp
+++ b/camera/ndk/impl/ACameraMetadata.cpp
@@ -162,6 +162,8 @@
         return ACAMERA_ERROR_INVALID_PARAMETER;
     }
 
+    Mutex::Autolock _l(mLock);
+
     camera_metadata_ro_entry rawEntry = mData.find(tag);
     if (rawEntry.count == 0) {
         ALOGE("%s: cannot find metadata tag %d", __FUNCTION__, tag);
@@ -204,6 +206,38 @@
     return updateImpl<camera_metadata_rational_t>(tag, count, data);
 }
 
+camera_status_t
+ACameraMetadata::getTags(/*out*/int32_t* numTags,
+                         /*out*/const uint32_t** tags) const {
+    Mutex::Autolock _l(mLock);
+    if (mTags.size() == 0) {
+        size_t entry_count = mData.entryCount();
+        mTags.setCapacity(entry_count);
+        const camera_metadata_t* rawMetadata = mData.getAndLock();
+        for (size_t i = 0; i < entry_count; i++) {
+            camera_metadata_ro_entry_t entry;
+            int ret = get_camera_metadata_ro_entry(rawMetadata, i, &entry);
+            if (ret != 0) {
+                ALOGE("%s: error reading metadata index %zu", __FUNCTION__, i);
+                return ACAMERA_ERROR_UNKNOWN;
+            }
+            // Hide system key from users
+            if (sSystemTags.count(entry.tag) == 0) {
+                mTags.push_back(entry.tag);
+            }
+        }
+        mData.unlock(rawMetadata);
+    }
+
+    *numTags = mTags.size();
+    *tags = mTags.array();
+    return ACAMERA_OK;
+}
+
+const CameraMetadata&
+ACameraMetadata::getInternalData() {
+    return mData;
+}
 
 // TODO: some of key below should be hidden from user
 // ex: ACAMERA_REQUEST_ID and ACAMERA_REPROCESS_EFFECTIVE_EXPOSURE_FACTOR
@@ -286,6 +320,49 @@
     }
 }
 
+// System tags that should be hidden from users
+std::unordered_set<uint32_t> ACameraMetadata::sSystemTags ({
+    ANDROID_CONTROL_SCENE_MODE_OVERRIDES,
+    ANDROID_CONTROL_AE_PRECAPTURE_ID,
+    ANDROID_CONTROL_AF_TRIGGER_ID,
+    ANDROID_DEMOSAIC_MODE,
+    ANDROID_EDGE_STRENGTH,
+    ANDROID_FLASH_FIRING_POWER,
+    ANDROID_FLASH_FIRING_TIME,
+    ANDROID_FLASH_COLOR_TEMPERATURE,
+    ANDROID_FLASH_MAX_ENERGY,
+    ANDROID_FLASH_INFO_CHARGE_DURATION,
+    ANDROID_JPEG_MAX_SIZE,
+    ANDROID_JPEG_SIZE,
+    ANDROID_NOISE_REDUCTION_STRENGTH,
+    ANDROID_QUIRKS_METERING_CROP_REGION,
+    ANDROID_QUIRKS_TRIGGER_AF_WITH_AUTO,
+    ANDROID_QUIRKS_USE_ZSL_FORMAT,
+    ANDROID_REQUEST_INPUT_STREAMS,
+    ANDROID_REQUEST_METADATA_MODE,
+    ANDROID_REQUEST_OUTPUT_STREAMS,
+    ANDROID_REQUEST_TYPE,
+    ANDROID_REQUEST_MAX_NUM_REPROCESS_STREAMS,
+    ANDROID_SCALER_AVAILABLE_RAW_MIN_DURATIONS,
+    ANDROID_SCALER_AVAILABLE_RAW_SIZES,
+    ANDROID_SENSOR_BASE_GAIN_FACTOR,
+    ANDROID_SENSOR_PROFILE_HUE_SAT_MAP_DIMENSIONS,
+    ANDROID_SENSOR_TEMPERATURE,
+    ANDROID_SENSOR_PROFILE_HUE_SAT_MAP,
+    ANDROID_SENSOR_PROFILE_TONE_CURVE,
+    ANDROID_SENSOR_OPAQUE_RAW_SIZE,
+    ANDROID_SHADING_STRENGTH,
+    ANDROID_STATISTICS_HISTOGRAM_MODE,
+    ANDROID_STATISTICS_SHARPNESS_MAP_MODE,
+    ANDROID_STATISTICS_HISTOGRAM,
+    ANDROID_STATISTICS_SHARPNESS_MAP,
+    ANDROID_STATISTICS_INFO_HISTOGRAM_BUCKET_COUNT,
+    ANDROID_STATISTICS_INFO_MAX_HISTOGRAM_COUNT,
+    ANDROID_STATISTICS_INFO_MAX_SHARPNESS_MAP_VALUE,
+    ANDROID_STATISTICS_INFO_SHARPNESS_MAP_SIZE,
+    ANDROID_DEPTH_MAX_DEPTH_SAMPLES,
+});
+
 /*~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
  * End generated code
  *~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~O@*/
diff --git a/camera/ndk/impl/ACameraMetadata.h b/camera/ndk/impl/ACameraMetadata.h
index 442e1dd..ab651a1 100644
--- a/camera/ndk/impl/ACameraMetadata.h
+++ b/camera/ndk/impl/ACameraMetadata.h
@@ -16,8 +16,12 @@
 #ifndef _ACAMERA_METADATA_H
 #define _ACAMERA_METADATA_H
 
+#include <unordered_set>
+
 #include <sys/types.h>
+#include <utils/Mutex.h>
 #include <utils/RefBase.h>
+#include <utils/Vector.h>
 #include <camera/CameraMetadata.h>
 
 #include "NdkCameraMetadata.h"
@@ -51,12 +55,17 @@
     camera_status_t update(uint32_t tag, uint32_t count, const int64_t* data);
     camera_status_t update(uint32_t tag, uint32_t count, const ACameraMetadata_rational* data);
 
+    camera_status_t getTags(/*out*/int32_t* numTags,
+                            /*out*/const uint32_t** tags) const;
+
     bool isNdkSupportedCapability(const int32_t capability);
-    inline bool isVendorTag(const uint32_t tag);
-    bool isCaptureRequestTag(const uint32_t tag);
+    static inline bool isVendorTag(const uint32_t tag);
+    static bool isCaptureRequestTag(const uint32_t tag);
     void filterUnsupportedFeatures(); // Hide features not yet supported by NDK
     void filterStreamConfigurations(); // Hide input streams, translate hal format to NDK formats
 
+    const CameraMetadata& getInternalData();
+
     template<typename INTERNAL_T, typename NDK_T>
     camera_status_t updateImpl(uint32_t tag, uint32_t count, const NDK_T* data) {
         if (mType != ACM_REQUEST) {
@@ -68,18 +77,27 @@
             return ACAMERA_ERROR_INVALID_PARAMETER;
         }
 
+        Mutex::Autolock _l(mLock);
+
         // Here we have to use reinterpret_cast because the NDK data type is
         // exact copy of internal data type but they do not inherit from each other
         status_t ret = mData.update(tag, reinterpret_cast<const INTERNAL_T*>(data), count);
         if (ret == OK) {
+            mTags.clear();
             return ACAMERA_OK;
         } else {
             return ACAMERA_ERROR_INVALID_PARAMETER;
         }
     }
 
-    CameraMetadata mData;
+  private:
+    // guard access of public APIs: get/update/getTags
+    mutable Mutex    mLock;
+    CameraMetadata   mData;
+    mutable Vector<uint32_t> mTags; // updated in getTags, cleared by update
     const ACAMERA_METADATA_TYPE mType;
+
+    static std::unordered_set<uint32_t> sSystemTags;
 };
 
 #endif // _ACAMERA_METADATA_H
diff --git a/include/camera/CameraMetadata.h b/include/camera/CameraMetadata.h
index db400de..28f47a1 100644
--- a/include/camera/CameraMetadata.h
+++ b/include/camera/CameraMetadata.h
@@ -64,7 +64,7 @@
      * from getAndLock must be provided to guarantee that the right object is
      * being unlocked.
      */
-    status_t unlock(const camera_metadata_t *buffer);
+    status_t unlock(const camera_metadata_t *buffer) const;
 
     /**
      * Release a raw metadata buffer to the caller. After this call,
diff --git a/include/camera/ndk/NdkCameraMetadata.h b/include/camera/ndk/NdkCameraMetadata.h
index 56412ad..9b56a9d 100644
--- a/include/camera/ndk/NdkCameraMetadata.h
+++ b/include/camera/ndk/NdkCameraMetadata.h
@@ -93,7 +93,13 @@
 camera_status_t ACameraMetadata_getConstEntry(
         const ACameraMetadata*, uint32_t tag, ACameraMetadata_const_entry* entry);
 
-// TODO: need an API to list all tags in the metadata. Same for ACaptureRequest
+/*
+ * List all the entry tags in this metadata.
+ * The memory of tags is managed by ACameraMetadata itself and must NOT be free/delete
+ * by application. Do NOT access tags after calling ACameraMetadata_free
+ */
+camera_status_t ACameraMetadata_getAllTags(
+        const ACameraMetadata*, /*out*/int32_t* numTags, /*out*/const uint32_t** tags);
 
 /**
  * Copy a metadata. Duplicates a metadata structure.
diff --git a/include/camera/ndk/NdkCameraMetadataTags.h b/include/camera/ndk/NdkCameraMetadataTags.h
index 43f5193..a1d3bf7 100644
--- a/include/camera/ndk/NdkCameraMetadataTags.h
+++ b/include/camera/ndk/NdkCameraMetadataTags.h
@@ -98,273 +98,382 @@
 typedef enum acamera_metadata_tag {
     ACAMERA_COLOR_CORRECTION_MODE =                             // byte (enum)
             ACAMERA_COLOR_CORRECTION_START,
-    ACAMERA_COLOR_CORRECTION_TRANSFORM,                         // rational[3*3]
-    ACAMERA_COLOR_CORRECTION_GAINS,                             // float[4]
-    ACAMERA_COLOR_CORRECTION_ABERRATION_MODE,                   // byte (enum)
-    ACAMERA_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,        // byte[n]
+    ACAMERA_COLOR_CORRECTION_TRANSFORM =                        // rational[3*3]
+            ACAMERA_COLOR_CORRECTION_START + 1,
+    ACAMERA_COLOR_CORRECTION_GAINS =                            // float[4]
+            ACAMERA_COLOR_CORRECTION_START + 2,
+    ACAMERA_COLOR_CORRECTION_ABERRATION_MODE =                  // byte (enum)
+            ACAMERA_COLOR_CORRECTION_START + 3,
+    ACAMERA_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES =       // byte[n]
+            ACAMERA_COLOR_CORRECTION_START + 4,
     ACAMERA_COLOR_CORRECTION_END,
 
     ACAMERA_CONTROL_AE_ANTIBANDING_MODE =                       // byte (enum)
             ACAMERA_CONTROL_START,
-    ACAMERA_CONTROL_AE_EXPOSURE_COMPENSATION,                   // int32
-    ACAMERA_CONTROL_AE_LOCK,                                    // byte (enum)
-    ACAMERA_CONTROL_AE_MODE,                                    // byte (enum)
-    ACAMERA_CONTROL_AE_REGIONS,                                 // int32[5*area_count]
-    ACAMERA_CONTROL_AE_TARGET_FPS_RANGE,                        // int32[2]
-    ACAMERA_CONTROL_AE_PRECAPTURE_TRIGGER,                      // byte (enum)
-    ACAMERA_CONTROL_AF_MODE,                                    // byte (enum)
-    ACAMERA_CONTROL_AF_REGIONS,                                 // int32[5*area_count]
-    ACAMERA_CONTROL_AF_TRIGGER,                                 // byte (enum)
-    ACAMERA_CONTROL_AWB_LOCK,                                   // byte (enum)
-    ACAMERA_CONTROL_AWB_MODE,                                   // byte (enum)
-    ACAMERA_CONTROL_AWB_REGIONS,                                // int32[5*area_count]
-    ACAMERA_CONTROL_CAPTURE_INTENT,                             // byte (enum)
-    ACAMERA_CONTROL_EFFECT_MODE,                                // byte (enum)
-    ACAMERA_CONTROL_MODE,                                       // byte (enum)
-    ACAMERA_CONTROL_SCENE_MODE,                                 // byte (enum)
-    ACAMERA_CONTROL_VIDEO_STABILIZATION_MODE,                   // byte (enum)
-    ACAMERA_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,             // byte[n]
-    ACAMERA_CONTROL_AE_AVAILABLE_MODES,                         // byte[n]
-    ACAMERA_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,             // int32[2*n]
-    ACAMERA_CONTROL_AE_COMPENSATION_RANGE,                      // int32[2]
-    ACAMERA_CONTROL_AE_COMPENSATION_STEP,                       // rational
-    ACAMERA_CONTROL_AF_AVAILABLE_MODES,                         // byte[n]
-    ACAMERA_CONTROL_AVAILABLE_EFFECTS,                          // byte[n]
-    ACAMERA_CONTROL_AVAILABLE_SCENE_MODES,                      // byte[n]
-    ACAMERA_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES,        // byte[n]
-    ACAMERA_CONTROL_AWB_AVAILABLE_MODES,                        // byte[n]
-    ACAMERA_CONTROL_MAX_REGIONS,                                // int32[3]
-    ACAMERA_CONTROL_RESERVED_29,
-    ACAMERA_CONTROL_RESERVED_30,
-    ACAMERA_CONTROL_AE_STATE,                                   // byte (enum)
-    ACAMERA_CONTROL_AF_STATE,                                   // byte (enum)
-    ACAMERA_CONTROL_RESERVED_33,
-    ACAMERA_CONTROL_AWB_STATE,                                  // byte (enum)
-    ACAMERA_CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS,  // int32[5*n]
-    ACAMERA_CONTROL_AE_LOCK_AVAILABLE,                          // byte (enum)
-    ACAMERA_CONTROL_AWB_LOCK_AVAILABLE,                         // byte (enum)
-    ACAMERA_CONTROL_AVAILABLE_MODES,                            // byte[n]
-    ACAMERA_CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE,           // int32[2]
-    ACAMERA_CONTROL_POST_RAW_SENSITIVITY_BOOST,                 // int32
+    ACAMERA_CONTROL_AE_EXPOSURE_COMPENSATION =                  // int32
+            ACAMERA_CONTROL_START + 1,
+    ACAMERA_CONTROL_AE_LOCK =                                   // byte (enum)
+            ACAMERA_CONTROL_START + 2,
+    ACAMERA_CONTROL_AE_MODE =                                   // byte (enum)
+            ACAMERA_CONTROL_START + 3,
+    ACAMERA_CONTROL_AE_REGIONS =                                // int32[5*area_count]
+            ACAMERA_CONTROL_START + 4,
+    ACAMERA_CONTROL_AE_TARGET_FPS_RANGE =                       // int32[2]
+            ACAMERA_CONTROL_START + 5,
+    ACAMERA_CONTROL_AE_PRECAPTURE_TRIGGER =                     // byte (enum)
+            ACAMERA_CONTROL_START + 6,
+    ACAMERA_CONTROL_AF_MODE =                                   // byte (enum)
+            ACAMERA_CONTROL_START + 7,
+    ACAMERA_CONTROL_AF_REGIONS =                                // int32[5*area_count]
+            ACAMERA_CONTROL_START + 8,
+    ACAMERA_CONTROL_AF_TRIGGER =                                // byte (enum)
+            ACAMERA_CONTROL_START + 9,
+    ACAMERA_CONTROL_AWB_LOCK =                                  // byte (enum)
+            ACAMERA_CONTROL_START + 10,
+    ACAMERA_CONTROL_AWB_MODE =                                  // byte (enum)
+            ACAMERA_CONTROL_START + 11,
+    ACAMERA_CONTROL_AWB_REGIONS =                               // int32[5*area_count]
+            ACAMERA_CONTROL_START + 12,
+    ACAMERA_CONTROL_CAPTURE_INTENT =                            // byte (enum)
+            ACAMERA_CONTROL_START + 13,
+    ACAMERA_CONTROL_EFFECT_MODE =                               // byte (enum)
+            ACAMERA_CONTROL_START + 14,
+    ACAMERA_CONTROL_MODE =                                      // byte (enum)
+            ACAMERA_CONTROL_START + 15,
+    ACAMERA_CONTROL_SCENE_MODE =                                // byte (enum)
+            ACAMERA_CONTROL_START + 16,
+    ACAMERA_CONTROL_VIDEO_STABILIZATION_MODE =                  // byte (enum)
+            ACAMERA_CONTROL_START + 17,
+    ACAMERA_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES =            // byte[n]
+            ACAMERA_CONTROL_START + 18,
+    ACAMERA_CONTROL_AE_AVAILABLE_MODES =                        // byte[n]
+            ACAMERA_CONTROL_START + 19,
+    ACAMERA_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES =            // int32[2*n]
+            ACAMERA_CONTROL_START + 20,
+    ACAMERA_CONTROL_AE_COMPENSATION_RANGE =                     // int32[2]
+            ACAMERA_CONTROL_START + 21,
+    ACAMERA_CONTROL_AE_COMPENSATION_STEP =                      // rational
+            ACAMERA_CONTROL_START + 22,
+    ACAMERA_CONTROL_AF_AVAILABLE_MODES =                        // byte[n]
+            ACAMERA_CONTROL_START + 23,
+    ACAMERA_CONTROL_AVAILABLE_EFFECTS =                         // byte[n]
+            ACAMERA_CONTROL_START + 24,
+    ACAMERA_CONTROL_AVAILABLE_SCENE_MODES =                     // byte[n]
+            ACAMERA_CONTROL_START + 25,
+    ACAMERA_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES =       // byte[n]
+            ACAMERA_CONTROL_START + 26,
+    ACAMERA_CONTROL_AWB_AVAILABLE_MODES =                       // byte[n]
+            ACAMERA_CONTROL_START + 27,
+    ACAMERA_CONTROL_MAX_REGIONS =                               // int32[3]
+            ACAMERA_CONTROL_START + 28,
+    ACAMERA_CONTROL_AE_STATE =                                  // byte (enum)
+            ACAMERA_CONTROL_START + 31,
+    ACAMERA_CONTROL_AF_STATE =                                  // byte (enum)
+            ACAMERA_CONTROL_START + 32,
+    ACAMERA_CONTROL_AWB_STATE =                                 // byte (enum)
+            ACAMERA_CONTROL_START + 34,
+    ACAMERA_CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS = // int32[5*n]
+            ACAMERA_CONTROL_START + 35,
+    ACAMERA_CONTROL_AE_LOCK_AVAILABLE =                         // byte (enum)
+            ACAMERA_CONTROL_START + 36,
+    ACAMERA_CONTROL_AWB_LOCK_AVAILABLE =                        // byte (enum)
+            ACAMERA_CONTROL_START + 37,
+    ACAMERA_CONTROL_AVAILABLE_MODES =                           // byte[n]
+            ACAMERA_CONTROL_START + 38,
+    ACAMERA_CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE =          // int32[2]
+            ACAMERA_CONTROL_START + 39,
+    ACAMERA_CONTROL_POST_RAW_SENSITIVITY_BOOST =                // int32
+            ACAMERA_CONTROL_START + 40,
     ACAMERA_CONTROL_END,
 
-    ACAMERA_DEMOSAIC_RESERVED_0 =
-            ACAMERA_DEMOSAIC_START,
-    ACAMERA_DEMOSAIC_END,
-
     ACAMERA_EDGE_MODE =                                         // byte (enum)
             ACAMERA_EDGE_START,
-    ACAMERA_EDGE_RESERVED_1,
-    ACAMERA_EDGE_AVAILABLE_EDGE_MODES,                          // byte[n]
+    ACAMERA_EDGE_AVAILABLE_EDGE_MODES =                         // byte[n]
+            ACAMERA_EDGE_START + 2,
     ACAMERA_EDGE_END,
 
-    ACAMERA_FLASH_RESERVED_0 =
-            ACAMERA_FLASH_START,
-    ACAMERA_FLASH_RESERVED_1,
-    ACAMERA_FLASH_MODE,                                         // byte (enum)
-    ACAMERA_FLASH_RESERVED_3,
-    ACAMERA_FLASH_RESERVED_4,
-    ACAMERA_FLASH_STATE,                                        // byte (enum)
+    ACAMERA_FLASH_MODE =                                        // byte (enum)
+            ACAMERA_FLASH_START + 2,
+    ACAMERA_FLASH_STATE =                                       // byte (enum)
+            ACAMERA_FLASH_START + 5,
     ACAMERA_FLASH_END,
 
     ACAMERA_FLASH_INFO_AVAILABLE =                              // byte (enum)
             ACAMERA_FLASH_INFO_START,
-    ACAMERA_FLASH_INFO_RESERVED_1,
     ACAMERA_FLASH_INFO_END,
 
     ACAMERA_HOT_PIXEL_MODE =                                    // byte (enum)
             ACAMERA_HOT_PIXEL_START,
-    ACAMERA_HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES,                // byte[n]
+    ACAMERA_HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES =               // byte[n]
+            ACAMERA_HOT_PIXEL_START + 1,
     ACAMERA_HOT_PIXEL_END,
 
     ACAMERA_JPEG_GPS_COORDINATES =                              // double[3]
             ACAMERA_JPEG_START,
-    ACAMERA_JPEG_GPS_PROCESSING_METHOD,                         // byte
-    ACAMERA_JPEG_GPS_TIMESTAMP,                                 // int64
-    ACAMERA_JPEG_ORIENTATION,                                   // int32
-    ACAMERA_JPEG_QUALITY,                                       // byte
-    ACAMERA_JPEG_THUMBNAIL_QUALITY,                             // byte
-    ACAMERA_JPEG_THUMBNAIL_SIZE,                                // int32[2]
-    ACAMERA_JPEG_AVAILABLE_THUMBNAIL_SIZES,                     // int32[2*n]
-    ACAMERA_JPEG_RESERVED_8,
-    ACAMERA_JPEG_RESERVED_9,
+    ACAMERA_JPEG_GPS_PROCESSING_METHOD =                        // byte
+            ACAMERA_JPEG_START + 1,
+    ACAMERA_JPEG_GPS_TIMESTAMP =                                // int64
+            ACAMERA_JPEG_START + 2,
+    ACAMERA_JPEG_ORIENTATION =                                  // int32
+            ACAMERA_JPEG_START + 3,
+    ACAMERA_JPEG_QUALITY =                                      // byte
+            ACAMERA_JPEG_START + 4,
+    ACAMERA_JPEG_THUMBNAIL_QUALITY =                            // byte
+            ACAMERA_JPEG_START + 5,
+    ACAMERA_JPEG_THUMBNAIL_SIZE =                               // int32[2]
+            ACAMERA_JPEG_START + 6,
+    ACAMERA_JPEG_AVAILABLE_THUMBNAIL_SIZES =                    // int32[2*n]
+            ACAMERA_JPEG_START + 7,
     ACAMERA_JPEG_END,
 
     ACAMERA_LENS_APERTURE =                                     // float
             ACAMERA_LENS_START,
-    ACAMERA_LENS_FILTER_DENSITY,                                // float
-    ACAMERA_LENS_FOCAL_LENGTH,                                  // float
-    ACAMERA_LENS_FOCUS_DISTANCE,                                // float
-    ACAMERA_LENS_OPTICAL_STABILIZATION_MODE,                    // byte (enum)
-    ACAMERA_LENS_FACING,                                        // byte (enum)
-    ACAMERA_LENS_POSE_ROTATION,                                 // float[4]
-    ACAMERA_LENS_POSE_TRANSLATION,                              // float[3]
-    ACAMERA_LENS_FOCUS_RANGE,                                   // float[2]
-    ACAMERA_LENS_STATE,                                         // byte (enum)
-    ACAMERA_LENS_INTRINSIC_CALIBRATION,                         // float[5]
-    ACAMERA_LENS_RADIAL_DISTORTION,                             // float[6]
+    ACAMERA_LENS_FILTER_DENSITY =                               // float
+            ACAMERA_LENS_START + 1,
+    ACAMERA_LENS_FOCAL_LENGTH =                                 // float
+            ACAMERA_LENS_START + 2,
+    ACAMERA_LENS_FOCUS_DISTANCE =                               // float
+            ACAMERA_LENS_START + 3,
+    ACAMERA_LENS_OPTICAL_STABILIZATION_MODE =                   // byte (enum)
+            ACAMERA_LENS_START + 4,
+    ACAMERA_LENS_FACING =                                       // byte (enum)
+            ACAMERA_LENS_START + 5,
+    ACAMERA_LENS_POSE_ROTATION =                                // float[4]
+            ACAMERA_LENS_START + 6,
+    ACAMERA_LENS_POSE_TRANSLATION =                             // float[3]
+            ACAMERA_LENS_START + 7,
+    ACAMERA_LENS_FOCUS_RANGE =                                  // float[2]
+            ACAMERA_LENS_START + 8,
+    ACAMERA_LENS_STATE =                                        // byte (enum)
+            ACAMERA_LENS_START + 9,
+    ACAMERA_LENS_INTRINSIC_CALIBRATION =                        // float[5]
+            ACAMERA_LENS_START + 10,
+    ACAMERA_LENS_RADIAL_DISTORTION =                            // float[6]
+            ACAMERA_LENS_START + 11,
     ACAMERA_LENS_END,
 
     ACAMERA_LENS_INFO_AVAILABLE_APERTURES =                     // float[n]
             ACAMERA_LENS_INFO_START,
-    ACAMERA_LENS_INFO_AVAILABLE_FILTER_DENSITIES,               // float[n]
-    ACAMERA_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,                  // float[n]
-    ACAMERA_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION,          // byte[n]
-    ACAMERA_LENS_INFO_HYPERFOCAL_DISTANCE,                      // float
-    ACAMERA_LENS_INFO_MINIMUM_FOCUS_DISTANCE,                   // float
-    ACAMERA_LENS_INFO_SHADING_MAP_SIZE,                         // int32[2]
-    ACAMERA_LENS_INFO_FOCUS_DISTANCE_CALIBRATION,               // byte (enum)
+    ACAMERA_LENS_INFO_AVAILABLE_FILTER_DENSITIES =              // float[n]
+            ACAMERA_LENS_INFO_START + 1,
+    ACAMERA_LENS_INFO_AVAILABLE_FOCAL_LENGTHS =                 // float[n]
+            ACAMERA_LENS_INFO_START + 2,
+    ACAMERA_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION =         // byte[n]
+            ACAMERA_LENS_INFO_START + 3,
+    ACAMERA_LENS_INFO_HYPERFOCAL_DISTANCE =                     // float
+            ACAMERA_LENS_INFO_START + 4,
+    ACAMERA_LENS_INFO_MINIMUM_FOCUS_DISTANCE =                  // float
+            ACAMERA_LENS_INFO_START + 5,
+    ACAMERA_LENS_INFO_SHADING_MAP_SIZE =                        // int32[2]
+            ACAMERA_LENS_INFO_START + 6,
+    ACAMERA_LENS_INFO_FOCUS_DISTANCE_CALIBRATION =              // byte (enum)
+            ACAMERA_LENS_INFO_START + 7,
     ACAMERA_LENS_INFO_END,
 
     ACAMERA_NOISE_REDUCTION_MODE =                              // byte (enum)
             ACAMERA_NOISE_REDUCTION_START,
-    ACAMERA_NOISE_REDUCTION_RESERVED_1,
-    ACAMERA_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,    // byte[n]
+    ACAMERA_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES =   // byte[n]
+            ACAMERA_NOISE_REDUCTION_START + 2,
     ACAMERA_NOISE_REDUCTION_END,
 
-    ACAMERA_QUIRKS_RESERVED_0 =
-            ACAMERA_QUIRKS_START,
-    ACAMERA_QUIRKS_RESERVED_1,
-    ACAMERA_QUIRKS_RESERVED_2,
-    ACAMERA_QUIRKS_USE_PARTIAL_RESULT,                          // Deprecated! DO NOT USE
-    ACAMERA_QUIRKS_PARTIAL_RESULT,                              // Deprecated! DO NOT USE
+    ACAMERA_QUIRKS_USE_PARTIAL_RESULT =                         // Deprecated! DO NOT USE
+            ACAMERA_QUIRKS_START + 3,
+    ACAMERA_QUIRKS_PARTIAL_RESULT =                             // Deprecated! DO NOT USE
+            ACAMERA_QUIRKS_START + 4,
     ACAMERA_QUIRKS_END,
 
     ACAMERA_REQUEST_FRAME_COUNT =                               // Deprecated! DO NOT USE
             ACAMERA_REQUEST_START,
-    ACAMERA_REQUEST_ID,                                         // int32
-    ACAMERA_REQUEST_RESERVED_2,
-    ACAMERA_REQUEST_RESERVED_3,
-    ACAMERA_REQUEST_RESERVED_4,
-    ACAMERA_REQUEST_RESERVED_5,
-    ACAMERA_REQUEST_MAX_NUM_OUTPUT_STREAMS,                     // int32[3]
-    ACAMERA_REQUEST_RESERVED_7,
-    ACAMERA_REQUEST_MAX_NUM_INPUT_STREAMS,                      // int32
-    ACAMERA_REQUEST_PIPELINE_DEPTH,                             // byte
-    ACAMERA_REQUEST_PIPELINE_MAX_DEPTH,                         // byte
-    ACAMERA_REQUEST_PARTIAL_RESULT_COUNT,                       // int32
-    ACAMERA_REQUEST_AVAILABLE_CAPABILITIES,                     // byte[n] (enum)
-    ACAMERA_REQUEST_AVAILABLE_REQUEST_KEYS,                     // int32[n]
-    ACAMERA_REQUEST_AVAILABLE_RESULT_KEYS,                      // int32[n]
-    ACAMERA_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS,             // int32[n]
+    ACAMERA_REQUEST_ID =                                        // int32
+            ACAMERA_REQUEST_START + 1,
+    ACAMERA_REQUEST_MAX_NUM_OUTPUT_STREAMS =                    // int32[3]
+            ACAMERA_REQUEST_START + 6,
+    ACAMERA_REQUEST_MAX_NUM_INPUT_STREAMS =                     // int32
+            ACAMERA_REQUEST_START + 8,
+    ACAMERA_REQUEST_PIPELINE_DEPTH =                            // byte
+            ACAMERA_REQUEST_START + 9,
+    ACAMERA_REQUEST_PIPELINE_MAX_DEPTH =                        // byte
+            ACAMERA_REQUEST_START + 10,
+    ACAMERA_REQUEST_PARTIAL_RESULT_COUNT =                      // int32
+            ACAMERA_REQUEST_START + 11,
+    ACAMERA_REQUEST_AVAILABLE_CAPABILITIES =                    // byte[n] (enum)
+            ACAMERA_REQUEST_START + 12,
+    ACAMERA_REQUEST_AVAILABLE_REQUEST_KEYS =                    // int32[n]
+            ACAMERA_REQUEST_START + 13,
+    ACAMERA_REQUEST_AVAILABLE_RESULT_KEYS =                     // int32[n]
+            ACAMERA_REQUEST_START + 14,
+    ACAMERA_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS =            // int32[n]
+            ACAMERA_REQUEST_START + 15,
     ACAMERA_REQUEST_END,
 
     ACAMERA_SCALER_CROP_REGION =                                // int32[4]
             ACAMERA_SCALER_START,
-    ACAMERA_SCALER_AVAILABLE_FORMATS,                           // Deprecated! DO NOT USE
-    ACAMERA_SCALER_AVAILABLE_JPEG_MIN_DURATIONS,                // Deprecated! DO NOT USE
-    ACAMERA_SCALER_AVAILABLE_JPEG_SIZES,                        // Deprecated! DO NOT USE
-    ACAMERA_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,                  // float
-    ACAMERA_SCALER_AVAILABLE_PROCESSED_MIN_DURATIONS,           // Deprecated! DO NOT USE
-    ACAMERA_SCALER_AVAILABLE_PROCESSED_SIZES,                   // Deprecated! DO NOT USE
-    ACAMERA_SCALER_RESERVED_7,
-    ACAMERA_SCALER_RESERVED_8,
-    ACAMERA_SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP,          // int32
-    ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,             // int32[n*4] (enum)
-    ACAMERA_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,               // int64[4*n]
-    ACAMERA_SCALER_AVAILABLE_STALL_DURATIONS,                   // int64[4*n]
-    ACAMERA_SCALER_CROPPING_TYPE,                               // byte (enum)
+    ACAMERA_SCALER_AVAILABLE_FORMATS =                          // Deprecated! DO NOT USE
+            ACAMERA_SCALER_START + 1,
+    ACAMERA_SCALER_AVAILABLE_JPEG_MIN_DURATIONS =               // Deprecated! DO NOT USE
+            ACAMERA_SCALER_START + 2,
+    ACAMERA_SCALER_AVAILABLE_JPEG_SIZES =                       // Deprecated! DO NOT USE
+            ACAMERA_SCALER_START + 3,
+    ACAMERA_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM =                 // float
+            ACAMERA_SCALER_START + 4,
+    ACAMERA_SCALER_AVAILABLE_PROCESSED_MIN_DURATIONS =          // Deprecated! DO NOT USE
+            ACAMERA_SCALER_START + 5,
+    ACAMERA_SCALER_AVAILABLE_PROCESSED_SIZES =                  // Deprecated! DO NOT USE
+            ACAMERA_SCALER_START + 6,
+    ACAMERA_SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP =         // int32
+            ACAMERA_SCALER_START + 9,
+    ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS =            // int32[n*4] (enum)
+            ACAMERA_SCALER_START + 10,
+    ACAMERA_SCALER_AVAILABLE_MIN_FRAME_DURATIONS =              // int64[4*n]
+            ACAMERA_SCALER_START + 11,
+    ACAMERA_SCALER_AVAILABLE_STALL_DURATIONS =                  // int64[4*n]
+            ACAMERA_SCALER_START + 12,
+    ACAMERA_SCALER_CROPPING_TYPE =                              // byte (enum)
+            ACAMERA_SCALER_START + 13,
     ACAMERA_SCALER_END,
 
     ACAMERA_SENSOR_EXPOSURE_TIME =                              // int64
             ACAMERA_SENSOR_START,
-    ACAMERA_SENSOR_FRAME_DURATION,                              // int64
-    ACAMERA_SENSOR_SENSITIVITY,                                 // int32
-    ACAMERA_SENSOR_REFERENCE_ILLUMINANT1,                       // byte (enum)
-    ACAMERA_SENSOR_REFERENCE_ILLUMINANT2,                       // byte
-    ACAMERA_SENSOR_CALIBRATION_TRANSFORM1,                      // rational[3*3]
-    ACAMERA_SENSOR_CALIBRATION_TRANSFORM2,                      // rational[3*3]
-    ACAMERA_SENSOR_COLOR_TRANSFORM1,                            // rational[3*3]
-    ACAMERA_SENSOR_COLOR_TRANSFORM2,                            // rational[3*3]
-    ACAMERA_SENSOR_FORWARD_MATRIX1,                             // rational[3*3]
-    ACAMERA_SENSOR_FORWARD_MATRIX2,                             // rational[3*3]
-    ACAMERA_SENSOR_RESERVED_11,
-    ACAMERA_SENSOR_BLACK_LEVEL_PATTERN,                         // int32[4]
-    ACAMERA_SENSOR_MAX_ANALOG_SENSITIVITY,                      // int32
-    ACAMERA_SENSOR_ORIENTATION,                                 // int32
-    ACAMERA_SENSOR_RESERVED_15,
-    ACAMERA_SENSOR_TIMESTAMP,                                   // int64
-    ACAMERA_SENSOR_RESERVED_17,
-    ACAMERA_SENSOR_NEUTRAL_COLOR_POINT,                         // rational[3]
-    ACAMERA_SENSOR_NOISE_PROFILE,                               // double[2*CFA Channels]
-    ACAMERA_SENSOR_RESERVED_20,
-    ACAMERA_SENSOR_RESERVED_21,
-    ACAMERA_SENSOR_GREEN_SPLIT,                                 // float
-    ACAMERA_SENSOR_TEST_PATTERN_DATA,                           // int32[4]
-    ACAMERA_SENSOR_TEST_PATTERN_MODE,                           // int32 (enum)
-    ACAMERA_SENSOR_AVAILABLE_TEST_PATTERN_MODES,                // int32[n]
-    ACAMERA_SENSOR_ROLLING_SHUTTER_SKEW,                        // int64
-    ACAMERA_SENSOR_OPTICAL_BLACK_REGIONS,                       // int32[4*num_regions]
-    ACAMERA_SENSOR_DYNAMIC_BLACK_LEVEL,                         // float[4]
-    ACAMERA_SENSOR_DYNAMIC_WHITE_LEVEL,                         // int32
-    ACAMERA_SENSOR_RESERVED_30,
+    ACAMERA_SENSOR_FRAME_DURATION =                             // int64
+            ACAMERA_SENSOR_START + 1,
+    ACAMERA_SENSOR_SENSITIVITY =                                // int32
+            ACAMERA_SENSOR_START + 2,
+    ACAMERA_SENSOR_REFERENCE_ILLUMINANT1 =                      // byte (enum)
+            ACAMERA_SENSOR_START + 3,
+    ACAMERA_SENSOR_REFERENCE_ILLUMINANT2 =                      // byte
+            ACAMERA_SENSOR_START + 4,
+    ACAMERA_SENSOR_CALIBRATION_TRANSFORM1 =                     // rational[3*3]
+            ACAMERA_SENSOR_START + 5,
+    ACAMERA_SENSOR_CALIBRATION_TRANSFORM2 =                     // rational[3*3]
+            ACAMERA_SENSOR_START + 6,
+    ACAMERA_SENSOR_COLOR_TRANSFORM1 =                           // rational[3*3]
+            ACAMERA_SENSOR_START + 7,
+    ACAMERA_SENSOR_COLOR_TRANSFORM2 =                           // rational[3*3]
+            ACAMERA_SENSOR_START + 8,
+    ACAMERA_SENSOR_FORWARD_MATRIX1 =                            // rational[3*3]
+            ACAMERA_SENSOR_START + 9,
+    ACAMERA_SENSOR_FORWARD_MATRIX2 =                            // rational[3*3]
+            ACAMERA_SENSOR_START + 10,
+    ACAMERA_SENSOR_BLACK_LEVEL_PATTERN =                        // int32[4]
+            ACAMERA_SENSOR_START + 12,
+    ACAMERA_SENSOR_MAX_ANALOG_SENSITIVITY =                     // int32
+            ACAMERA_SENSOR_START + 13,
+    ACAMERA_SENSOR_ORIENTATION =                                // int32
+            ACAMERA_SENSOR_START + 14,
+    ACAMERA_SENSOR_TIMESTAMP =                                  // int64
+            ACAMERA_SENSOR_START + 16,
+    ACAMERA_SENSOR_NEUTRAL_COLOR_POINT =                        // rational[3]
+            ACAMERA_SENSOR_START + 18,
+    ACAMERA_SENSOR_NOISE_PROFILE =                              // double[2*CFA Channels]
+            ACAMERA_SENSOR_START + 19,
+    ACAMERA_SENSOR_GREEN_SPLIT =                                // float
+            ACAMERA_SENSOR_START + 22,
+    ACAMERA_SENSOR_TEST_PATTERN_DATA =                          // int32[4]
+            ACAMERA_SENSOR_START + 23,
+    ACAMERA_SENSOR_TEST_PATTERN_MODE =                          // int32 (enum)
+            ACAMERA_SENSOR_START + 24,
+    ACAMERA_SENSOR_AVAILABLE_TEST_PATTERN_MODES =               // int32[n]
+            ACAMERA_SENSOR_START + 25,
+    ACAMERA_SENSOR_ROLLING_SHUTTER_SKEW =                       // int64
+            ACAMERA_SENSOR_START + 26,
+    ACAMERA_SENSOR_OPTICAL_BLACK_REGIONS =                      // int32[4*num_regions]
+            ACAMERA_SENSOR_START + 27,
+    ACAMERA_SENSOR_DYNAMIC_BLACK_LEVEL =                        // float[4]
+            ACAMERA_SENSOR_START + 28,
+    ACAMERA_SENSOR_DYNAMIC_WHITE_LEVEL =                        // int32
+            ACAMERA_SENSOR_START + 29,
     ACAMERA_SENSOR_END,
 
     ACAMERA_SENSOR_INFO_ACTIVE_ARRAY_SIZE =                     // int32[4]
             ACAMERA_SENSOR_INFO_START,
-    ACAMERA_SENSOR_INFO_SENSITIVITY_RANGE,                      // int32[2]
-    ACAMERA_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,               // byte (enum)
-    ACAMERA_SENSOR_INFO_EXPOSURE_TIME_RANGE,                    // int64[2]
-    ACAMERA_SENSOR_INFO_MAX_FRAME_DURATION,                     // int64
-    ACAMERA_SENSOR_INFO_PHYSICAL_SIZE,                          // float[2]
-    ACAMERA_SENSOR_INFO_PIXEL_ARRAY_SIZE,                       // int32[2]
-    ACAMERA_SENSOR_INFO_WHITE_LEVEL,                            // int32
-    ACAMERA_SENSOR_INFO_TIMESTAMP_SOURCE,                       // byte (enum)
-    ACAMERA_SENSOR_INFO_LENS_SHADING_APPLIED,                   // byte (enum)
-    ACAMERA_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE,       // int32[4]
+    ACAMERA_SENSOR_INFO_SENSITIVITY_RANGE =                     // int32[2]
+            ACAMERA_SENSOR_INFO_START + 1,
+    ACAMERA_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT =              // byte (enum)
+            ACAMERA_SENSOR_INFO_START + 2,
+    ACAMERA_SENSOR_INFO_EXPOSURE_TIME_RANGE =                   // int64[2]
+            ACAMERA_SENSOR_INFO_START + 3,
+    ACAMERA_SENSOR_INFO_MAX_FRAME_DURATION =                    // int64
+            ACAMERA_SENSOR_INFO_START + 4,
+    ACAMERA_SENSOR_INFO_PHYSICAL_SIZE =                         // float[2]
+            ACAMERA_SENSOR_INFO_START + 5,
+    ACAMERA_SENSOR_INFO_PIXEL_ARRAY_SIZE =                      // int32[2]
+            ACAMERA_SENSOR_INFO_START + 6,
+    ACAMERA_SENSOR_INFO_WHITE_LEVEL =                           // int32
+            ACAMERA_SENSOR_INFO_START + 7,
+    ACAMERA_SENSOR_INFO_TIMESTAMP_SOURCE =                      // byte (enum)
+            ACAMERA_SENSOR_INFO_START + 8,
+    ACAMERA_SENSOR_INFO_LENS_SHADING_APPLIED =                  // byte (enum)
+            ACAMERA_SENSOR_INFO_START + 9,
+    ACAMERA_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE =      // int32[4]
+            ACAMERA_SENSOR_INFO_START + 10,
     ACAMERA_SENSOR_INFO_END,
 
     ACAMERA_SHADING_MODE =                                      // byte (enum)
             ACAMERA_SHADING_START,
-    ACAMERA_SHADING_RESERVED_1,
-    ACAMERA_SHADING_AVAILABLE_MODES,                            // byte[n]
+    ACAMERA_SHADING_AVAILABLE_MODES =                           // byte[n]
+            ACAMERA_SHADING_START + 2,
     ACAMERA_SHADING_END,
 
     ACAMERA_STATISTICS_FACE_DETECT_MODE =                       // byte (enum)
             ACAMERA_STATISTICS_START,
-    ACAMERA_STATISTICS_RESERVED_1,
-    ACAMERA_STATISTICS_RESERVED_2,
-    ACAMERA_STATISTICS_HOT_PIXEL_MAP_MODE,                      // byte (enum)
-    ACAMERA_STATISTICS_FACE_IDS,                                // int32[n]
-    ACAMERA_STATISTICS_FACE_LANDMARKS,                          // int32[n*6]
-    ACAMERA_STATISTICS_FACE_RECTANGLES,                         // int32[n*4]
-    ACAMERA_STATISTICS_FACE_SCORES,                             // byte[n]
-    ACAMERA_STATISTICS_RESERVED_8,
-    ACAMERA_STATISTICS_RESERVED_9,
-    ACAMERA_STATISTICS_LENS_SHADING_CORRECTION_MAP,             // byte
-    ACAMERA_STATISTICS_LENS_SHADING_MAP,                        // float[4*n*m]
-    ACAMERA_STATISTICS_PREDICTED_COLOR_GAINS,                   // Deprecated! DO NOT USE
-    ACAMERA_STATISTICS_PREDICTED_COLOR_TRANSFORM,               // Deprecated! DO NOT USE
-    ACAMERA_STATISTICS_SCENE_FLICKER,                           // byte (enum)
-    ACAMERA_STATISTICS_HOT_PIXEL_MAP,                           // int32[2*n]
-    ACAMERA_STATISTICS_LENS_SHADING_MAP_MODE,                   // byte (enum)
+    ACAMERA_STATISTICS_HOT_PIXEL_MAP_MODE =                     // byte (enum)
+            ACAMERA_STATISTICS_START + 3,
+    ACAMERA_STATISTICS_FACE_IDS =                               // int32[n]
+            ACAMERA_STATISTICS_START + 4,
+    ACAMERA_STATISTICS_FACE_LANDMARKS =                         // int32[n*6]
+            ACAMERA_STATISTICS_START + 5,
+    ACAMERA_STATISTICS_FACE_RECTANGLES =                        // int32[n*4]
+            ACAMERA_STATISTICS_START + 6,
+    ACAMERA_STATISTICS_FACE_SCORES =                            // byte[n]
+            ACAMERA_STATISTICS_START + 7,
+    ACAMERA_STATISTICS_LENS_SHADING_CORRECTION_MAP =            // byte
+            ACAMERA_STATISTICS_START + 10,
+    ACAMERA_STATISTICS_LENS_SHADING_MAP =                       // float[4*n*m]
+            ACAMERA_STATISTICS_START + 11,
+    ACAMERA_STATISTICS_PREDICTED_COLOR_GAINS =                  // Deprecated! DO NOT USE
+            ACAMERA_STATISTICS_START + 12,
+    ACAMERA_STATISTICS_PREDICTED_COLOR_TRANSFORM =              // Deprecated! DO NOT USE
+            ACAMERA_STATISTICS_START + 13,
+    ACAMERA_STATISTICS_SCENE_FLICKER =                          // byte (enum)
+            ACAMERA_STATISTICS_START + 14,
+    ACAMERA_STATISTICS_HOT_PIXEL_MAP =                          // int32[2*n]
+            ACAMERA_STATISTICS_START + 15,
+    ACAMERA_STATISTICS_LENS_SHADING_MAP_MODE =                  // byte (enum)
+            ACAMERA_STATISTICS_START + 16,
     ACAMERA_STATISTICS_END,
 
     ACAMERA_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES =       // byte[n]
             ACAMERA_STATISTICS_INFO_START,
-    ACAMERA_STATISTICS_INFO_RESERVED_1,
-    ACAMERA_STATISTICS_INFO_MAX_FACE_COUNT,                     // int32
-    ACAMERA_STATISTICS_INFO_RESERVED_3,
-    ACAMERA_STATISTICS_INFO_RESERVED_4,
-    ACAMERA_STATISTICS_INFO_RESERVED_5,
-    ACAMERA_STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES,      // byte[n]
-    ACAMERA_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES,   // byte[n]
+    ACAMERA_STATISTICS_INFO_MAX_FACE_COUNT =                    // int32
+            ACAMERA_STATISTICS_INFO_START + 2,
+    ACAMERA_STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES =     // byte[n]
+            ACAMERA_STATISTICS_INFO_START + 6,
+    ACAMERA_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES =  // byte[n]
+            ACAMERA_STATISTICS_INFO_START + 7,
     ACAMERA_STATISTICS_INFO_END,
 
     ACAMERA_TONEMAP_CURVE_BLUE =                                // float[n*2]
             ACAMERA_TONEMAP_START,
-    ACAMERA_TONEMAP_CURVE_GREEN,                                // float[n*2]
-    ACAMERA_TONEMAP_CURVE_RED,                                  // float[n*2]
-    ACAMERA_TONEMAP_MODE,                                       // byte (enum)
-    ACAMERA_TONEMAP_MAX_CURVE_POINTS,                           // int32
-    ACAMERA_TONEMAP_AVAILABLE_TONE_MAP_MODES,                   // byte[n]
-    ACAMERA_TONEMAP_GAMMA,                                      // float
-    ACAMERA_TONEMAP_PRESET_CURVE,                               // byte (enum)
+    ACAMERA_TONEMAP_CURVE_GREEN =                               // float[n*2]
+            ACAMERA_TONEMAP_START + 1,
+    ACAMERA_TONEMAP_CURVE_RED =                                 // float[n*2]
+            ACAMERA_TONEMAP_START + 2,
+    ACAMERA_TONEMAP_MODE =                                      // byte (enum)
+            ACAMERA_TONEMAP_START + 3,
+    ACAMERA_TONEMAP_MAX_CURVE_POINTS =                          // int32
+            ACAMERA_TONEMAP_START + 4,
+    ACAMERA_TONEMAP_AVAILABLE_TONE_MAP_MODES =                  // byte[n]
+            ACAMERA_TONEMAP_START + 5,
+    ACAMERA_TONEMAP_GAMMA =                                     // float
+            ACAMERA_TONEMAP_START + 6,
+    ACAMERA_TONEMAP_PRESET_CURVE =                              // byte (enum)
+            ACAMERA_TONEMAP_START + 7,
     ACAMERA_TONEMAP_END,
 
     ACAMERA_LED_TRANSMIT =                                      // byte (enum)
             ACAMERA_LED_START,
-    ACAMERA_LED_AVAILABLE_LEDS,                                 // byte[n] (enum)
+    ACAMERA_LED_AVAILABLE_LEDS =                                // byte[n] (enum)
+            ACAMERA_LED_START + 1,
     ACAMERA_LED_END,
 
     ACAMERA_INFO_SUPPORTED_HARDWARE_LEVEL =                     // byte (enum)
@@ -377,20 +486,24 @@
 
     ACAMERA_SYNC_FRAME_NUMBER =                                 // int64 (enum)
             ACAMERA_SYNC_START,
-    ACAMERA_SYNC_MAX_LATENCY,                                   // int32 (enum)
+    ACAMERA_SYNC_MAX_LATENCY =                                  // int32 (enum)
+            ACAMERA_SYNC_START + 1,
     ACAMERA_SYNC_END,
 
     ACAMERA_REPROCESS_EFFECTIVE_EXPOSURE_FACTOR =               // float
             ACAMERA_REPROCESS_START,
-    ACAMERA_REPROCESS_MAX_CAPTURE_STALL,                        // int32
+    ACAMERA_REPROCESS_MAX_CAPTURE_STALL =                       // int32
+            ACAMERA_REPROCESS_START + 1,
     ACAMERA_REPROCESS_END,
 
-    ACAMERA_DEPTH_RESERVED_0 =
-            ACAMERA_DEPTH_START,
-    ACAMERA_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS,        // int32[n*4] (enum)
-    ACAMERA_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS,          // int64[4*n]
-    ACAMERA_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS,              // int64[4*n]
-    ACAMERA_DEPTH_DEPTH_IS_EXCLUSIVE,                           // byte (enum)
+    ACAMERA_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS =       // int32[n*4] (enum)
+            ACAMERA_DEPTH_START + 1,
+    ACAMERA_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS =         // int64[4*n]
+            ACAMERA_DEPTH_START + 2,
+    ACAMERA_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS =             // int64[4*n]
+            ACAMERA_DEPTH_START + 3,
+    ACAMERA_DEPTH_DEPTH_IS_EXCLUSIVE =                          // byte (enum)
+            ACAMERA_DEPTH_START + 4,
     ACAMERA_DEPTH_END,
 
 } acamera_metadata_tag_t;
@@ -534,6 +647,8 @@
     ACAMERA_CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO,
     ACAMERA_CONTROL_SCENE_MODE_HDR,
     ACAMERA_CONTROL_SCENE_MODE_FACE_PRIORITY_LOW_LIGHT,
+    ACAMERA_CONTROL_SCENE_MODE_DEVICE_CUSTOM_START              = 100,
+    ACAMERA_CONTROL_SCENE_MODE_DEVICE_CUSTOM_END                = 127,
 } acamera_metadata_enum_android_control_scene_mode_t;
 
 // ACAMERA_CONTROL_VIDEO_STABILIZATION_MODE
diff --git a/include/camera/ndk/NdkCaptureRequest.h b/include/camera/ndk/NdkCaptureRequest.h
index 566d78f..d9fb164 100644
--- a/include/camera/ndk/NdkCaptureRequest.h
+++ b/include/camera/ndk/NdkCaptureRequest.h
@@ -54,6 +54,19 @@
  */
 camera_status_t ACaptureRequest_getConstEntry(
         const ACaptureRequest*, uint32_t tag, ACameraMetadata_const_entry* entry);
+
+/*
+ * List all the entry tags in this capture request.
+ * The memory of tags is managed by ACaptureRequest itself and must NOT be free/delete
+ * by application. Calling ACaptureRequest_setEntry_* API will invalidate previous
+ * output of ACaptureRequest_getAllTags. Do not access tags after calling
+ * ACaptureRequest_setEntry_*. To get new list of tags after updating capture request,
+ * application must call ACaptureRequest_getAllTags again.
+ * Do NOT access tags after calling ACaptureRequest_free.
+ */
+camera_status_t ACaptureRequest_getAllTags(
+        const ACaptureRequest*, /*out*/int32_t* numTags, /*out*/const uint32_t** tags);
+
 /*
  * Set an entry of corresponding type.
  * The entry tag's type must match corresponding set API or an
diff --git a/include/media/AudioRecord.h b/include/media/AudioRecord.h
index b0bc2d0..b034c8e 100644
--- a/include/media/AudioRecord.h
+++ b/include/media/AudioRecord.h
@@ -596,7 +596,13 @@
     size_t                  mFrameSize;         // app-level frame size == AudioFlinger frame size
     uint32_t                mLatency;           // in ms
     audio_channel_mask_t    mChannelMask;
-    audio_input_flags_t     mFlags;
+
+    audio_input_flags_t     mFlags;                 // same as mOrigFlags, except for bits that may
+                                                    // be denied by client or server, such as
+                                                    // AUDIO_INPUT_FLAG_FAST.  mLock must be
+                                                    // held to read or write those bits reliably.
+    audio_input_flags_t     mOrigFlags;             // as specified in constructor or set(), const
+
     int                     mSessionId;
     transfer_type           mTransfer;
 
diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h
index e0fb603..69dc062 100644
--- a/include/media/AudioTrack.h
+++ b/include/media/AudioTrack.h
@@ -949,9 +949,11 @@
 
     uint32_t                mUnderrunCountOffset;   // updated when restoring tracks
 
-    audio_output_flags_t    mFlags;
-        // const after set(), except for bits AUDIO_OUTPUT_FLAG_FAST and AUDIO_OUTPUT_FLAG_OFFLOAD.
-        // mLock must be held to read or write those bits reliably.
+    audio_output_flags_t    mFlags;                 // same as mOrigFlags, except for bits that may
+                                                    // be denied by client or server, such as
+                                                    // AUDIO_OUTPUT_FLAG_FAST.  mLock must be
+                                                    // held to read or write those bits reliably.
+    audio_output_flags_t    mOrigFlags;             // as specified in constructor or set(), const
 
     bool                    mDoNotReconnect;
 
diff --git a/include/media/stagefright/CodecBase.h b/include/media/stagefright/CodecBase.h
index 3de0d21..2d28432 100644
--- a/include/media/stagefright/CodecBase.h
+++ b/include/media/stagefright/CodecBase.h
@@ -20,9 +20,12 @@
 
 #include <stdint.h>
 
+#define STRINGIFY_ENUMS
+
 #include <media/IOMX.h>
 #include <media/MediaCodecInfo.h>
 #include <media/stagefright/foundation/AHandler.h>
+#include <media/stagefright/foundation/ColorUtils.h>
 #include <media/hardware/HardwareAPI.h>
 
 #include <utils/NativeHandle.h>
@@ -34,7 +37,7 @@
 struct ABuffer;
 struct PersistentSurface;
 
-struct CodecBase : public AHandler {
+struct CodecBase : public AHandler, /* static */ ColorUtils {
     enum {
         kWhatFillThisBuffer      = 'fill',
         kWhatDrainThisBuffer     = 'drai',
@@ -97,113 +100,6 @@
      * Codec-related defines
      */
 
-    /**********************************************************************************************/
-
-    /*
-     * Media-platform color constants. MediaCodec uses (an extended version of) platform-defined
-     * constants that are derived from HAL_DATASPACE, since these are directly exposed to the user.
-     * We extend the values to maintain the richer set of information defined inside media
-     * containers and bitstreams that are not supported by the platform. We also expect vendors
-     * to extend some of these values with vendor-specific values. These are separated into a
-     * vendor-extension section so they won't collide with future platform values.
-     */
-
-    enum ColorStandard : uint32_t {
-        kColorStandardUnspecified =
-                HAL_DATASPACE_STANDARD_UNSPECIFIED >> HAL_DATASPACE_STANDARD_SHIFT,
-        kColorStandardBT709 =     HAL_DATASPACE_STANDARD_BT709 >> HAL_DATASPACE_STANDARD_SHIFT,
-        kColorStandardBT601_625 = HAL_DATASPACE_STANDARD_BT601_625 >> HAL_DATASPACE_STANDARD_SHIFT,
-        kColorStandardBT601_625_Unadjusted =
-                HAL_DATASPACE_STANDARD_BT601_625_UNADJUSTED >> HAL_DATASPACE_STANDARD_SHIFT,
-        kColorStandardBT601_525 = HAL_DATASPACE_STANDARD_BT601_525 >> HAL_DATASPACE_STANDARD_SHIFT,
-        kColorStandardBT601_525_Unadjusted =
-                HAL_DATASPACE_STANDARD_BT601_525_UNADJUSTED >> HAL_DATASPACE_STANDARD_SHIFT,
-        kColorStandardBT2020 =    HAL_DATASPACE_STANDARD_BT2020 >> HAL_DATASPACE_STANDARD_SHIFT,
-        kColorStandardBT2020Constant =
-                HAL_DATASPACE_STANDARD_BT2020_CONSTANT_LUMINANCE >> HAL_DATASPACE_STANDARD_SHIFT,
-        kColorStandardBT470M =    HAL_DATASPACE_STANDARD_BT470M >> HAL_DATASPACE_STANDARD_SHIFT,
-        kColorStandardFilm =      HAL_DATASPACE_STANDARD_FILM >> HAL_DATASPACE_STANDARD_SHIFT,
-        kColorStandardMax =       HAL_DATASPACE_STANDARD_MASK >> HAL_DATASPACE_STANDARD_SHIFT,
-
-        /* This marks a section of color-standard values that are not supported by graphics HAL,
-           but track defined color primaries-matrix coefficient combinations in media.
-           These are stable for a given release. */
-        kColorStandardExtendedStart = kColorStandardMax + 1,
-
-        /* This marks a section of color-standard values that are not supported by graphics HAL
-           nor using media defined color primaries or matrix coefficients. These may differ per
-           device. */
-        kColorStandardVendorStart = 0x10000,
-    };
-
-    enum ColorTransfer : uint32_t  {
-        kColorTransferUnspecified =
-                HAL_DATASPACE_TRANSFER_UNSPECIFIED >> HAL_DATASPACE_TRANSFER_SHIFT,
-        kColorTransferLinear =      HAL_DATASPACE_TRANSFER_LINEAR >> HAL_DATASPACE_TRANSFER_SHIFT,
-        kColorTransferSRGB =        HAL_DATASPACE_TRANSFER_SRGB >> HAL_DATASPACE_TRANSFER_SHIFT,
-        kColorTransferSMPTE_170M =
-                HAL_DATASPACE_TRANSFER_SMPTE_170M >> HAL_DATASPACE_TRANSFER_SHIFT,
-        kColorTransferGamma22 =     HAL_DATASPACE_TRANSFER_GAMMA2_2 >> HAL_DATASPACE_TRANSFER_SHIFT,
-        kColorTransferGamma28 =     HAL_DATASPACE_TRANSFER_GAMMA2_8 >> HAL_DATASPACE_TRANSFER_SHIFT,
-        kColorTransferST2084 =      HAL_DATASPACE_TRANSFER_ST2084 >> HAL_DATASPACE_TRANSFER_SHIFT,
-        kColorTransferHLG =         HAL_DATASPACE_TRANSFER_HLG >> HAL_DATASPACE_TRANSFER_SHIFT,
-        kColorTransferMax =         HAL_DATASPACE_TRANSFER_MASK >> HAL_DATASPACE_TRANSFER_SHIFT,
-
-        /* This marks a section of color-transfer values that are not supported by graphics HAL,
-           but track media-defined color-transfer. These are stable for a given release. */
-        kColorTransferExtendedStart = kColorTransferMax + 1,
-
-        /* This marks a section of color-transfer values that are not supported by graphics HAL
-           nor defined by media. These may differ per device. */
-        kColorTransferVendorStart = 0x10000,
-    };
-
-    enum ColorRange : uint32_t  {
-        kColorRangeUnspecified = HAL_DATASPACE_RANGE_UNSPECIFIED >> HAL_DATASPACE_RANGE_SHIFT,
-        kColorRangeFull =        HAL_DATASPACE_RANGE_FULL >> HAL_DATASPACE_RANGE_SHIFT,
-        kColorRangeLimited =     HAL_DATASPACE_RANGE_LIMITED >> HAL_DATASPACE_RANGE_SHIFT,
-        kColorRangeMax =         HAL_DATASPACE_RANGE_MASK >> HAL_DATASPACE_RANGE_SHIFT,
-
-        /* This marks a section of color-transfer values that are not supported by graphics HAL,
-           but track media-defined color-transfer. These are stable for a given release. */
-        kColorRangeExtendedStart = kColorRangeMax + 1,
-
-        /* This marks a section of color-transfer values that are not supported by graphics HAL
-           nor defined by media. These may differ per device. */
-        kColorRangeVendorStart = 0x10000,
-    };
-
-    /*
-     * Static utilities for codec support
-     */
-
-    // using int32_t for media range/standard/transfers to denote extended ranges
-    static int32_t wrapColorAspectsIntoColorStandard(
-            ColorAspects::Primaries primaries, ColorAspects::MatrixCoeffs coeffs);
-    static int32_t wrapColorAspectsIntoColorRange(ColorAspects::Range range);
-    static int32_t wrapColorAspectsIntoColorTransfer(ColorAspects::Transfer transfer);
-
-    static status_t unwrapColorAspectsFromColorRange(
-            int32_t range, ColorAspects::Range *aspect);
-    static status_t unwrapColorAspectsFromColorTransfer(
-            int32_t transfer, ColorAspects::Transfer *aspect);
-    static status_t unwrapColorAspectsFromColorStandard(
-            int32_t standard,
-            ColorAspects::Primaries *primaries, ColorAspects::MatrixCoeffs *coeffs);
-
-    static status_t convertPlatformColorAspectsToCodecAspects(
-            int32_t range, int32_t standard, int32_t transfer, ColorAspects &aspects);
-    static status_t convertCodecColorAspectsToPlatformAspects(
-            const ColorAspects &aspects,
-            int32_t *range, int32_t *standard, int32_t *transfer);
-
-    // updates unspecified range, standard and transfer values to their defaults
-    static void setDefaultPlatformColorAspectsIfNeeded(
-            int32_t &range, int32_t &standard, int32_t &transfer,
-            int32_t width, int32_t height);
-    static void setDefaultCodecColorAspectsIfNeeded(
-            ColorAspects &aspects, int32_t width, int32_t height);
-
 protected:
     CodecBase();
     virtual ~CodecBase();
diff --git a/include/media/stagefright/MetaData.h b/include/media/stagefright/MetaData.h
index 91341b8..7d2208c 100644
--- a/include/media/stagefright/MetaData.h
+++ b/include/media/stagefright/MetaData.h
@@ -188,6 +188,19 @@
 
     // Size of NALU length in mkv/mp4
     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.
+
+    // color aspects
+    kKeyColorRange       = 'cRng', // int32_t, color range, value defined by ColorAspects.Range
+    kKeyColorPrimaries   = 'cPrm', // int32_t,
+                                   // color Primaries, value defined by ColorAspects.Primaries
+    kKeyTransferFunction = 'tFun', // int32_t,
+                                   // transfer Function, value defined by ColorAspects.Transfer.
+    kKeyColorMatrix      = 'cMtx', // int32_t,
+                                   // color Matrix, value defined by ColorAspects.MatrixCoeffs.
 };
 
 enum {
diff --git a/include/media/stagefright/foundation/ColorUtils.h b/include/media/stagefright/foundation/ColorUtils.h
new file mode 100644
index 0000000..b95c80b
--- /dev/null
+++ b/include/media/stagefright/foundation/ColorUtils.h
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef COLOR_UTILS_H_
+
+#define COLOR_UTILS_H_
+
+#include <stdint.h>
+
+#define STRINGIFY_ENUMS
+
+#include <media/stagefright/foundation/AMessage.h>
+
+#include <media/hardware/VideoAPI.h>
+#include <system/graphics.h>
+
+namespace android {
+
+struct ColorUtils {
+    /*
+     * Media-platform color constants. MediaCodec uses (an extended version of) platform-defined
+     * constants that are derived from HAL_DATASPACE, since these are directly exposed to the user.
+     * We extend the values to maintain the richer set of information defined inside media
+     * containers and bitstreams that are not supported by the platform. We also expect vendors
+     * to extend some of these values with vendor-specific values. These are separated into a
+     * vendor-extension section so they won't collide with future platform values.
+     */
+
+#define GET_HAL_ENUM(class, name) HAL_DATASPACE_##class##name
+#define GET_HAL_BITFIELD(class, name) (GET_HAL_ENUM(class, _##name) >> GET_HAL_ENUM(class, _SHIFT))
+
+    enum ColorStandard : uint32_t {
+        kColorStandardUnspecified =          GET_HAL_BITFIELD(STANDARD, UNSPECIFIED),
+        kColorStandardBT709 =                GET_HAL_BITFIELD(STANDARD, BT709),
+        kColorStandardBT601_625 =            GET_HAL_BITFIELD(STANDARD, BT601_625),
+        kColorStandardBT601_625_Unadjusted = GET_HAL_BITFIELD(STANDARD, BT601_625_UNADJUSTED),
+        kColorStandardBT601_525 =            GET_HAL_BITFIELD(STANDARD, BT601_525),
+        kColorStandardBT601_525_Unadjusted = GET_HAL_BITFIELD(STANDARD, BT601_525_UNADJUSTED),
+        kColorStandardBT2020 =               GET_HAL_BITFIELD(STANDARD, BT2020),
+        kColorStandardBT2020Constant =       GET_HAL_BITFIELD(STANDARD, BT2020_CONSTANT_LUMINANCE),
+        kColorStandardBT470M =               GET_HAL_BITFIELD(STANDARD, BT470M),
+        kColorStandardFilm =                 GET_HAL_BITFIELD(STANDARD, FILM),
+        kColorStandardMax =                  GET_HAL_BITFIELD(STANDARD, MASK),
+
+        /* This marks a section of color-standard values that are not supported by graphics HAL,
+           but track defined color primaries-matrix coefficient combinations in media.
+           These are stable for a given release. */
+        kColorStandardExtendedStart = kColorStandardMax + 1,
+
+        /* This marks a section of color-standard values that are not supported by graphics HAL
+           nor using media defined color primaries or matrix coefficients. These may differ per
+           device. */
+        kColorStandardVendorStart = 0x10000,
+    };
+
+    enum ColorTransfer : uint32_t  {
+        kColorTransferUnspecified = GET_HAL_BITFIELD(TRANSFER, UNSPECIFIED),
+        kColorTransferLinear =      GET_HAL_BITFIELD(TRANSFER, LINEAR),
+        kColorTransferSRGB =        GET_HAL_BITFIELD(TRANSFER, SRGB),
+        kColorTransferSMPTE_170M =  GET_HAL_BITFIELD(TRANSFER, SMPTE_170M),
+        kColorTransferGamma22 =     GET_HAL_BITFIELD(TRANSFER, GAMMA2_2),
+        kColorTransferGamma28 =     GET_HAL_BITFIELD(TRANSFER, GAMMA2_8),
+        kColorTransferST2084 =      GET_HAL_BITFIELD(TRANSFER, ST2084),
+        kColorTransferHLG =         GET_HAL_BITFIELD(TRANSFER, HLG),
+        kColorTransferMax =         GET_HAL_BITFIELD(TRANSFER, MASK),
+
+        /* This marks a section of color-transfer values that are not supported by graphics HAL,
+           but track media-defined color-transfer. These are stable for a given release. */
+        kColorTransferExtendedStart = kColorTransferMax + 1,
+
+        /* This marks a section of color-transfer values that are not supported by graphics HAL
+           nor defined by media. These may differ per device. */
+        kColorTransferVendorStart = 0x10000,
+    };
+
+    enum ColorRange : uint32_t  {
+        kColorRangeUnspecified = GET_HAL_BITFIELD(RANGE, UNSPECIFIED),
+        kColorRangeFull =        GET_HAL_BITFIELD(RANGE, FULL),
+        kColorRangeLimited =     GET_HAL_BITFIELD(RANGE, LIMITED),
+        kColorRangeMax =         GET_HAL_BITFIELD(RANGE, MASK),
+
+        /* This marks a section of color-transfer values that are not supported by graphics HAL,
+           but track media-defined color-transfer. These are stable for a given release. */
+        kColorRangeExtendedStart = kColorRangeMax + 1,
+
+        /* This marks a section of color-transfer values that are not supported by graphics HAL
+           nor defined by media. These may differ per device. */
+        kColorRangeVendorStart = 0x10000,
+    };
+
+#undef GET_HAL_BITFIELD
+#undef GET_HAL_ENUM
+
+    /*
+     * Static utilities for codec support
+     */
+
+    // using int32_t for media range/standard/transfers to denote extended ranges
+    // wrap methods change invalid aspects to the Unspecified value
+    static int32_t wrapColorAspectsIntoColorStandard(
+            ColorAspects::Primaries primaries, ColorAspects::MatrixCoeffs coeffs);
+    static int32_t wrapColorAspectsIntoColorRange(ColorAspects::Range range);
+    static int32_t wrapColorAspectsIntoColorTransfer(ColorAspects::Transfer transfer);
+
+    // unwrap methods change invalid aspects to the Other value
+    static status_t unwrapColorAspectsFromColorRange(
+            int32_t range, ColorAspects::Range *aspect);
+    static status_t unwrapColorAspectsFromColorTransfer(
+            int32_t transfer, ColorAspects::Transfer *aspect);
+    static status_t unwrapColorAspectsFromColorStandard(
+            int32_t standard,
+            ColorAspects::Primaries *primaries, ColorAspects::MatrixCoeffs *coeffs);
+
+    static status_t convertPlatformColorAspectsToCodecAspects(
+            int32_t range, int32_t standard, int32_t transfer, ColorAspects &aspects);
+    static status_t convertCodecColorAspectsToPlatformAspects(
+            const ColorAspects &aspects, int32_t *range, int32_t *standard, int32_t *transfer);
+
+    // updates unspecified range, standard and transfer values to their defaults
+    static void setDefaultPlatformColorAspectsIfNeeded(
+            int32_t &range, int32_t &standard, int32_t &transfer, int32_t width, int32_t height);
+    static void setDefaultCodecColorAspectsIfNeeded(
+            ColorAspects &aspects, int32_t width, int32_t height);
+};
+
+inline static const char *asString(android::ColorUtils::ColorStandard i, const char *def = "??") {
+    using namespace android;
+    switch (i) {
+        case ColorUtils::kColorStandardUnspecified:          return "Unspecified";
+        case ColorUtils::kColorStandardBT709:                return "BT709";
+        case ColorUtils::kColorStandardBT601_625:            return "BT601_625";
+        case ColorUtils::kColorStandardBT601_625_Unadjusted: return "BT601_625_Unadjusted";
+        case ColorUtils::kColorStandardBT601_525:            return "BT601_525";
+        case ColorUtils::kColorStandardBT601_525_Unadjusted: return "BT601_525_Unadjusted";
+        case ColorUtils::kColorStandardBT2020:               return "BT2020";
+        case ColorUtils::kColorStandardBT2020Constant:       return "BT2020Constant";
+        case ColorUtils::kColorStandardBT470M:               return "BT470M";
+        case ColorUtils::kColorStandardFilm:                 return "Film";
+        default:                                            return def;
+    }
+}
+
+inline static const char *asString(android::ColorUtils::ColorTransfer i, const char *def = "??") {
+    using namespace android;
+    switch (i) {
+        case ColorUtils::kColorTransferUnspecified: return "Unspecified";
+        case ColorUtils::kColorTransferLinear:      return "Linear";
+        case ColorUtils::kColorTransferSRGB:        return "SRGB";
+        case ColorUtils::kColorTransferSMPTE_170M:  return "SMPTE_170M";
+        case ColorUtils::kColorTransferGamma22:     return "Gamma22";
+        case ColorUtils::kColorTransferGamma28:     return "Gamma28";
+        case ColorUtils::kColorTransferST2084:      return "ST2084";
+        case ColorUtils::kColorTransferHLG:         return "HLG";
+        default:                                   return def;
+    }
+}
+
+inline static const char *asString(android::ColorUtils::ColorRange i, const char *def = "??") {
+    using namespace android;
+    switch (i) {
+        case ColorUtils::kColorRangeUnspecified: return "Unspecified";
+        case ColorUtils::kColorRangeFull:        return "Full";
+        case ColorUtils::kColorRangeLimited:     return "Limited";
+        default:                                return def;
+    }
+}
+
+}  // namespace android
+
+#endif  // COLOR_UTILS_H_
+
diff --git a/media/img_utils/include/img_utils/TagDefinitions.h b/media/img_utils/include/img_utils/TagDefinitions.h
index e9a7480..1cc9866 100644
--- a/media/img_utils/include/img_utils/TagDefinitions.h
+++ b/media/img_utils/include/img_utils/TagDefinitions.h
@@ -193,6 +193,18 @@
 };
 
 /**
+ * Convenience values for tags with enumerated values
+ */
+
+enum {
+    TAG_ORIENTATION_NORMAL = 1,
+    TAG_ORIENTATION_ROTATE_180 = 3,
+    TAG_ORIENTATION_ROTATE_90 = 6,
+    TAG_ORIENTATION_ROTATE_270 = 8,
+    TAG_ORIENTATION_UNKNOWN = 9
+};
+
+/**
  * TIFF_EP_TAG_DEFINITIONS contains tags defined in the TIFF EP spec
  */
 const TagDefinition_t TIFF_EP_TAG_DEFINITIONS[] =  {
@@ -731,7 +743,7 @@
     { // BlackLevel
         "BlackLevel",
         0xC61Au,
-        LONG,
+        RATIONAL,
         RAW_IFD,
         0,
         UNDEFINED_ENDIAN
diff --git a/media/img_utils/src/DngUtils.cpp b/media/img_utils/src/DngUtils.cpp
index 9473dce..9dc5f05 100644
--- a/media/img_utils/src/DngUtils.cpp
+++ b/media/img_utils/src/DngUtils.cpp
@@ -18,6 +18,7 @@
 
 #include <inttypes.h>
 
+#include <vector>
 #include <math.h>
 
 namespace android {
@@ -63,10 +64,17 @@
     double spacingV = 1.0 / lsmHeight;
     double spacingH = 1.0 / lsmWidth;
 
-    float redMap[lsmWidth * lsmHeight];
-    float greenEvenMap[lsmWidth * lsmHeight];
-    float greenOddMap[lsmWidth * lsmHeight];
-    float blueMap[lsmWidth * lsmHeight];
+    std::vector<float> redMapVector(lsmWidth * lsmHeight);
+    float *redMap = redMapVector.data();
+
+    std::vector<float> greenEvenMapVector(lsmWidth * lsmHeight);
+    float *greenEvenMap = greenEvenMapVector.data();
+
+    std::vector<float> greenOddMapVector(lsmWidth * lsmHeight);
+    float *greenOddMap = greenOddMapVector.data();
+
+    std::vector<float> blueMapVector(lsmWidth * lsmHeight);
+    float *blueMap = blueMapVector.data();
 
     size_t lsmMapSize = lsmWidth * lsmHeight * 4;
 
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index fef20d9..9eb5ec7 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -246,7 +246,7 @@
         mClientPid = pid;
     }
 
-    mFlags = flags;
+    mOrigFlags = mFlags = flags;
     mCbf = cbf;
 
     if (cbf != NULL) {
@@ -518,6 +518,9 @@
     }
     audio_io_handle_t input;
 
+    // mFlags (not mOrigFlags) is modified depending on whether fast request is accepted.
+    // After fast request is denied, we will request again if IAudioRecord is re-created.
+
     status_t status;
     status = AudioSystem::getInputForAttr(&mAttributes, &input,
                                         (audio_session_t)mSessionId,
@@ -569,7 +572,6 @@
             ALOGW("AUDIO_INPUT_FLAG_FAST denied by client; transfer %d, "
                 "track %u Hz, input %u Hz",
                 mTransfer, mSampleRate, afSampleRate);
-            // once denied, do not request again if IAudioRecord is re-created
             mFlags = (audio_input_flags_t) (mFlags & ~AUDIO_INPUT_FLAG_FAST);
         }
     }
@@ -669,8 +671,7 @@
             ALOGV("AUDIO_INPUT_FLAG_FAST successful; frameCount %zu", frameCount);
             mAwaitBoost = true;
         } else {
-            ALOGV("AUDIO_INPUT_FLAG_FAST denied by server; frameCount %zu", frameCount);
-            // once denied, do not request again if IAudioRecord is re-created
+            ALOGW("AUDIO_INPUT_FLAG_FAST denied by server; frameCount %zu", frameCount);
             mFlags = (audio_input_flags_t) (mFlags & ~AUDIO_INPUT_FLAG_FAST);
         }
     }
@@ -1140,6 +1141,8 @@
     ALOGW("dead IAudioRecord, creating a new one from %s()", from);
     ++mSequence;
 
+    mFlags = mOrigFlags;
+
     // if the new IAudioRecord is created, openRecord_l() will modify the
     // following member variables: mAudioRecord, mCblkMemory, mCblk, mBufferMemory.
     // It will also delete the strong references on previous IAudioRecord and IMemory
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index 8e02900..423273d 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -455,7 +455,7 @@
         mClientPid = pid;
     }
     mAuxEffectId = 0;
-    mFlags = flags;
+    mOrigFlags = mFlags = flags;
     mCbf = cbf;
 
     if (cbf != NULL) {
@@ -1153,6 +1153,9 @@
     audio_stream_type_t streamType = mStreamType;
     audio_attributes_t *attr = (mStreamType == AUDIO_STREAM_DEFAULT) ? &mAttributes : NULL;
 
+    // mFlags (not mOrigFlags) is modified depending on whether fast request is accepted.
+    // After fast request is denied, we will request again if IAudioTrack is re-created.
+
     status_t status;
     status = AudioSystem::getOutputForAttr(attr, &output,
                                            (audio_session_t)mSessionId, &streamType, mClientUid,
@@ -1211,7 +1214,6 @@
             ALOGW("AUDIO_OUTPUT_FLAG_FAST denied by client; transfer %d, "
                 "track %u Hz, output %u Hz",
                 mTransfer, mSampleRate, mAfSampleRate);
-            // once denied, do not request again if IAudioTrack is re-created
             mFlags = (audio_output_flags_t) (mFlags & ~AUDIO_OUTPUT_FLAG_FAST);
         }
     }
@@ -1353,31 +1355,10 @@
                 mAwaitBoost = true;
             }
         } else {
-            ALOGV("AUDIO_OUTPUT_FLAG_FAST denied by server; frameCount %zu", frameCount);
-            // once denied, do not request again if IAudioTrack is re-created
+            ALOGW("AUDIO_OUTPUT_FLAG_FAST denied by server; frameCount %zu", frameCount);
             mFlags = (audio_output_flags_t) (mFlags & ~AUDIO_OUTPUT_FLAG_FAST);
         }
     }
-    if (mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
-        if (trackFlags & IAudioFlinger::TRACK_OFFLOAD) {
-            ALOGV("AUDIO_OUTPUT_FLAG_OFFLOAD successful");
-        } else {
-            ALOGW("AUDIO_OUTPUT_FLAG_OFFLOAD denied by server");
-            mFlags = (audio_output_flags_t) (mFlags & ~AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD);
-            // FIXME This is a warning, not an error, so don't return error status
-            //return NO_INIT;
-        }
-    }
-    if (mFlags & AUDIO_OUTPUT_FLAG_DIRECT) {
-        if (trackFlags & IAudioFlinger::TRACK_DIRECT) {
-            ALOGV("AUDIO_OUTPUT_FLAG_DIRECT successful");
-        } else {
-            ALOGW("AUDIO_OUTPUT_FLAG_DIRECT denied by server");
-            mFlags = (audio_output_flags_t) (mFlags & ~AUDIO_OUTPUT_FLAG_DIRECT);
-            // FIXME This is a warning, not an error, so don't return error status
-            //return NO_INIT;
-        }
-    }
 
     // Make sure that application is notified with sufficient margin before underrun.
     // The client's AudioTrack buffer is divided into n parts for purpose of wakeup by server, where
@@ -2089,6 +2070,8 @@
         mStaticProxy->getBufferPositionAndLoopCount(&bufferPosition, &loopCount);
     }
 
+    mFlags = mOrigFlags;
+
     // If a new IAudioTrack is successfully created, createTrack_l() will modify the
     // following member variables: mAudioTrack, mCblkMemory and mCblk.
     // It will also delete the strong references on previous IAudioTrack and IMemory.
diff --git a/media/libstagefright/CodecBase.cpp b/media/libstagefright/CodecBase.cpp
index c9de2b0..f729d4d 100644
--- a/media/libstagefright/CodecBase.cpp
+++ b/media/libstagefright/CodecBase.cpp
@@ -20,8 +20,6 @@
 #include <inttypes.h>
 
 #include <media/stagefright/CodecBase.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/ALookup.h>
 
 namespace android {
 
@@ -37,277 +35,4 @@
 CodecBase::PortDescription::~PortDescription() {
 }
 
-/***************************************** COLOR SUPPORT *****************************************/
-
-// shortcut names for brevity in the following tables
-typedef ColorAspects CA;
-typedef CodecBase CB;
-
-ALookup<CB::ColorRange, CA::Range> sRanges{
-    {
-        { CB::kColorRangeLimited, CA::RangeLimited },
-        { CB::kColorRangeFull, CA::RangeFull },
-        { CB::kColorRangeUnspecified, CA::RangeUnspecified },
-    }
-};
-
-ALookup<CB::ColorStandard, std::pair<CA::Primaries, CA::MatrixCoeffs>> sStandards {
-    {
-        { CB::kColorStandardUnspecified,    { CA::PrimariesUnspecified, CA::MatrixUnspecified } },
-        { CB::kColorStandardBT709,          { CA::PrimariesBT709_5, CA::MatrixBT709_5 } },
-        { CB::kColorStandardBT601_625,      { CA::PrimariesBT601_6_625, CA::MatrixBT601_6 } },
-        { CB::kColorStandardBT601_625_Unadjusted,
-                                            // this is a really close match
-                                            { CA::PrimariesBT601_6_625, CA::MatrixBT709_5 } },
-        { CB::kColorStandardBT601_525,      { CA::PrimariesBT601_6_525, CA::MatrixBT601_6 } },
-        { CB::kColorStandardBT601_525_Unadjusted,
-                                            { CA::PrimariesBT601_6_525, CA::MatrixSMPTE240M } },
-        { CB::kColorStandardBT2020,         { CA::PrimariesBT2020, CA::MatrixBT2020 } },
-        { CB::kColorStandardBT2020Constant, { CA::PrimariesBT2020, CA::MatrixBT2020Constant } },
-        { CB::kColorStandardBT470M,         { CA::PrimariesBT470_6M, CA::MatrixBT470_6M } },
-        // NOTE: there is no close match to the matrix used by standard film, chose closest
-        { CB::kColorStandardFilm,           { CA::PrimariesGenericFilm, CA::MatrixBT2020 } },
-    }
-};
-
-ALookup<CB::ColorTransfer, CA::Transfer> sTransfers{
-    {
-        { CB::kColorTransferUnspecified,    CA::TransferUnspecified },
-        { CB::kColorTransferLinear,         CA::TransferLinear },
-        { CB::kColorTransferSRGB,           CA::TransferSRGB },
-        { CB::kColorTransferSMPTE_170M,     CA::TransferSMPTE170M },
-        { CB::kColorTransferGamma22,        CA::TransferGamma22 },
-        { CB::kColorTransferGamma28,        CA::TransferGamma28 },
-        { CB::kColorTransferST2084,         CA::TransferST2084 },
-        { CB::kColorTransferHLG,            CA::TransferHLG },
-    }
-};
-
-static bool isValid(ColorAspects::Primaries p) {
-    return p <= ColorAspects::PrimariesOther;
-}
-
-static bool isDefined(ColorAspects::Primaries p) {
-    return p <= ColorAspects::PrimariesBT2020;
-}
-
-static bool isValid(ColorAspects::MatrixCoeffs c) {
-    return c <= ColorAspects::MatrixOther;
-}
-
-static bool isDefined(ColorAspects::MatrixCoeffs c) {
-    return c <= ColorAspects::MatrixBT2020Constant;
-}
-
-//static
-int32_t CodecBase::wrapColorAspectsIntoColorStandard(
-        ColorAspects::Primaries primaries, ColorAspects::MatrixCoeffs coeffs) {
-    ColorStandard res;
-    if (sStandards.map(std::make_pair(primaries, coeffs), &res)) {
-        return res;
-    } else if (!isValid(primaries) || !isValid(coeffs)) {
-        return kColorStandardUnspecified;
-    }
-
-    // check platform media limits
-    uint32_t numPrimaries = ColorAspects::PrimariesBT2020 + 1;
-    if (isDefined(primaries) && isDefined(coeffs)) {
-        return kColorStandardExtendedStart + primaries + coeffs * numPrimaries;
-    } else {
-        return kColorStandardVendorStart + primaries + coeffs * 0x100;
-    }
-}
-
-//static
-status_t CodecBase::unwrapColorAspectsFromColorStandard(
-        int32_t standard,
-        ColorAspects::Primaries *primaries, ColorAspects::MatrixCoeffs *coeffs) {
-    std::pair<ColorAspects::Primaries, ColorAspects::MatrixCoeffs> res;
-    if (sStandards.map((ColorStandard)standard, &res)) {
-        *primaries = res.first;
-        *coeffs = res.second;
-        return OK;
-    }
-
-    int32_t start = kColorStandardExtendedStart;
-    int32_t numPrimaries = ColorAspects::PrimariesBT2020 + 1;
-    int32_t numCoeffs = ColorAspects::MatrixBT2020Constant + 1;
-    if (standard >= (int32_t)kColorStandardVendorStart) {
-        start = kColorStandardVendorStart;
-        numPrimaries = ColorAspects::PrimariesOther + 1; // 0x100
-        numCoeffs = ColorAspects::MatrixOther + 1; // 0x100;
-    }
-    if (standard >= start && standard < start + numPrimaries * numCoeffs) {
-        int32_t product = standard - start;
-        *primaries = (ColorAspects::Primaries)(product % numPrimaries);
-        *coeffs = (ColorAspects::MatrixCoeffs)(product / numPrimaries);
-        return OK;
-    }
-    *primaries = ColorAspects::PrimariesOther;
-    *coeffs = ColorAspects::MatrixOther;
-    return BAD_VALUE;
-}
-
-static bool isValid(ColorAspects::Range r) {
-    return r <= ColorAspects::RangeOther;
-}
-
-static bool isDefined(ColorAspects::Range r) {
-    return r <= ColorAspects::RangeLimited;
-}
-
-//  static
-int32_t CodecBase::wrapColorAspectsIntoColorRange(ColorAspects::Range range) {
-    ColorRange res;
-    if (sRanges.map(range, &res)) {
-        return res;
-    } else if (!isValid(range)) {
-        return kColorRangeUnspecified;
-    } else {
-        CHECK(!isDefined(range));
-        // all platform values are in sRanges
-        return kColorRangeVendorStart + range;
-    }
-}
-
-//static
-status_t CodecBase::unwrapColorAspectsFromColorRange(
-        int32_t range, ColorAspects::Range *aspect) {
-    if (sRanges.map((ColorRange)range, aspect)) {
-        return OK;
-    }
-
-    int32_t start = kColorRangeVendorStart;
-    int32_t numRanges = ColorAspects::RangeOther + 1; // 0x100
-    if (range >= start && range < start + numRanges) {
-        *aspect = (ColorAspects::Range)(range - start);
-        return OK;
-    }
-    *aspect = ColorAspects::RangeOther;
-    return BAD_VALUE;
-}
-
-static bool isValid(ColorAspects::Transfer t) {
-    return t <= ColorAspects::TransferOther;
-}
-
-static bool isDefined(ColorAspects::Transfer t) {
-    return t <= ColorAspects::TransferHLG
-            || (t >= ColorAspects::TransferSMPTE240M && t <= ColorAspects::TransferST428);
-}
-
-//  static
-int32_t CodecBase::wrapColorAspectsIntoColorTransfer(
-        ColorAspects::Transfer transfer) {
-    ColorTransfer res;
-    if (sTransfers.map(transfer, &res)) {
-        return res;
-    } else if (!isValid(transfer)) {
-        return kColorTransferUnspecified;
-    } else if (isDefined(transfer)) {
-        return kColorTransferExtendedStart + transfer;
-    } else {
-        // all platform values are in sRanges
-        return kColorTransferVendorStart + transfer;
-    }
-}
-
-//static
-status_t CodecBase::unwrapColorAspectsFromColorTransfer(
-        int32_t transfer, ColorAspects::Transfer *aspect) {
-    if (sTransfers.map((ColorTransfer)transfer, aspect)) {
-        return OK;
-    }
-
-    int32_t start = kColorTransferExtendedStart;
-    int32_t numTransfers = ColorAspects::TransferST428 + 1;
-    if (transfer >= (int32_t)kColorTransferVendorStart) {
-        start = kColorTransferVendorStart;
-        numTransfers = ColorAspects::TransferOther + 1; // 0x100
-    }
-    if (transfer >= start && transfer < start + numTransfers) {
-        *aspect = (ColorAspects::Transfer)(transfer - start);
-        return OK;
-    }
-    *aspect = ColorAspects::TransferOther;
-    return BAD_VALUE;
-}
-
-// static
-status_t CodecBase::convertPlatformColorAspectsToCodecAspects(
-    int32_t range, int32_t standard, int32_t transfer, ColorAspects &aspects) {
-    status_t res1 = unwrapColorAspectsFromColorRange(range, &aspects.mRange);
-    status_t res2 = unwrapColorAspectsFromColorStandard(
-            standard, &aspects.mPrimaries, &aspects.mMatrixCoeffs);
-    status_t res3 = unwrapColorAspectsFromColorTransfer(transfer, &aspects.mTransfer);
-    return res1 != OK ? res1 : (res2 != OK ? res2 : res3);
-}
-
-// static
-status_t CodecBase::convertCodecColorAspectsToPlatformAspects(
-    const ColorAspects &aspects, int32_t *range, int32_t *standard, int32_t *transfer) {
-    *range = wrapColorAspectsIntoColorRange(aspects.mRange);
-    *standard = wrapColorAspectsIntoColorStandard(aspects.mPrimaries, aspects.mMatrixCoeffs);
-    *transfer = wrapColorAspectsIntoColorTransfer(aspects.mTransfer);
-    if (isValid(aspects.mRange) && isValid(aspects.mPrimaries)
-            && isValid(aspects.mMatrixCoeffs) && isValid(aspects.mTransfer)) {
-        return OK;
-    } else {
-        return BAD_VALUE;
-    }
-}
-
-// static
-void CodecBase::setDefaultPlatformColorAspectsIfNeeded(
-        int32_t &range, int32_t &standard, int32_t &transfer,
-        int32_t width, int32_t height) {
-    if (range == CodecBase::kColorRangeUnspecified) {
-        range = CodecBase::kColorRangeLimited;
-    }
-
-    if (standard == CodecBase::kColorStandardUnspecified) {
-        // Default to BT2020, BT709 or BT601 based on size. Allow 2.35:1 aspect ratio. Limit BT601
-        // to PAL or smaller, BT2020 to 4K or larger, leaving BT709 for all resolutions in between.
-        if (width >= 3840 || height >= 3840 || width * (int64_t)height >= 3840 * 1634) {
-            standard = CodecBase::kColorStandardBT2020;
-        } else if ((width <= 720 && height > 480) || (height <= 720 && width > 480)) {
-            standard = CodecBase::kColorStandardBT601_625;
-        } else if ((width <= 720 && height <= 480) || (height <= 720 && width <= 480)) {
-            standard = CodecBase::kColorStandardBT601_525;
-        } else {
-            standard = CodecBase::kColorStandardBT709;
-        }
-    }
-
-    if (transfer == CodecBase::kColorTransferUnspecified) {
-        transfer = CodecBase::kColorTransferSMPTE_170M;
-    }
-}
-
-// static
-void CodecBase::setDefaultCodecColorAspectsIfNeeded(
-        ColorAspects &aspects, int32_t width, int32_t height) {
-    // reuse other method to get default aspects
-    int32_t range = 0, standard = 0, transfer = 0;
-    setDefaultPlatformColorAspectsIfNeeded(range, standard, transfer, width, height);
-    ColorAspects defaultAspects;
-    memset(&defaultAspects, 0, sizeof(defaultAspects));
-    convertPlatformColorAspectsToCodecAspects(range, standard, transfer, defaultAspects);
-
-    if (aspects.mRange == ColorAspects::RangeUnspecified) {
-        aspects.mRange = defaultAspects.mRange;
-    }
-    if (aspects.mPrimaries == ColorAspects::PrimariesUnspecified) {
-        aspects.mPrimaries = defaultAspects.mPrimaries;
-    }
-    if (aspects.mMatrixCoeffs == ColorAspects::MatrixUnspecified) {
-        aspects.mMatrixCoeffs = defaultAspects.mMatrixCoeffs;
-    }
-    if (aspects.mTransfer == ColorAspects::TransferUnspecified) {
-        aspects.mTransfer = defaultAspects.mTransfer;
-    }
-}
-
-/**************************************************************************************************/
-
 }  // namespace android
diff --git a/media/libstagefright/MediaCodecSource.cpp b/media/libstagefright/MediaCodecSource.cpp
index bdfddc7..5f9a1c0 100644
--- a/media/libstagefright/MediaCodecSource.cpp
+++ b/media/libstagefright/MediaCodecSource.cpp
@@ -286,6 +286,7 @@
                 }
                 if (queue->mPulling && err == OK) {
                     msg->post(); // if simply paused, keep pulling source
+                    break;
                 } else if (err == ERROR_END_OF_STREAM) {
                     ALOGV("stream ended, mbuf %p", mbuf);
                 } else if (err != OK) {
diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp
index dcc29fe..34deaad 100644
--- a/media/libstagefright/Utils.cpp
+++ b/media/libstagefright/Utils.cpp
@@ -27,6 +27,7 @@
 #include <arpa/inet.h>
 #include <cutils/properties.h>
 #include <media/openmax/OMX_Audio.h>
+#include <media/stagefright/CodecBase.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/AMessage.h>
@@ -90,6 +91,49 @@
     return OK;
 }
 
+static void convertMetaDataToMessageInt32(
+        const sp<MetaData> &meta, sp<AMessage> &msg, uint32_t key, const char *name) {
+    int32_t value;
+    if (meta->findInt32(key, &value)) {
+        msg->setInt32(name, value);
+    }
+}
+
+static void convertMetaDataToMessageColorAspects(const sp<MetaData> &meta, sp<AMessage> &msg) {
+    // 0 values are unspecified
+    int32_t range = 0;
+    int32_t primaries = 0;
+    int32_t transferFunction = 0;
+    int32_t colorMatrix = 0;
+    meta->findInt32(kKeyColorRange, &range);
+    meta->findInt32(kKeyColorPrimaries, &primaries);
+    meta->findInt32(kKeyTransferFunction, &transferFunction);
+    meta->findInt32(kKeyColorMatrix, &colorMatrix);
+    ColorAspects colorAspects;
+    memset(&colorAspects, 0, sizeof(colorAspects));
+    colorAspects.mRange = (ColorAspects::Range)range;
+    colorAspects.mPrimaries = (ColorAspects::Primaries)primaries;
+    colorAspects.mTransfer = (ColorAspects::Transfer)transferFunction;
+    colorAspects.mMatrixCoeffs = (ColorAspects::MatrixCoeffs)colorMatrix;
+
+    int32_t rangeMsg, standardMsg, transferMsg;
+    if (CodecBase::convertCodecColorAspectsToPlatformAspects(
+            colorAspects, &rangeMsg, &standardMsg, &transferMsg) != OK) {
+        return;
+    }
+
+    // save specified values to msg
+    if (rangeMsg != 0) {
+        msg->setInt32("color-range", rangeMsg);
+    }
+    if (standardMsg != 0) {
+        msg->setInt32("color-standard", standardMsg);
+    }
+    if (transferMsg != 0) {
+        msg->setInt32("color-transfer", transferMsg);
+    }
+}
+
 status_t convertMetaDataToMessage(
         const sp<MetaData> &meta, sp<AMessage> *format) {
 
@@ -158,6 +202,10 @@
         if (meta->findInt32(kKeyRotation, &rotationDegrees)) {
             msg->setInt32("rotation-degrees", rotationDegrees);
         }
+
+        convertMetaDataToMessageInt32(meta, msg, kKeyMinLuminance, "min-luminance");
+        convertMetaDataToMessageInt32(meta, msg, kKeyMaxLuminance, "max-luminance");
+        convertMetaDataToMessageColorAspects(meta, msg);
     } else if (!strncasecmp("audio/", mime, 6)) {
         int32_t numChannels, sampleRate;
         if (!meta->findInt32(kKeyChannelCount, &numChannels)
@@ -626,6 +674,43 @@
     return size;
 }
 
+static void convertMessageToMetaDataInt32(
+        const sp<AMessage> &msg, sp<MetaData> &meta, uint32_t key, const char *name) {
+    int32_t value;
+    if (msg->findInt32(name, &value)) {
+        meta->setInt32(key, value);
+    }
+}
+
+static void convertMessageToMetaDataColorAspects(const sp<AMessage> &msg, sp<MetaData> &meta) {
+    // 0 values are unspecified
+    int32_t range = 0, standard = 0, transfer = 0;
+    (void)msg->findInt32("color-range", &range);
+    (void)msg->findInt32("color-standard", &standard);
+    (void)msg->findInt32("color-transfer", &transfer);
+
+    ColorAspects colorAspects;
+    memset(&colorAspects, 0, sizeof(colorAspects));
+    if (CodecBase::convertPlatformColorAspectsToCodecAspects(
+            range, standard, transfer, colorAspects) != OK) {
+        return;
+    }
+
+    // save specified values to meta
+    if (colorAspects.mRange != 0) {
+        meta->setInt32(kKeyColorRange, colorAspects.mRange);
+    }
+    if (colorAspects.mPrimaries != 0) {
+        meta->setInt32(kKeyColorPrimaries, colorAspects.mPrimaries);
+    }
+    if (colorAspects.mTransfer != 0) {
+        meta->setInt32(kKeyTransferFunction, colorAspects.mTransfer);
+    }
+    if (colorAspects.mMatrixCoeffs != 0) {
+        meta->setInt32(kKeyColorMatrix, colorAspects.mMatrixCoeffs);
+    }
+}
+
 void convertMessageToMetaData(const sp<AMessage> &msg, sp<MetaData> &meta) {
     AString mime;
     if (msg->findString("mime", &mime)) {
@@ -679,6 +764,10 @@
         if (msg->findInt32("rotation-degrees", &rotationDegrees)) {
             meta->setInt32(kKeyRotation, rotationDegrees);
         }
+
+        convertMessageToMetaDataInt32(msg, meta, kKeyMinLuminance, "min-luminance");
+        convertMessageToMetaDataInt32(msg, meta, kKeyMaxLuminance, "max-luminance");
+        convertMessageToMetaDataColorAspects(msg, meta);
     } else if (mime.startsWith("audio/")) {
         int32_t numChannels;
         if (msg->findInt32("channel-count", &numChannels)) {
diff --git a/media/libstagefright/foundation/Android.mk b/media/libstagefright/foundation/Android.mk
index 711601f..3c3ed59 100644
--- a/media/libstagefright/foundation/Android.mk
+++ b/media/libstagefright/foundation/Android.mk
@@ -15,6 +15,7 @@
     AString.cpp                   \
     AStringUtils.cpp              \
     AWakeLock.cpp                 \
+    ColorUtils.cpp                \
     MediaBuffer.cpp               \
     MediaBufferGroup.cpp          \
     MetaData.cpp                  \
diff --git a/media/libstagefright/foundation/ColorUtils.cpp b/media/libstagefright/foundation/ColorUtils.cpp
new file mode 100644
index 0000000..2b86b0e
--- /dev/null
+++ b/media/libstagefright/foundation/ColorUtils.cpp
@@ -0,0 +1,312 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "ColorUtils"
+
+#include <inttypes.h>
+
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/ALookup.h>
+#include <media/stagefright/foundation/ColorUtils.h>
+
+namespace android {
+
+// shortcut names for brevity in the following tables
+typedef ColorAspects CA;
+typedef ColorUtils CU;
+
+ALookup<CU::ColorRange, CA::Range> sRanges{
+    {
+        { CU::kColorRangeLimited, CA::RangeLimited },
+        { CU::kColorRangeFull, CA::RangeFull },
+        { CU::kColorRangeUnspecified, CA::RangeUnspecified },
+    }
+};
+
+ALookup<CU::ColorStandard, std::pair<CA::Primaries, CA::MatrixCoeffs>> sStandards {
+    {
+        { CU::kColorStandardUnspecified,    { CA::PrimariesUnspecified, CA::MatrixUnspecified } },
+        { CU::kColorStandardBT709,          { CA::PrimariesBT709_5, CA::MatrixBT709_5 } },
+        { CU::kColorStandardBT601_625,      { CA::PrimariesBT601_6_625, CA::MatrixBT601_6 } },
+        { CU::kColorStandardBT601_625_Unadjusted,
+                                            // this is a really close match
+                                            { CA::PrimariesBT601_6_625, CA::MatrixBT709_5 } },
+        { CU::kColorStandardBT601_525,      { CA::PrimariesBT601_6_525, CA::MatrixBT601_6 } },
+        { CU::kColorStandardBT601_525_Unadjusted,
+                                            { CA::PrimariesBT601_6_525, CA::MatrixSMPTE240M } },
+        { CU::kColorStandardBT2020,         { CA::PrimariesBT2020, CA::MatrixBT2020 } },
+        { CU::kColorStandardBT2020Constant, { CA::PrimariesBT2020, CA::MatrixBT2020Constant } },
+        { CU::kColorStandardBT470M,         { CA::PrimariesBT470_6M, CA::MatrixBT470_6M } },
+        // NOTE: there is no close match to the matrix used by standard film, chose closest
+        { CU::kColorStandardFilm,           { CA::PrimariesGenericFilm, CA::MatrixBT2020 } },
+    }
+};
+
+ALookup<CU::ColorTransfer, CA::Transfer> sTransfers{
+    {
+        { CU::kColorTransferUnspecified,    CA::TransferUnspecified },
+        { CU::kColorTransferLinear,         CA::TransferLinear },
+        { CU::kColorTransferSRGB,           CA::TransferSRGB },
+        { CU::kColorTransferSMPTE_170M,     CA::TransferSMPTE170M },
+        { CU::kColorTransferGamma22,        CA::TransferGamma22 },
+        { CU::kColorTransferGamma28,        CA::TransferGamma28 },
+        { CU::kColorTransferST2084,         CA::TransferST2084 },
+        { CU::kColorTransferHLG,            CA::TransferHLG },
+    }
+};
+
+static bool isValid(ColorAspects::Primaries p) {
+    return p <= ColorAspects::PrimariesOther;
+}
+
+static bool isDefined(ColorAspects::Primaries p) {
+    return p <= ColorAspects::PrimariesBT2020;
+}
+
+static bool isValid(ColorAspects::MatrixCoeffs c) {
+    return c <= ColorAspects::MatrixOther;
+}
+
+static bool isDefined(ColorAspects::MatrixCoeffs c) {
+    return c <= ColorAspects::MatrixBT2020Constant;
+}
+
+//static
+int32_t ColorUtils::wrapColorAspectsIntoColorStandard(
+        ColorAspects::Primaries primaries, ColorAspects::MatrixCoeffs coeffs) {
+    ColorStandard res;
+    if (sStandards.map(std::make_pair(primaries, coeffs), &res)) {
+        return res;
+    } else if (!isValid(primaries) || !isValid(coeffs)) {
+        return kColorStandardUnspecified;
+    }
+
+    // check platform media limits
+    uint32_t numPrimaries = ColorAspects::PrimariesBT2020 + 1;
+    if (isDefined(primaries) && isDefined(coeffs)) {
+        return kColorStandardExtendedStart + primaries + coeffs * numPrimaries;
+    } else {
+        return kColorStandardVendorStart + primaries + coeffs * 0x100;
+    }
+}
+
+//static
+status_t ColorUtils::unwrapColorAspectsFromColorStandard(
+        int32_t standard,
+        ColorAspects::Primaries *primaries, ColorAspects::MatrixCoeffs *coeffs) {
+    std::pair<ColorAspects::Primaries, ColorAspects::MatrixCoeffs> res;
+    if (sStandards.map((ColorStandard)standard, &res)) {
+        *primaries = res.first;
+        *coeffs = res.second;
+        return OK;
+    }
+
+    int32_t start = kColorStandardExtendedStart;
+    int32_t numPrimaries = ColorAspects::PrimariesBT2020 + 1;
+    int32_t numCoeffs = ColorAspects::MatrixBT2020Constant + 1;
+    if (standard >= (int32_t)kColorStandardVendorStart) {
+        start = kColorStandardVendorStart;
+        numPrimaries = ColorAspects::PrimariesOther + 1; // 0x100
+        numCoeffs = ColorAspects::MatrixOther + 1; // 0x100;
+    }
+    if (standard >= start && standard < start + numPrimaries * numCoeffs) {
+        int32_t product = standard - start;
+        *primaries = (ColorAspects::Primaries)(product % numPrimaries);
+        *coeffs = (ColorAspects::MatrixCoeffs)(product / numPrimaries);
+        return OK;
+    }
+    *primaries = ColorAspects::PrimariesOther;
+    *coeffs = ColorAspects::MatrixOther;
+    return BAD_VALUE;
+}
+
+static bool isValid(ColorAspects::Range r) {
+    return r <= ColorAspects::RangeOther;
+}
+
+static bool isDefined(ColorAspects::Range r) {
+    return r <= ColorAspects::RangeLimited;
+}
+
+//  static
+int32_t ColorUtils::wrapColorAspectsIntoColorRange(ColorAspects::Range range) {
+    ColorRange res;
+    if (sRanges.map(range, &res)) {
+        return res;
+    } else if (!isValid(range)) {
+        return kColorRangeUnspecified;
+    } else {
+        CHECK(!isDefined(range));
+        // all platform values are in sRanges
+        return kColorRangeVendorStart + range;
+    }
+}
+
+//static
+status_t ColorUtils::unwrapColorAspectsFromColorRange(
+        int32_t range, ColorAspects::Range *aspect) {
+    if (sRanges.map((ColorRange)range, aspect)) {
+        return OK;
+    }
+
+    int32_t start = kColorRangeVendorStart;
+    int32_t numRanges = ColorAspects::RangeOther + 1; // 0x100
+    if (range >= start && range < start + numRanges) {
+        *aspect = (ColorAspects::Range)(range - start);
+        return OK;
+    }
+    *aspect = ColorAspects::RangeOther;
+    return BAD_VALUE;
+}
+
+static bool isValid(ColorAspects::Transfer t) {
+    return t <= ColorAspects::TransferOther;
+}
+
+static bool isDefined(ColorAspects::Transfer t) {
+    return t <= ColorAspects::TransferHLG
+            || (t >= ColorAspects::TransferSMPTE240M && t <= ColorAspects::TransferST428);
+}
+
+//  static
+int32_t ColorUtils::wrapColorAspectsIntoColorTransfer(
+        ColorAspects::Transfer transfer) {
+    ColorTransfer res;
+    if (sTransfers.map(transfer, &res)) {
+        return res;
+    } else if (!isValid(transfer)) {
+        return kColorTransferUnspecified;
+    } else if (isDefined(transfer)) {
+        return kColorTransferExtendedStart + transfer;
+    } else {
+        // all platform values are in sRanges
+        return kColorTransferVendorStart + transfer;
+    }
+}
+
+//static
+status_t ColorUtils::unwrapColorAspectsFromColorTransfer(
+        int32_t transfer, ColorAspects::Transfer *aspect) {
+    if (sTransfers.map((ColorTransfer)transfer, aspect)) {
+        return OK;
+    }
+
+    int32_t start = kColorTransferExtendedStart;
+    int32_t numTransfers = ColorAspects::TransferST428 + 1;
+    if (transfer >= (int32_t)kColorTransferVendorStart) {
+        start = kColorTransferVendorStart;
+        numTransfers = ColorAspects::TransferOther + 1; // 0x100
+    }
+    if (transfer >= start && transfer < start + numTransfers) {
+        *aspect = (ColorAspects::Transfer)(transfer - start);
+        return OK;
+    }
+    *aspect = ColorAspects::TransferOther;
+    return BAD_VALUE;
+}
+
+// static
+status_t ColorUtils::convertPlatformColorAspectsToCodecAspects(
+    int32_t range, int32_t standard, int32_t transfer, ColorAspects &aspects) {
+    status_t res1 = unwrapColorAspectsFromColorRange(range, &aspects.mRange);
+    status_t res2 = unwrapColorAspectsFromColorStandard(
+            standard, &aspects.mPrimaries, &aspects.mMatrixCoeffs);
+    status_t res3 = unwrapColorAspectsFromColorTransfer(transfer, &aspects.mTransfer);
+    return res1 != OK ? res1 : (res2 != OK ? res2 : res3);
+}
+
+// static
+status_t ColorUtils::convertCodecColorAspectsToPlatformAspects(
+    const ColorAspects &aspects, int32_t *range, int32_t *standard, int32_t *transfer) {
+    *range = wrapColorAspectsIntoColorRange(aspects.mRange);
+    *standard = wrapColorAspectsIntoColorStandard(aspects.mPrimaries, aspects.mMatrixCoeffs);
+    *transfer = wrapColorAspectsIntoColorTransfer(aspects.mTransfer);
+    if (isValid(aspects.mRange) && isValid(aspects.mPrimaries)
+            && isValid(aspects.mMatrixCoeffs) && isValid(aspects.mTransfer)) {
+        return OK;
+    } else {
+        return BAD_VALUE;
+    }
+}
+
+// static
+void ColorUtils::setDefaultPlatformColorAspectsIfNeeded(
+        int32_t &range, int32_t &standard, int32_t &transfer,
+        int32_t width, int32_t height) {
+    if (range == ColorUtils::kColorRangeUnspecified) {
+        range = ColorUtils::kColorRangeLimited;
+    }
+
+    if (standard == ColorUtils::kColorStandardUnspecified) {
+        // Default to BT2020, BT709 or BT601 based on size. Allow 2.35:1 aspect ratio. Limit BT601
+        // to PAL or smaller, BT2020 to 4K or larger, leaving BT709 for all resolutions in between.
+        if (width >= 3840 || height >= 3840 || width * (int64_t)height >= 3840 * 1634) {
+            standard = ColorUtils::kColorStandardBT2020;
+        } else if ((width <= 720 && height > 480) || (height <= 720 && width > 480)) {
+            standard = ColorUtils::kColorStandardBT601_625;
+        } else if ((width <= 720 && height <= 480) || (height <= 720 && width <= 480)) {
+            standard = ColorUtils::kColorStandardBT601_525;
+        } else {
+            standard = ColorUtils::kColorStandardBT709;
+        }
+    }
+
+    if (transfer == ColorUtils::kColorTransferUnspecified) {
+        transfer = ColorUtils::kColorTransferSMPTE_170M;
+    }
+}
+
+// static
+void ColorUtils::setDefaultCodecColorAspectsIfNeeded(
+        ColorAspects &aspects, int32_t width, int32_t height) {
+    ColorAspects::MatrixCoeffs coeffs;
+    ColorAspects::Primaries primaries;
+
+    // Default to BT2020, BT709 or BT601 based on size. Allow 2.35:1 aspect ratio. Limit BT601
+    // to PAL or smaller, BT2020 to 4K or larger, leaving BT709 for all resolutions in between.
+    if (width >= 3840 || height >= 3840 || width * (int64_t)height >= 3840 * 1634) {
+        primaries = ColorAspects::PrimariesBT2020;
+        coeffs = ColorAspects::MatrixBT2020;
+    } else if ((width <= 720 && height > 480 && height <= 576)
+            || (height <= 720 && width > 480 && width <= 576)) {
+        primaries = ColorAspects::PrimariesBT601_6_625;
+        coeffs = ColorAspects::MatrixBT601_6;
+    } else if ((width <= 720 && height <= 480) || (height <= 720 && width <= 480)) {
+        primaries = ColorAspects::PrimariesBT601_6_525;
+        coeffs = ColorAspects::MatrixBT601_6;
+    } else {
+        primaries = ColorAspects::PrimariesBT709_5;
+        coeffs = ColorAspects::MatrixBT709_5;
+    }
+
+    if (aspects.mRange == ColorAspects::RangeUnspecified) {
+        aspects.mRange = ColorAspects::RangeLimited;
+    }
+
+    if (aspects.mPrimaries == ColorAspects::PrimariesUnspecified) {
+        aspects.mPrimaries = primaries;
+    }
+    if (aspects.mMatrixCoeffs == ColorAspects::MatrixUnspecified) {
+        aspects.mMatrixCoeffs = coeffs;
+    }
+    if (aspects.mTransfer == ColorAspects::TransferUnspecified) {
+        aspects.mTransfer = ColorAspects::TransferSMPTE170M;
+    }
+}
+
+}  // namespace android
+
diff --git a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
index 787f53f..cf7c8fc 100644
--- a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
@@ -50,15 +50,11 @@
 {
     // Devices are considered equal if they:
     // - are of the same type (a device type cannot be AUDIO_DEVICE_NONE)
-    // - have the same address or one device does not specify the address
-    // - have the same channel mask or one device does not specify the channel mask
+    // - have the same address
     if (other == 0) {
         return false;
     }
-    return (mDeviceType == other->mDeviceType) &&
-           (mAddress == "" || other->mAddress == "" || mAddress == other->mAddress) &&
-           (mChannelMask == 0 || other->mChannelMask == 0 ||
-                mChannelMask == other->mChannelMask);
+    return (mDeviceType == other->mDeviceType) && (mAddress == other->mAddress);
 }
 
 void DeviceVector::refreshTypes()
diff --git a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
index dd2a60a..b7c7879 100644
--- a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
@@ -310,12 +310,6 @@
         if (!deviceList.isEmpty()) {
             return deviceList.itemAt(0);
         }
-        deviceList = hwModule->getDeclaredDevices().getDevicesFromType(device);
-        if (!deviceList.isEmpty()) {
-            deviceList.itemAt(0)->setName(String8(device_name));
-            deviceList.itemAt(0)->mAddress = address;
-            return deviceList.itemAt(0);
-        }
     }
 
     sp<DeviceDescriptor> devDesc = new DeviceDescriptor(device);
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/example/Android.mk b/services/audiopolicy/engineconfigurable/parameter-framework/example/Android.mk
index e15e418..5775556 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/example/Android.mk
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/example/Android.mk
@@ -13,7 +13,7 @@
 
 PFW_CORE := external/parameter-framework
 BUILD_PFW_SETTINGS := $(PFW_CORE)/support/android/build_pfw_settings.mk
-PFW_DEFAULT_SCHEMAS_DIR := $(PFW_CORE)/Schemas
+PFW_DEFAULT_SCHEMAS_DIR := $(PFW_CORE)/upstream/schemas
 PFW_SCHEMAS_DIR := $(PFW_DEFAULT_SCHEMAS_DIR)
 
 ##################################################################
@@ -26,7 +26,17 @@
 LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_CLASS := ETC
 LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/parameter-framework
-LOCAL_SRC_FILES := $(LOCAL_MODULE)
+LOCAL_SRC_FILES := $(LOCAL_MODULE).in
+
+AUDIO_PATTERN = @TUNING_ALLOWED@
+ifeq ($(TARGET_BUILD_VARIANT),user)
+AUDIO_VALUE = false
+else
+AUDIO_VALUE = true
+endif
+
+LOCAL_POST_INSTALL_CMD := $(hide) sed -i -e 's|$(AUDIO_PATTERN)|$(AUDIO_VALUE)|g' $(LOCAL_MODULE_PATH)/$(LOCAL_MODULE)
+
 include $(BUILD_PREBUILT)
 
 
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/example/ParameterFrameworkConfigurationPolicy.xml b/services/audiopolicy/engineconfigurable/parameter-framework/example/ParameterFrameworkConfigurationPolicy.xml.in
similarity index 78%
rename from services/audiopolicy/engineconfigurable/parameter-framework/example/ParameterFrameworkConfigurationPolicy.xml
rename to services/audiopolicy/engineconfigurable/parameter-framework/example/ParameterFrameworkConfigurationPolicy.xml.in
index 6905201..f5615cd 100755
--- a/services/audiopolicy/engineconfigurable/parameter-framework/example/ParameterFrameworkConfigurationPolicy.xml
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/example/ParameterFrameworkConfigurationPolicy.xml.in
@@ -1,7 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <ParameterFrameworkConfiguration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-    xsi:noNamespaceSchemaLocation="Schemas/ParameterFrameworkConfiguration.xsd"
-    SystemClassName="Policy" ServerPort="5019" TuningAllowed="true">
+    SystemClassName="Policy" ServerPort="5019" TuningAllowed="@TUNING_ALLOWED@">
 
     <SubsystemPlugins>
         <Location Folder="">
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/PolicyConfigurableDomains.xml b/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/PolicyConfigurableDomains.xml
index 8c3917a..be86b8d 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/PolicyConfigurableDomains.xml
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/PolicyConfigurableDomains.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- #### DO NOT EDIT THIS FILE #### -->
-<ConfigurableDomains xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Schemas/ConfigurableDomains.xsd" SystemClassName="Policy">
+<ConfigurableDomains SystemClassName="Policy">
   <ConfigurableDomain Name="DeviceForStrategy.Media.UnreachableDevices" SequenceAware="false">
     <Configurations>
       <Configuration Name="Calibration">
@@ -5220,16 +5220,16 @@
       </Configuration>
     </Configurations>
     <ConfigurableElements>
-      <ConfigurableElement Path="/Policy/policy/strategies/media/selected_output_devices/mask/hdmi_arc"/>
+      <ConfigurableElement Path="/Policy/policy/strategies/dtmf/selected_output_devices/mask/hdmi_arc"/>
     </ConfigurableElements>
     <Settings>
       <Configuration Name="Selected">
-        <ConfigurableElement Path="/Policy/policy/strategies/media/selected_output_devices/mask/hdmi_arc">
+        <ConfigurableElement Path="/Policy/policy/strategies/dtmf/selected_output_devices/mask/hdmi_arc">
           <BitParameter Name="hdmi_arc">1</BitParameter>
         </ConfigurableElement>
       </Configuration>
       <Configuration Name="NotSelected">
-        <ConfigurableElement Path="/Policy/policy/strategies/media/selected_output_devices/mask/hdmi_arc">
+        <ConfigurableElement Path="/Policy/policy/strategies/dtmf/selected_output_devices/mask/hdmi_arc">
           <BitParameter Name="hdmi_arc">0</BitParameter>
         </ConfigurableElement>
       </Configuration>
@@ -5249,16 +5249,16 @@
       </Configuration>
     </Configurations>
     <ConfigurableElements>
-      <ConfigurableElement Path="/Policy/policy/strategies/media/selected_output_devices/mask/spdif"/>
+      <ConfigurableElement Path="/Policy/policy/strategies/dtmf/selected_output_devices/mask/spdif"/>
     </ConfigurableElements>
     <Settings>
       <Configuration Name="Selected">
-        <ConfigurableElement Path="/Policy/policy/strategies/media/selected_output_devices/mask/spdif">
+        <ConfigurableElement Path="/Policy/policy/strategies/dtmf/selected_output_devices/mask/spdif">
           <BitParameter Name="spdif">1</BitParameter>
         </ConfigurableElement>
       </Configuration>
       <Configuration Name="NotSelected">
-        <ConfigurableElement Path="/Policy/policy/strategies/media/selected_output_devices/mask/spdif">
+        <ConfigurableElement Path="/Policy/policy/strategies/dtmf/selected_output_devices/mask/spdif">
           <BitParameter Name="spdif">0</BitParameter>
         </ConfigurableElement>
       </Configuration>
@@ -5278,16 +5278,16 @@
       </Configuration>
     </Configurations>
     <ConfigurableElements>
-      <ConfigurableElement Path="/Policy/policy/strategies/media/selected_output_devices/mask/aux_line"/>
+      <ConfigurableElement Path="/Policy/policy/strategies/dtmf/selected_output_devices/mask/aux_line"/>
     </ConfigurableElements>
     <Settings>
       <Configuration Name="Selected">
-        <ConfigurableElement Path="/Policy/policy/strategies/media/selected_output_devices/mask/aux_line">
+        <ConfigurableElement Path="/Policy/policy/strategies/dtmf/selected_output_devices/mask/aux_line">
           <BitParameter Name="aux_line">1</BitParameter>
         </ConfigurableElement>
       </Configuration>
       <Configuration Name="NotSelected">
-        <ConfigurableElement Path="/Policy/policy/strategies/media/selected_output_devices/mask/aux_line">
+        <ConfigurableElement Path="/Policy/policy/strategies/dtmf/selected_output_devices/mask/aux_line">
           <BitParameter Name="aux_line">0</BitParameter>
         </ConfigurableElement>
       </Configuration>
@@ -5300,7 +5300,6 @@
       </Configuration>
     </Configurations>
     <ConfigurableElements>
-      <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/remote_submix"/>
       <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/hdmi_arc"/>
       <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"/>
@@ -5308,9 +5307,6 @@
     </ConfigurableElements>
     <Settings>
       <Configuration Name="Calibration">
-        <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/hdmi_arc">
           <BitParameter Name="hdmi_arc">0</BitParameter>
         </ConfigurableElement>
@@ -5474,7 +5470,6 @@
       <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"/>
-      <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/speaker_safe"/>
     </ConfigurableElements>
     <Settings>
       <Configuration Name="RemoteSubmix">
@@ -5532,9 +5527,6 @@
         <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/speaker_safe">
-          <BitParameter Name="speaker_safe">0</BitParameter>
-        </ConfigurableElement>
       </Configuration>
       <Configuration Name="BluetoothA2dp">
         <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/remote_submix">
@@ -5591,9 +5583,6 @@
         <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/speaker_safe">
-          <BitParameter Name="speaker_safe">0</BitParameter>
-        </ConfigurableElement>
       </Configuration>
       <Configuration Name="BluetoothA2dpHeadphones">
         <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/remote_submix">
@@ -5650,9 +5639,6 @@
         <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/speaker_safe">
-          <BitParameter Name="speaker_safe">0</BitParameter>
-        </ConfigurableElement>
       </Configuration>
       <Configuration Name="BluetoothA2dpSpeaker">
         <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/remote_submix">
@@ -5709,9 +5695,6 @@
         <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/speaker_safe">
-          <BitParameter Name="speaker_safe">0</BitParameter>
-        </ConfigurableElement>
       </Configuration>
       <Configuration Name="WiredHeadphone">
         <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/remote_submix">
@@ -5768,9 +5751,6 @@
         <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/speaker_safe">
-          <BitParameter Name="speaker_safe">0</BitParameter>
-        </ConfigurableElement>
       </Configuration>
       <Configuration Name="Line">
         <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/remote_submix">
@@ -5827,9 +5807,6 @@
         <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/speaker_safe">
-          <BitParameter Name="speaker_safe">0</BitParameter>
-        </ConfigurableElement>
       </Configuration>
       <Configuration Name="WiredHeadset">
         <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/remote_submix">
@@ -5886,9 +5863,6 @@
         <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/speaker_safe">
-          <BitParameter Name="speaker_safe">0</BitParameter>
-        </ConfigurableElement>
       </Configuration>
       <Configuration Name="UsbAccessory">
         <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/remote_submix">
@@ -5945,9 +5919,6 @@
         <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/speaker_safe">
-          <BitParameter Name="speaker_safe">0</BitParameter>
-        </ConfigurableElement>
       </Configuration>
       <Configuration Name="UsbDevice">
         <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/remote_submix">
@@ -6004,9 +5975,6 @@
         <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/speaker_safe">
-          <BitParameter Name="speaker_safe">0</BitParameter>
-        </ConfigurableElement>
       </Configuration>
       <Configuration Name="DgtlDockHeadset">
         <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/remote_submix">
@@ -6063,9 +6031,6 @@
         <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/speaker_safe">
-          <BitParameter Name="speaker_safe">0</BitParameter>
-        </ConfigurableElement>
       </Configuration>
       <Configuration Name="Hdmi">
         <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/remote_submix">
@@ -6122,9 +6087,6 @@
         <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/speaker_safe">
-          <BitParameter Name="speaker_safe">0</BitParameter>
-        </ConfigurableElement>
       </Configuration>
       <Configuration Name="AnlgDockHeadset">
         <ConfigurableElement Path="/Policy/policy/strategies/enforced_audible/selected_output_devices/mask/remote_submix">
@@ -6181,9 +6143,6 @@
         <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/speaker_safe">
-          <BitParameter Name="speaker_safe">0</BitParameter>
-        </ConfigurableElement>
       </Configuration>
     </Settings>
   </ConfigurableDomain>
@@ -8225,7 +8184,6 @@
       <ConfigurableElement Path="/Policy/policy/input_sources/fm_tuner/applicable_input_device/mask/dgtl_dock_headset"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/fm_tuner/applicable_input_device/mask/usb_accessory"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/fm_tuner/applicable_input_device/mask/usb_device"/>
-      <ConfigurableElement Path="/Policy/policy/input_sources/fm_tuner/applicable_input_device/mask/fm_tuner"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/fm_tuner/applicable_input_device/mask/tv_tuner"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/fm_tuner/applicable_input_device/mask/line"/>
       <ConfigurableElement Path="/Policy/policy/input_sources/fm_tuner/applicable_input_device/mask/spdif"/>
@@ -8837,9 +8795,6 @@
         <ConfigurableElement Path="/Policy/policy/input_sources/fm_tuner/applicable_input_device/mask/usb_device">
           <BitParameter Name="usb_device">0</BitParameter>
         </ConfigurableElement>
-        <ConfigurableElement Path="/Policy/policy/input_sources/fm_tuner/applicable_input_device/mask/fm_tuner">
-          <BitParameter Name="fm_tuner">0</BitParameter>
-        </ConfigurableElement>
         <ConfigurableElement Path="/Policy/policy/input_sources/fm_tuner/applicable_input_device/mask/tv_tuner">
           <BitParameter Name="tv_tuner">0</BitParameter>
         </ConfigurableElement>
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_input_source.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_input_source.pfw
index 07a3c81..16bcb01 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_input_source.pfw
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_input_source.pfw
@@ -218,7 +218,6 @@
 				dgtl_dock_headset = 0
 				usb_accessory = 0
 				usb_device = 0
-				fm_tuner = 0
 				tv_tuner = 0
 				line = 0
 				spdif = 0
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_dtmf.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_dtmf.pfw
index 85273b2..d8b5b9d 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_dtmf.pfw
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_dtmf.pfw
@@ -599,10 +599,10 @@
 				TelephonyMode IsNot InCommunication
 				AvailableOutputDevices Includes HdmiArc
 
-				/Policy/policy/strategies/media/selected_output_devices/mask/hdmi_arc = 1
+				/Policy/policy/strategies/dtmf/selected_output_devices/mask/hdmi_arc = 1
 
 			conf: NotSelected
-				/Policy/policy/strategies/media/selected_output_devices/mask/hdmi_arc = 0
+				/Policy/policy/strategies/dtmf/selected_output_devices/mask/hdmi_arc = 0
 
 		domain: Spdif
 			#
@@ -615,10 +615,10 @@
 				TelephonyMode IsNot InCommunication
 				AvailableOutputDevices Includes Spdif
 
-				/Policy/policy/strategies/media/selected_output_devices/mask/spdif = 1
+				/Policy/policy/strategies/dtmf/selected_output_devices/mask/spdif = 1
 
 			conf: NotSelected
-				/Policy/policy/strategies/media/selected_output_devices/mask/spdif = 0
+				/Policy/policy/strategies/dtmf/selected_output_devices/mask/spdif = 0
 
 		domain: AuxLine
 			#
@@ -631,7 +631,7 @@
 				TelephonyMode IsNot InCommunication
 				AvailableOutputDevices Includes AuxLine
 
-				/Policy/policy/strategies/media/selected_output_devices/mask/aux_line = 1
+				/Policy/policy/strategies/dtmf/selected_output_devices/mask/aux_line = 1
 
 			conf: NotSelected
-				/Policy/policy/strategies/media/selected_output_devices/mask/aux_line = 0
+				/Policy/policy/strategies/dtmf/selected_output_devices/mask/aux_line = 0
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_enforced_audible.pfw b/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_enforced_audible.pfw
index d714743..593ef64 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_enforced_audible.pfw
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/device_for_strategy_enforced_audible.pfw
@@ -6,7 +6,6 @@
 			conf: Calibration
 				component: /Policy/policy/strategies/enforced_audible/selected_output_devices/mask
 					# no enforced_audible on remote submix (e.g. WFD)
-					remote_submix = 0
 					hdmi_arc = 0
 					spdif = 0
 					aux_line = 0
@@ -78,7 +77,6 @@
 					telephony_tx = 0
 					line = 0
 					fm = 0
-					speaker_safe = 0
 
 			conf: BluetoothA2dp
 				AvailableOutputDevices Includes BluetoothA2dp
@@ -103,7 +101,6 @@
 					telephony_tx = 0
 					line = 0
 					fm = 0
-					speaker_safe = 0
 
 			conf: BluetoothA2dpHeadphones
 				AvailableOutputDevices Includes BluetoothA2dpHeadphones
@@ -128,7 +125,6 @@
 					telephony_tx = 0
 					line = 0
 					fm = 0
-					speaker_safe = 0
 
 			conf: BluetoothA2dpSpeaker
 				AvailableOutputDevices Includes BluetoothA2dpSpeaker
@@ -153,7 +149,6 @@
 					telephony_tx = 0
 					line = 0
 					fm = 0
-					speaker_safe = 0
 
 			conf: WiredHeadphone
 				ForceUseForMedia IsNot ForceSpeaker
@@ -178,7 +173,6 @@
 					telephony_tx = 0
 					line = 0
 					fm = 0
-					speaker_safe = 0
 
 			conf: Line
 				ForceUseForMedia IsNot ForceSpeaker
@@ -203,7 +197,6 @@
 					telephony_tx = 0
 					line = 1
 					fm = 0
-					speaker_safe = 0
 
 			conf: WiredHeadset
 				ForceUseForMedia IsNot ForceSpeaker
@@ -228,7 +221,6 @@
 					telephony_tx = 0
 					line = 0
 					fm = 0
-					speaker_safe = 0
 
 			conf: UsbAccessory
 				ForceUseForMedia IsNot ForceSpeaker
@@ -253,7 +245,6 @@
 					telephony_tx = 0
 					line = 0
 					fm = 0
-					speaker_safe = 0
 
 			conf: UsbDevice
 				ForceUseForMedia IsNot ForceSpeaker
@@ -278,7 +269,6 @@
 					telephony_tx = 0
 					line = 0
 					fm = 0
-					speaker_safe = 0
 
 			conf: DgtlDockHeadset
 				ForceUseForMedia IsNot ForceSpeaker
@@ -303,7 +293,6 @@
 					telephony_tx = 0
 					line = 0
 					fm = 0
-					speaker_safe = 0
 
 			conf: Hdmi
 				ForceUseForMedia IsNot ForceSpeaker
@@ -328,7 +317,6 @@
 					telephony_tx = 0
 					line = 0
 					fm = 0
-					speaker_safe = 0
 
 			conf: AnlgDockHeadset
 				ForceUseForMedia IsNot ForceSpeaker
@@ -354,5 +342,4 @@
 					telephony_tx = 0
 					line = 0
 					fm = 0
-					speaker_safe = 0
 
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/example/Structure/PolicySubsystem.xml b/services/audiopolicy/engineconfigurable/parameter-framework/example/Structure/PolicySubsystem.xml
index e35511c..71b2b62 100755
--- a/services/audiopolicy/engineconfigurable/parameter-framework/example/Structure/PolicySubsystem.xml
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/example/Structure/PolicySubsystem.xml
@@ -2,7 +2,7 @@
 <Subsystem xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns:xi="http://www.w3.org/2001/XInclude"
            xsi:noNamespaceSchemaLocation="Schemas/Subsystem.xsd"
-           Name="policy" Type="Policy" Endianness="Little">
+           Name="policy" Type="Policy">
 
     <ComponentLibrary>
         <!--#################### GLOBAL COMPONENTS BEGIN ####################-->
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Android.mk b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Android.mk
index 8221496..6348648 100755
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Android.mk
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Android.mk
@@ -17,9 +17,10 @@
     -Wall \
     -Werror \
     -Wextra \
+    -fvisibility-inlines-hidden \
+    -fvisibility=hidden
 
 LOCAL_C_INCLUDES := \
-    $(TOPDIR)external/parameter-framework/parameter \
     $(TOPDIR)frameworks/av/services/audiopolicy/common/include \
     $(TOPDIR)frameworks/av/services/audiopolicy/engineconfigurable/include \
     $(TOPDIR)frameworks/av/services/audiopolicy/engineconfigurable/interface \
@@ -27,9 +28,10 @@
 LOCAL_SHARED_LIBRARIES := \
     libaudiopolicyengineconfigurable  \
     libparameter \
-    libxmlserializer \
     liblog \
 
+LOCAL_STATIC_LIBRARIES := libpfw_utility
+
 LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE := libpolicy-subsystem
 
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/InputSource.cpp b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/InputSource.cpp
index ccb10ae..eac4efe 100755
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/InputSource.cpp
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/InputSource.cpp
@@ -21,9 +21,10 @@
 using std::string;
 
 InputSource::InputSource(const string &mappingValue,
-                   CInstanceConfigurableElement *instanceConfigurableElement,
-                   const CMappingContext &context)
+                         CInstanceConfigurableElement *instanceConfigurableElement,
+                         const CMappingContext &context, core::log::Logger &logger)
     : CFormattedSubsystemObject(instanceConfigurableElement,
+                                logger,
                                 mappingValue,
                                 MappingKeyAmend1,
                                 (MappingKeyAmendEnd - MappingKeyAmend1 + 1),
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/InputSource.h b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/InputSource.h
index 0db4f70..58f3c06 100755
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/InputSource.h
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/InputSource.h
@@ -28,8 +28,9 @@
 {
 public:
     InputSource(const std::string &mappingValue,
-             CInstanceConfigurableElement *instanceConfigurableElement,
-             const CMappingContext &context);
+                CInstanceConfigurableElement *instanceConfigurableElement,
+                const CMappingContext &context,
+                core::log::Logger& logger);
 
 protected:
     virtual bool sendToHW(std::string &error);
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/PolicySubsystem.cpp b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/PolicySubsystem.cpp
index 6412134..98d10a9 100755
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/PolicySubsystem.cpp
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/PolicySubsystem.cpp
@@ -40,8 +40,8 @@
 const char *const PolicySubsystem::mInputSourceComponentName = "InputSource";
 const char *const PolicySubsystem::mUsageComponentName = "Usage";
 
-PolicySubsystem::PolicySubsystem(const std::string &name)
-    : CSubsystem(name),
+PolicySubsystem::PolicySubsystem(const std::string &name, core::log::Logger &logger)
+    : CSubsystem(name, logger),
       mPluginInterface(NULL)
 {
     // Try to connect a Plugin Interface from Audio Policy Engine
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/PolicySubsystem.h b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/PolicySubsystem.h
index e3143a5..822eeb9 100755
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/PolicySubsystem.h
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/PolicySubsystem.h
@@ -28,7 +28,7 @@
 class PolicySubsystem : public CSubsystem
 {
 public:
-    PolicySubsystem(const std::string &strName);
+    PolicySubsystem(const std::string &strName, core::log::Logger& logger);
 
     /**
      * Retrieve Route Manager interface.
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/PolicySubsystemBuilder.cpp b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/PolicySubsystemBuilder.cpp
index b14d446..348d5e7 100755
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/PolicySubsystemBuilder.cpp
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/PolicySubsystemBuilder.cpp
@@ -14,16 +14,16 @@
  * limitations under the License.
  */
 
-#include "SubsystemLibrary.h"
-#include "NamedElementBuilderTemplate.h"
+#include <Plugin.h>
+#include "LoggingElementBuilderTemplate.h"
 #include "PolicySubsystem.h"
 
 static const char *const POLICY_SUBSYSTEM_NAME = "Policy";
 extern "C"
 {
-void getPOLICYSubsystemBuilder(CSubsystemLibrary *subsystemLibrary)
+void PARAMETER_FRAMEWORK_PLUGIN_ENTRYPOINT_V1(CSubsystemLibrary *subsystemLibrary, core::log::Logger& logger)
 {
     subsystemLibrary->addElementBuilder(POLICY_SUBSYSTEM_NAME,
-                                        new TNamedElementBuilderTemplate<PolicySubsystem>());
+                                        new TLoggingElementBuilderTemplate<PolicySubsystem>(logger));
 }
 }
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Strategy.cpp b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Strategy.cpp
index 5c536d5..746c3a8 100755
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Strategy.cpp
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Strategy.cpp
@@ -23,8 +23,10 @@
 
 Strategy::Strategy(const string &mappingValue,
                    CInstanceConfigurableElement *instanceConfigurableElement,
-                   const CMappingContext &context)
+                   const CMappingContext &context,
+                   core::log::Logger& logger)
     : CFormattedSubsystemObject(instanceConfigurableElement,
+                                logger,
                                 mappingValue,
                                 MappingKeyAmend1,
                                 (MappingKeyAmendEnd - MappingKeyAmend1 + 1),
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Strategy.h b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Strategy.h
index cbb72e2..c02b82c 100755
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Strategy.h
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Strategy.h
@@ -29,7 +29,8 @@
 public:
     Strategy(const std::string &mappingValue,
              CInstanceConfigurableElement *instanceConfigurableElement,
-             const CMappingContext &context);
+             const CMappingContext &context,
+             core::log::Logger& logger);
 
 protected:
     virtual bool sendToHW(std::string &error);
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Stream.cpp b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Stream.cpp
index 4387634..c642a23 100755
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Stream.cpp
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Stream.cpp
@@ -21,10 +21,10 @@
 using std::string;
 using android::routing_strategy;
 
-Stream::Stream(const string &mappingValue,
-                   CInstanceConfigurableElement *instanceConfigurableElement,
-                   const CMappingContext &context)
-    : CSubsystemObject(instanceConfigurableElement),
+Stream::Stream(const string &/*mappingValue*/,
+               CInstanceConfigurableElement *instanceConfigurableElement,
+               const CMappingContext &context, core::log::Logger &logger)
+    : CSubsystemObject(instanceConfigurableElement, logger),
       mPolicySubsystem(static_cast<const PolicySubsystem *>(
                            instanceConfigurableElement->getBelongingSubsystem())),
       mPolicyPluginInterface(mPolicySubsystem->getPolicyPluginInterface())
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Stream.h b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Stream.h
index 4b0e081..4a875db 100755
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Stream.h
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Stream.h
@@ -35,8 +35,9 @@
 
 public:
     Stream(const std::string &mappingValue,
-             CInstanceConfigurableElement *instanceConfigurableElement,
-             const CMappingContext &context);
+           CInstanceConfigurableElement *instanceConfigurableElement,
+           const CMappingContext &context,
+           core::log::Logger& logger);
 
 protected:
     virtual bool sendToHW(std::string &error);
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Usage.cpp b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Usage.cpp
index eb7d78f..78199f8 100755
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Usage.cpp
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Usage.cpp
@@ -23,8 +23,9 @@
 
 Usage::Usage(const string &mappingValue,
                    CInstanceConfigurableElement *instanceConfigurableElement,
-                   const CMappingContext &context)
+                   const CMappingContext &context, core::log::Logger &logger)
     : CFormattedSubsystemObject(instanceConfigurableElement,
+                                logger,
                                 mappingValue,
                                 MappingKeyAmend1,
                                 (MappingKeyAmendEnd - MappingKeyAmend1 + 1),
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Usage.h b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Usage.h
index 3b82f8c..860204f 100755
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Usage.h
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Usage.h
@@ -28,8 +28,9 @@
 {
 public:
     Usage(const std::string &mappingValue,
-             CInstanceConfigurableElement *instanceConfigurableElement,
-             const CMappingContext &context);
+          CInstanceConfigurableElement *instanceConfigurableElement,
+          const CMappingContext &context,
+          core::log::Logger& logger);
 
 protected:
     virtual bool sendToHW(std::string &error);
diff --git a/services/audiopolicy/engineconfigurable/src/Engine.cpp b/services/audiopolicy/engineconfigurable/src/Engine.cpp
index ed807c6..7f8ed1f 100755
--- a/services/audiopolicy/engineconfigurable/src/Engine.cpp
+++ b/services/audiopolicy/engineconfigurable/src/Engine.cpp
@@ -142,6 +142,8 @@
 {
     const SwAudioOutputCollection &outputs = mPolicyEngine->mApmObserver->getOutputs();
 
+    //FIXME: getStrategyForUsage() should return STRATEGY_ACCESSIBILITY and getDeviceForStrategy()
+    // should be implemented accordingly for STRATEGY_ACCESSIBILITY
     if (usage == AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY &&
             (outputs.isStreamActive(AUDIO_STREAM_RING) ||
              outputs.isStreamActive(AUDIO_STREAM_ALARM))) {
diff --git a/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapper.cpp b/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapper.cpp
index cc4d4db..6872e52 100755
--- a/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapper.cpp
+++ b/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapper.cpp
@@ -46,15 +46,13 @@
 public:
     ParameterMgrPlatformConnectorLogger() {}
 
-    virtual void log(bool isWarning, const string &log)
+    virtual void info(const string &log)
     {
-        const static string format("policy-parameter-manager: ");
-
-        if (isWarning) {
-            ALOGW("%s %s", format.c_str(), log.c_str());
-        } else {
-            ALOGD("%s %s", format.c_str(), log.c_str());
-        }
+        ALOGD("policy-parameter-manager: %s", log.c_str());
+    }
+    virtual void warning(const string &log)
+    {
+        ALOGW("policy-parameter-manager: %s", log.c_str());
     }
 };
 
@@ -134,7 +132,8 @@
     ALOGV("%s: Adding new value pair (%d,%s) for criterionType %s", __FUNCTION__,
           numericValue, literalValue.c_str(), typeName.c_str());
     ISelectionCriterionTypeInterface *criterionType = mPolicyCriterionTypes[typeName];
-    criterionType->addValuePair(numericValue, literalValue.c_str());
+    std::string error;
+    criterionType->addValuePair(numericValue, literalValue, error);
 }
 
 void ParameterManagerWrapper::loadCriterionType(cnode *root, bool isInclusive)
diff --git a/services/audiopolicy/enginedefault/src/Engine.cpp b/services/audiopolicy/enginedefault/src/Engine.cpp
index 43664e6..f8ba3f2 100755
--- a/services/audiopolicy/enginedefault/src/Engine.cpp
+++ b/services/audiopolicy/enginedefault/src/Engine.cpp
@@ -195,18 +195,9 @@
 
 routing_strategy Engine::getStrategyForUsage(audio_usage_t usage)
 {
-    const SwAudioOutputCollection &outputs = mApmObserver->getOutputs();
-
     // usage to strategy mapping
     switch (usage) {
     case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY:
-        if (outputs.isStreamActive(AUDIO_STREAM_RING) ||
-                outputs.isStreamActive(AUDIO_STREAM_ALARM)) {
-            return STRATEGY_SONIFICATION;
-        }
-        if (isInCall()) {
-            return STRATEGY_PHONE;
-        }
         return STRATEGY_ACCESSIBILITY;
 
     case AUDIO_USAGE_MEDIA:
@@ -245,6 +236,17 @@
 
     const SwAudioOutputCollection &outputs = mApmObserver->getOutputs();
 
+    return getDeviceForStrategyInt(strategy, (DeviceVector&)availableOutputDevices,
+                                   availableInputDevices, outputs);
+}
+
+
+
+audio_devices_t Engine::getDeviceForStrategyInt(routing_strategy strategy,
+                                                DeviceVector &availableOutputDevices,
+                                                const DeviceVector &availableInputDevices,
+                                                const SwAudioOutputCollection &outputs) const
+{
     uint32_t device = AUDIO_DEVICE_NONE;
     uint32_t availableOutputDevicesType = availableOutputDevices.types();
 
@@ -260,14 +262,16 @@
 
     case STRATEGY_SONIFICATION_RESPECTFUL:
         if (isInCall()) {
-            device = getDeviceForStrategy(STRATEGY_SONIFICATION);
+            device = getDeviceForStrategyInt(
+                    STRATEGY_SONIFICATION, availableOutputDevices, availableInputDevices, outputs);
         } else if (outputs.isStreamActiveRemotely(AUDIO_STREAM_MUSIC,
                 SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) {
             // while media is playing on a remote device, use the the sonification behavior.
             // Note that we test this usecase before testing if media is playing because
             //   the isStreamActive() method only informs about the activity of a stream, not
             //   if it's for local playback. Note also that we use the same delay between both tests
-            device = getDeviceForStrategy(STRATEGY_SONIFICATION);
+            device = getDeviceForStrategyInt(
+                    STRATEGY_SONIFICATION, availableOutputDevices, availableInputDevices, outputs);
             //user "safe" speaker if available instead of normal speaker to avoid triggering
             //other acoustic safety mechanisms for notification
             if ((device & AUDIO_DEVICE_OUT_SPEAKER) &&
@@ -275,12 +279,15 @@
                 device |= AUDIO_DEVICE_OUT_SPEAKER_SAFE;
                 device &= ~AUDIO_DEVICE_OUT_SPEAKER;
             }
-        } else if (outputs.isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) {
+        } else if (outputs.isStreamActive(
+                                AUDIO_STREAM_MUSIC, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) {
             // while media is playing (or has recently played), use the same device
-            device = getDeviceForStrategy(STRATEGY_MEDIA);
+            device = getDeviceForStrategyInt(
+                    STRATEGY_MEDIA, availableOutputDevices, availableInputDevices, outputs);
         } else {
             // when media is not playing anymore, fall back on the sonification behavior
-            device = getDeviceForStrategy(STRATEGY_SONIFICATION);
+            device = getDeviceForStrategyInt(
+                    STRATEGY_SONIFICATION, availableOutputDevices, availableInputDevices, outputs);
             //user "safe" speaker if available instead of normal speaker to avoid triggering
             //other acoustic safety mechanisms for notification
             if ((device & AUDIO_DEVICE_OUT_SPEAKER) &&
@@ -294,7 +301,8 @@
     case STRATEGY_DTMF:
         if (!isInCall()) {
             // when off call, DTMF strategy follows the same rules as MEDIA strategy
-            device = getDeviceForStrategy(STRATEGY_MEDIA);
+            device = getDeviceForStrategyInt(
+                    STRATEGY_MEDIA, availableOutputDevices, availableInputDevices, outputs);
             break;
         }
         // when in call, DTMF and PHONE strategies follow the same rules
@@ -321,8 +329,8 @@
                 availableOutputDevicesType = availPrimaryOutputDevices;
             }
         }
-        // for phone strategy, we first consider the forced use and then the available devices by order
-        // of priority
+        // for phone strategy, we first consider the forced use and then the available devices by
+        // order of priority
         switch (mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]) {
         case AUDIO_POLICY_FORCE_BT_SCO:
             if (!isInCall() || strategy != STRATEGY_DTMF) {
@@ -350,6 +358,8 @@
             if (device) break;
             device = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADSET;
             if (device) break;
+            device = availableOutputDevicesType & AUDIO_DEVICE_OUT_LINE;
+            if (device) break;
             device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_DEVICE;
             if (device) break;
             if (!isInCall()) {
@@ -391,8 +401,6 @@
                 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
                 if (device) break;
             }
-            device = availableOutputDevicesType & AUDIO_DEVICE_OUT_LINE;
-            if (device) break;
             device = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
             if (device) break;
             device = mApmObserver->getDefaultOutputDevice()->type();
@@ -408,7 +416,8 @@
         // If incall, just select the STRATEGY_PHONE device: The rest of the behavior is handled by
         // handleIncallSonification().
         if (isInCall()) {
-            device = getDeviceForStrategy(STRATEGY_PHONE);
+            device = getDeviceForStrategyInt(
+                    STRATEGY_PHONE, availableOutputDevices, availableInputDevices, outputs);
             break;
         }
         // FALL THROUGH
@@ -429,7 +438,6 @@
         // The second device used for sonification is the same as the device used by media strategy
         // FALL THROUGH
 
-    // FIXME: STRATEGY_ACCESSIBILITY and STRATEGY_REROUTING follow STRATEGY_MEDIA for now
     case STRATEGY_ACCESSIBILITY:
         if (strategy == STRATEGY_ACCESSIBILITY) {
             // do not route accessibility prompts to a digital output currently configured with a
@@ -443,20 +451,35 @@
                     availableOutputDevicesType = availableOutputDevices.types() & ~devices;
                 }
             }
+            availableOutputDevices =
+                    availableOutputDevices.getDevicesFromType(availableOutputDevicesType);
+            if (outputs.isStreamActive(AUDIO_STREAM_RING) ||
+                    outputs.isStreamActive(AUDIO_STREAM_ALARM)) {
+                return getDeviceForStrategyInt(
+                    STRATEGY_SONIFICATION, availableOutputDevices, availableInputDevices, outputs);
+            }
+            if (isInCall()) {
+                return getDeviceForStrategyInt(
+                        STRATEGY_PHONE, availableOutputDevices, availableInputDevices, outputs);
+            }
         }
+        // For other cases, STRATEGY_ACCESSIBILITY behaves like STRATEGY_MEDIA
         // FALL THROUGH
 
+    // FIXME: STRATEGY_REROUTING follow STRATEGY_MEDIA for now
     case STRATEGY_REROUTING:
     case STRATEGY_MEDIA: {
         uint32_t device2 = AUDIO_DEVICE_NONE;
         if (strategy != STRATEGY_SONIFICATION) {
             // no sonification on remote submix (e.g. WFD)
-            if (availableOutputDevices.getDevice(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, String8("0")) != 0) {
+            if (availableOutputDevices.getDevice(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
+                                                 String8("0")) != 0) {
                 device2 = availableOutputDevices.types() & AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
             }
         }
         if (isInCall() && (strategy == STRATEGY_MEDIA)) {
-            device = getDeviceForStrategy(STRATEGY_PHONE);
+            device = getDeviceForStrategyInt(
+                    STRATEGY_PHONE, availableOutputDevices, availableInputDevices, outputs);
             break;
         }
         if ((device2 == AUDIO_DEVICE_NONE) &&
diff --git a/services/audiopolicy/enginedefault/src/Engine.h b/services/audiopolicy/enginedefault/src/Engine.h
index 8b6eaf6..ed93d1c 100755
--- a/services/audiopolicy/enginedefault/src/Engine.h
+++ b/services/audiopolicy/enginedefault/src/Engine.h
@@ -125,6 +125,10 @@
     routing_strategy getStrategyForStream(audio_stream_type_t stream);
     routing_strategy getStrategyForUsage(audio_usage_t usage);
     audio_devices_t getDeviceForStrategy(routing_strategy strategy) const;
+    audio_devices_t getDeviceForStrategyInt(routing_strategy strategy,
+                                            DeviceVector &availableOutputDevices,
+                                            const DeviceVector &availableInputDevices,
+                                            const SwAudioOutputCollection &outputs) const;
     audio_devices_t getDeviceForInputSource(audio_source_t inputSource) const;
     audio_mode_t mPhoneState;  /**< current phone state. */
 
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index a7b90f4..21107a1 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -1794,8 +1794,15 @@
 {
     ALOGV("initStreamVolume() stream %d, min %d, max %d", stream , indexMin, indexMax);
     mVolumeCurves->initStreamVolume(stream, indexMin, indexMax);
-    if (stream == AUDIO_STREAM_MUSIC) {
-        mVolumeCurves->initStreamVolume(AUDIO_STREAM_ACCESSIBILITY, indexMin, indexMax);
+
+    // initialize other private stream volumes which follow this one
+    routing_strategy strategy = getStrategy(stream);
+    for (int curStream = 0; curStream < AUDIO_STREAM_CNT; curStream++) {
+        routing_strategy curStrategy = getStrategy((audio_stream_type_t)curStream);
+        if (!strategiesMatchForvolume(strategy, curStrategy)) {
+            continue;
+        }
+        mVolumeCurves->initStreamVolume((audio_stream_type_t)curStream, indexMin, indexMax);
     }
 }
 
@@ -1823,38 +1830,43 @@
     if (device == AUDIO_DEVICE_OUT_DEFAULT) {
         mVolumeCurves->clearCurrentVolumeIndex(stream);
     }
-    mVolumeCurves->addCurrentVolumeIndex(stream, device, index);
+
+    // update other private stream volumes which follow this one
+    routing_strategy strategy = getStrategy(stream);
+    for (int curStream = 0; curStream < AUDIO_STREAM_CNT; curStream++) {
+        routing_strategy curStrategy = getStrategy((audio_stream_type_t)curStream);
+        if (!strategiesMatchForvolume(strategy, curStrategy)) {
+            continue;
+        }
+        mVolumeCurves->addCurrentVolumeIndex((audio_stream_type_t)curStream, device, index);
+    }
 
     // update volume on all outputs whose current device is also selected by the same
     // strategy as the device specified by the caller
-    audio_devices_t selectedDevices = getDeviceForStrategy(getStrategy(stream), true /*fromCache*/);
-    // it is possible that the requested device is not selected by the strategy (e.g an explicit
-    // audio patch is active causing getDevicesForStream() to return this device. We must make
-    // sure that the device passed is part of the devices considered when applying volume below.
-    selectedDevices |= device;
-
-    //FIXME: AUDIO_STREAM_ACCESSIBILITY volume follows AUDIO_STREAM_MUSIC for now
-    audio_devices_t accessibilityDevice = AUDIO_DEVICE_NONE;
-    if (stream == AUDIO_STREAM_MUSIC) {
-        mVolumeCurves->addCurrentVolumeIndex(AUDIO_STREAM_ACCESSIBILITY, device, index);
-        accessibilityDevice = getDeviceForStrategy(STRATEGY_ACCESSIBILITY, true /*fromCache*/);
-    }
-
     status_t status = NO_ERROR;
     for (size_t i = 0; i < mOutputs.size(); i++) {
         sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
         audio_devices_t curDevice = Volume::getDeviceForVolume(desc->device());
-        if ((device == AUDIO_DEVICE_OUT_DEFAULT) || ((curDevice & selectedDevices) != 0)) {
-            status_t volStatus = checkAndSetVolume(stream, index, desc, curDevice);
-            if (volStatus != NO_ERROR) {
-                status = volStatus;
+        for (int curStream = 0; curStream < AUDIO_STREAM_CNT; curStream++) {
+            routing_strategy curStrategy = getStrategy((audio_stream_type_t)curStream);
+            if (!strategiesMatchForvolume(strategy, curStrategy)) {
+                continue;
             }
-        }
-        if ((accessibilityDevice != AUDIO_DEVICE_NONE) &&
-                ((device == AUDIO_DEVICE_OUT_DEFAULT) || ((curDevice & accessibilityDevice) != 0)))
-        {
-            status_t volStatus = checkAndSetVolume(AUDIO_STREAM_ACCESSIBILITY,
-                                                   index, desc, curDevice);
+            audio_devices_t curStreamDevice = getDeviceForStrategy(curStrategy, true /*fromCache*/);
+            // it is possible that the requested device is not selected by the strategy
+            // (e.g an explicit audio patch is active causing getDevicesForStream()
+            // to return this device. We must make sure that the device passed is part of the
+            // devices considered when applying volume below.
+            curStreamDevice |= device;
+
+            if (((device == AUDIO_DEVICE_OUT_DEFAULT) ||
+                    ((curDevice & curStreamDevice) != 0))) {
+                status_t volStatus =
+                        checkAndSetVolume((audio_stream_type_t)curStream, index, desc, curDevice);
+                if (volStatus != NO_ERROR) {
+                    status = volStatus;
+                }
+            }
         }
     }
     return status;
@@ -1957,7 +1969,17 @@
 
 bool AudioPolicyManager::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const
 {
-    return mOutputs.isStreamActive(stream, inPastMs);
+    bool active = false;
+    routing_strategy strategy = getStrategy(stream);
+    for (int curStream = 0; curStream < AUDIO_STREAM_CNT && !active; curStream++) {
+        routing_strategy curStrategy = getStrategy((audio_stream_type_t)curStream);
+        if (!strategiesMatchForvolume(strategy, curStrategy)) {
+            continue;
+        }
+        active = mOutputs.isStreamActive((audio_stream_type_t)curStream, inPastMs);
+    }
+
+    return active;
 }
 
 bool AudioPolicyManager::isStreamActiveRemotely(audio_stream_type_t stream, uint32_t inPastMs) const
@@ -2838,7 +2860,7 @@
     disconnectAudioSource(sourceDesc);
 
     routing_strategy strategy = (routing_strategy) getStrategyForAttr(&sourceDesc->mAttributes);
-    audio_stream_type_t stream = audio_attributes_to_stream_type(&sourceDesc->mAttributes);
+    audio_stream_type_t stream = streamTypefromAttributesInt(&sourceDesc->mAttributes);
     sp<DeviceDescriptor> srcDeviceDesc = sourceDesc->mDevice;
 
     audio_devices_t sinkDevice = getDeviceForStrategy(strategy, true);
@@ -2971,7 +2993,7 @@
     }
     removeAudioPatch(sourceDesc->mPatchDesc->mHandle);
 
-    audio_stream_type_t stream = audio_attributes_to_stream_type(&sourceDesc->mAttributes);
+    audio_stream_type_t stream = streamTypefromAttributesInt(&sourceDesc->mAttributes);
     sp<SwAudioOutputDescriptor> swOutputDesc = sourceDesc->mSwOutput.promote();
     if (swOutputDesc != 0) {
         stopSource(swOutputDesc, stream, false);
@@ -4170,10 +4192,10 @@
     //      use device for strategy phone
     // 3: the strategy for enforced audible is active but not enforced on the output:
     //      use the device for strategy enforced audible
-    // 4: the strategy accessibility is active on the output:
-    //      use device for strategy accessibility
-    // 5: the strategy sonification is active on the output:
+    // 4: the strategy sonification is active on the output:
     //      use device for strategy sonification
+    // 5: the strategy accessibility is active on the output:
+    //      use device for strategy accessibility
     // 6: the strategy "respectful" sonification is active on the output:
     //      use device for strategy "respectful" sonification
     // 7: the strategy media is active on the output:
@@ -4190,10 +4212,10 @@
         device = getDeviceForStrategy(STRATEGY_PHONE, fromCache);
     } else if (isStrategyActive(outputDesc, STRATEGY_ENFORCED_AUDIBLE)) {
         device = getDeviceForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache);
-    } else if (isStrategyActive(outputDesc, STRATEGY_ACCESSIBILITY)) {
-        device = getDeviceForStrategy(STRATEGY_ACCESSIBILITY, fromCache);
     } else if (isStrategyActive(outputDesc, STRATEGY_SONIFICATION)) {
         device = getDeviceForStrategy(STRATEGY_SONIFICATION, fromCache);
+    } else if (isStrategyActive(outputDesc, STRATEGY_ACCESSIBILITY)) {
+        device = getDeviceForStrategy(STRATEGY_ACCESSIBILITY, fromCache);
     } else if (isStrategyActive(outputDesc, STRATEGY_SONIFICATION_RESPECTFUL)) {
         device = getDeviceForStrategy(STRATEGY_SONIFICATION_RESPECTFUL, fromCache);
     } else if (isStrategyActive(outputDesc, STRATEGY_MEDIA)) {
@@ -4229,6 +4251,13 @@
     return device;
 }
 
+bool AudioPolicyManager::strategiesMatchForvolume(routing_strategy strategy1,
+                                                  routing_strategy strategy2) {
+    return ((strategy1 == strategy2) ||
+            ((strategy1 == STRATEGY_ACCESSIBILITY) && (strategy2 == STRATEGY_MEDIA)) ||
+            ((strategy1 == STRATEGY_MEDIA) && (strategy2 == STRATEGY_ACCESSIBILITY)));
+}
+
 uint32_t AudioPolicyManager::getStrategyForStream(audio_stream_type_t stream) {
     return (uint32_t)getStrategy(stream);
 }
@@ -4240,16 +4269,22 @@
     if (stream < (audio_stream_type_t) 0 || stream >= AUDIO_STREAM_PUBLIC_CNT) {
         return AUDIO_DEVICE_NONE;
     }
-    audio_devices_t devices;
+    audio_devices_t devices = AUDIO_DEVICE_NONE;
     routing_strategy strategy = getStrategy(stream);
-    devices = getDeviceForStrategy(strategy, true /*fromCache*/);
-    SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(devices, mOutputs);
-    for (size_t i = 0; i < outputs.size(); i++) {
-        sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(outputs[i]);
-        if (isStrategyActive(outputDesc, strategy)) {
-            devices = outputDesc->device();
-            break;
+    for (int curStrategy = 0; curStrategy < NUM_STRATEGIES; curStrategy++) {
+        if (!strategiesMatchForvolume(strategy, (routing_strategy)curStrategy)) {
+            continue;
         }
+        audio_devices_t curDevices =
+                getDeviceForStrategy((routing_strategy)curStrategy, true /*fromCache*/);
+        SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(curDevices, mOutputs);
+        for (size_t i = 0; i < outputs.size(); i++) {
+            sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(outputs[i]);
+            if (isStrategyActive(outputDesc, (routing_strategy)curStrategy)) {
+                curDevices |= outputDesc->device();
+            }
+        }
+        devices |= curDevices;
     }
 
     /*Filter SPEAKER_SAFE out of results, as AudioService doesn't know about it
@@ -4361,15 +4396,8 @@
     // the device = the device from the descriptor in the RouteMap, and exit.
     for (size_t routeIndex = 0; routeIndex < mOutputRoutes.size(); routeIndex++) {
         sp<SessionRoute> route = mOutputRoutes.valueAt(routeIndex);
-        routing_strategy strat = getStrategy(route->mStreamType);
-        // Special case for accessibility strategy which must follow any strategy it is
-        // currently remapped to
-        bool strategyMatch = (strat == strategy) ||
-                             ((strategy == STRATEGY_ACCESSIBILITY) &&
-                              ((mEngine->getStrategyForUsage(
-                                      AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY) == strat) ||
-                               (strat == STRATEGY_MEDIA)));
-        if (strategyMatch && route->isActive()) {
+        routing_strategy routeStrategy = getStrategy(route->mStreamType);
+        if ((routeStrategy == strategy) && route->isActive()) {
             return route->mDeviceDescriptor->type();
         }
     }
@@ -5007,15 +5035,6 @@
     case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
         return AUDIO_STREAM_MUSIC;
     case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY:
-        if (isStreamActive(AUDIO_STREAM_ALARM)) {
-            return AUDIO_STREAM_ALARM;
-        }
-        if (isStreamActive(AUDIO_STREAM_RING)) {
-            return AUDIO_STREAM_RING;
-        }
-        if (isInCall()) {
-            return AUDIO_STREAM_VOICE_CALL;
-        }
         return AUDIO_STREAM_ACCESSIBILITY;
     case AUDIO_USAGE_ASSISTANCE_SONIFICATION:
         return AUDIO_STREAM_SYSTEM;
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 38700fc..d6e48ab 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -506,6 +506,9 @@
         void clearAudioSources(uid_t uid);
 
 
+        static bool strategiesMatchForvolume(routing_strategy strategy1,
+                                             routing_strategy strategy2);
+
         uid_t mUidCached;
         AudioPolicyClientInterface *mpClientInterface;  // audio policy client interface
         sp<SwAudioOutputDescriptor> mPrimaryOutput;     // primary output descriptor
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index 307b412..316cfda 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -310,6 +310,15 @@
     ALOGV("%s: ending configure (%d input stream, %zu output streams)",
             __FUNCTION__, mInputStream.configured ? 1 : 0, mStreamMap.size());
 
+    binder::Status res;
+    if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
+
+    Mutex::Autolock icl(mBinderSerializationLock);
+
+    if (!mDevice.get()) {
+        return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
+    }
+
     // Sanitize the high speed session against necessary capability bit.
     if (isConstrainedHighSpeed) {
         CameraMetadata staticInfo = mDevice->info();
@@ -332,15 +341,6 @@
         }
     }
 
-    binder::Status res;
-    if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
-
-    Mutex::Autolock icl(mBinderSerializationLock);
-
-    if (!mDevice.get()) {
-        return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
-    }
-
     status_t err = mDevice->configureStreams(isConstrainedHighSpeed);
     if (err != OK) {
         res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
@@ -710,6 +710,11 @@
         request != NULL) {
 
         request->swap(metadata);
+    } else if (err == BAD_VALUE) {
+        res = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
+                "Camera %d: Template ID %d is invalid or not supported: %s (%d)",
+                mCameraId, templateId, strerror(-err), err);
+
     } else {
         res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
                 "Camera %d: Error creating default request for template %d: %s (%d)",
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index ee84ff0..9f8eac6 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -534,9 +534,11 @@
         mOutputStreams[i]->dump(fd,args);
     }
 
-    lines = String8("    Camera3 Buffer Manager:\n");
-    write(fd, lines.string(), lines.size());
-    mBufferManager->dump(fd, args);
+    if (mBufferManager != NULL) {
+        lines = String8("    Camera3 Buffer Manager:\n");
+        write(fd, lines.string(), lines.size());
+        mBufferManager->dump(fd, args);
+    }
 
     lines = String8("    In-flight requests:\n");
     if (mInFlightMap.size() == 0) {
@@ -1237,6 +1239,13 @@
         CameraMetadata *request) {
     ATRACE_CALL();
     ALOGV("%s: for template %d", __FUNCTION__, templateId);
+
+    if (templateId <= 0 || templateId >= CAMERA3_TEMPLATE_COUNT) {
+        android_errorWriteWithInfoLog(CameraService::SN_EVENT_LOG_ID, "26866110",
+                IPCThreadState::self()->getCallingUid(), nullptr, 0);
+        return BAD_VALUE;
+    }
+
     Mutex::Autolock il(mInterfaceLock);
     Mutex::Autolock l(mLock);
 
diff --git a/services/mediacodec/minijail/seccomp_policy/mediacodec-seccomp-arm.policy b/services/mediacodec/minijail/seccomp_policy/mediacodec-seccomp-arm.policy
index 3419195..4be96d5 100644
--- a/services/mediacodec/minijail/seccomp_policy/mediacodec-seccomp-arm.policy
+++ b/services/mediacodec/minijail/seccomp_policy/mediacodec-seccomp-arm.policy
@@ -38,6 +38,8 @@
 sched_get_priority_max: 1
 sched_get_priority_min: 1
 statfs64: 1
+sched_setscheduler: 1
+fstatat64: 1
 
 # for attaching to debuggerd on process crash
 sigaction: 1