Merge "rm libbinderthreadstate"
diff --git a/camera/cameraserver/Android.bp b/camera/cameraserver/Android.bp
index 22e9578..dc7f88a 100644
--- a/camera/cameraserver/Android.bp
+++ b/camera/cameraserver/Android.bp
@@ -48,6 +48,6 @@
     init_rc: ["cameraserver.rc"],
 
     vintf_fragments: [
-        "manifest_android.frameworks.cameraservice.service@2.0.xml",
+        "manifest_android.frameworks.cameraservice.service@2.1.xml",
     ],
 }
diff --git a/camera/cameraserver/manifest_android.frameworks.cameraservice.service@2.0.xml b/camera/cameraserver/manifest_android.frameworks.cameraservice.service@2.1.xml
similarity index 90%
rename from camera/cameraserver/manifest_android.frameworks.cameraservice.service@2.0.xml
rename to camera/cameraserver/manifest_android.frameworks.cameraservice.service@2.1.xml
index 601c717..5a15b35 100644
--- a/camera/cameraserver/manifest_android.frameworks.cameraservice.service@2.0.xml
+++ b/camera/cameraserver/manifest_android.frameworks.cameraservice.service@2.1.xml
@@ -2,7 +2,7 @@
     <hal>
         <name>android.frameworks.cameraservice.service</name>
         <transport>hwbinder</transport>
-        <version>2.0</version>
+        <version>2.1</version>
         <interface>
             <name>ICameraService</name>
             <instance>default</instance>
diff --git a/camera/ndk/Android.bp b/camera/ndk/Android.bp
index 56f209c..7ba82c1 100644
--- a/camera/ndk/Android.bp
+++ b/camera/ndk/Android.bp
@@ -123,6 +123,7 @@
         "android.frameworks.cameraservice.device@2.0",
         "android.frameworks.cameraservice.common@2.0",
         "android.frameworks.cameraservice.service@2.0",
+        "android.frameworks.cameraservice.service@2.1",
     ],
     static_libs: [
         "android.hardware.camera.common@1.0-helper",
@@ -140,9 +141,12 @@
 }
 
 cc_test {
-    name: "AImageReaderVendorTest",
+    name: "ACameraNdkVendorTest",
     vendor: true,
-    srcs: ["ndk_vendor/tests/AImageReaderVendorTest.cpp"],
+    srcs: [
+        "ndk_vendor/tests/AImageReaderVendorTest.cpp",
+        "ndk_vendor/tests/ACameraManagerTest.cpp",
+    ],
     shared_libs: [
         "libcamera2ndk_vendor",
         "libcamera_metadata",
diff --git a/camera/ndk/impl/ACameraManager.cpp b/camera/ndk/impl/ACameraManager.cpp
index 4870265..f408b6a 100644
--- a/camera/ndk/impl/ACameraManager.cpp
+++ b/camera/ndk/impl/ACameraManager.cpp
@@ -130,6 +130,11 @@
         mCameraService->addListener(mCameraServiceListener, &cameraStatuses);
         for (auto& c : cameraStatuses) {
             onStatusChangedLocked(c.status, c.cameraId);
+
+            for (auto& unavailablePhysicalId : c.unavailablePhysicalIds) {
+                onStatusChangedLocked(hardware::ICameraServiceListener::STATUS_NOT_PRESENT,
+                        c.cameraId, unavailablePhysicalId);
+            }
         }
 
         // setup vendor tags
@@ -200,9 +205,7 @@
 
 void CameraManagerGlobal::registerExtendedAvailabilityCallback(
         const ACameraManager_ExtendedAvailabilityCallbacks *callback) {
-    Mutex::Autolock _l(mLock);
-    Callback cb(callback);
-    mCallbacks.insert(cb);
+    return registerAvailCallback<ACameraManager_ExtendedAvailabilityCallbacks>(callback);
 }
 
 void CameraManagerGlobal::unregisterExtendedAvailabilityCallback(
@@ -214,6 +217,18 @@
 
 void CameraManagerGlobal::registerAvailabilityCallback(
         const ACameraManager_AvailabilityCallbacks *callback) {
+    return registerAvailCallback<ACameraManager_AvailabilityCallbacks>(callback);
+}
+
+void CameraManagerGlobal::unregisterAvailabilityCallback(
+        const ACameraManager_AvailabilityCallbacks *callback) {
+    Mutex::Autolock _l(mLock);
+    Callback cb(callback);
+    mCallbacks.erase(cb);
+}
+
+template<class T>
+void CameraManagerGlobal::registerAvailCallback(const T *callback) {
     Mutex::Autolock _l(mLock);
     Callback cb(callback);
     auto pair = mCallbacks.insert(cb);
@@ -227,24 +242,33 @@
             if (!pair.second.supportsHAL3) {
                 continue;
             }
+
+            // Camera available/unavailable callback
             sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler);
-            ACameraManager_AvailabilityCallback cb = isStatusAvailable(status) ?
-                    callback->onCameraAvailable : callback->onCameraUnavailable;
-            msg->setPointer(kCallbackFpKey, (void *) cb);
-            msg->setPointer(kContextKey, callback->context);
+            ACameraManager_AvailabilityCallback cbFunc = isStatusAvailable(status) ?
+                    cb.mAvailable : cb.mUnavailable;
+            msg->setPointer(kCallbackFpKey, (void *) cbFunc);
+            msg->setPointer(kContextKey, cb.mContext);
             msg->setString(kCameraIdKey, AString(cameraId));
             msg->post();
+
+            // Physical camera unavailable callback
+            std::set<String8> unavailablePhysicalCameras =
+                    pair.second.getUnavailablePhysicalIds();
+            for (const auto& physicalCameraId : unavailablePhysicalCameras) {
+                sp<AMessage> msg = new AMessage(kWhatSendSinglePhysicalCameraCallback, mHandler);
+                ACameraManager_PhysicalCameraAvailabilityCallback cbFunc =
+                        cb.mPhysicalCamUnavailable;
+                msg->setPointer(kCallbackFpKey, (void *) cbFunc);
+                msg->setPointer(kContextKey, cb.mContext);
+                msg->setString(kCameraIdKey, AString(cameraId));
+                msg->setString(kPhysicalCameraIdKey, AString(physicalCameraId));
+                msg->post();
+            }
         }
     }
 }
 
-void CameraManagerGlobal::unregisterAvailabilityCallback(
-        const ACameraManager_AvailabilityCallbacks *callback) {
-    Mutex::Autolock _l(mLock);
-    Callback cb(callback);
-    mCallbacks.erase(cb);
-}
-
 bool CameraManagerGlobal::supportsCamera2ApiLocked(const String8 &cameraId) {
     bool camera2Support = false;
     auto cs = getCameraServiceLocked();
@@ -550,6 +574,11 @@
     return count > 0;
 }
 
+std::set<String8> CameraManagerGlobal::StatusAndHAL3Support::getUnavailablePhysicalIds() {
+    std::lock_guard<std::mutex> lock(mLock);
+    return unavailablePhysicalIds;
+}
+
 } // namespace acam
 } // namespace android
 
diff --git a/camera/ndk/impl/ACameraManager.h b/camera/ndk/impl/ACameraManager.h
index 98cd934..836e037 100644
--- a/camera/ndk/impl/ACameraManager.h
+++ b/camera/ndk/impl/ACameraManager.h
@@ -70,6 +70,9 @@
     const char*                  kCameraServiceName      = "media.camera";
     Mutex                        mLock;
 
+    template<class T>
+    void registerAvailCallback(const T *callback);
+
     class DeathNotifier : public IBinder::DeathRecipient {
       public:
         explicit DeathNotifier(CameraManagerGlobal* cm) : mCameraManager(cm) {}
@@ -222,6 +225,7 @@
         bool removeUnavailablePhysicalId(const String8& physicalCameraId);
         int32_t getStatus();
         void updateStatus(int32_t newStatus);
+        std::set<String8> getUnavailablePhysicalIds();
     };
 
     // Map camera_id -> status
diff --git a/camera/ndk/ndk_vendor/impl/ACameraManager.cpp b/camera/ndk/ndk_vendor/impl/ACameraManager.cpp
index 70c887a..a95fe2a 100644
--- a/camera/ndk/ndk_vendor/impl/ACameraManager.cpp
+++ b/camera/ndk/ndk_vendor/impl/ACameraManager.cpp
@@ -36,13 +36,13 @@
 namespace android {
 namespace acam {
 
-using frameworks::cameraservice::service::V2_0::CameraStatusAndId;
 using frameworks::cameraservice::common::V2_0::ProviderIdAndVendorTagSections;
 using android::hardware::camera::common::V1_0::helper::VendorTagDescriptor;
 using android::hardware::camera::common::V1_0::helper::VendorTagDescriptorCache;
 
 // Static member definitions
 const char* CameraManagerGlobal::kCameraIdKey   = "CameraId";
+const char* CameraManagerGlobal::kPhysicalCameraIdKey   = "PhysicalCameraId";
 const char* CameraManagerGlobal::kCallbackFpKey = "CallbackFp";
 const char* CameraManagerGlobal::kContextKey    = "CallbackContext";
 Mutex                CameraManagerGlobal::sLock;
@@ -258,9 +258,9 @@
         if (mCameraServiceListener == nullptr) {
             mCameraServiceListener = new CameraServiceListener(this);
         }
-        hidl_vec<CameraStatusAndId> cameraStatuses{};
+        hidl_vec<frameworks::cameraservice::service::V2_1::CameraStatusAndId> cameraStatuses{};
         Status status = Status::NO_ERROR;
-        auto remoteRet = mCameraService->addListener(mCameraServiceListener,
+        auto remoteRet = mCameraService->addListener_2_1(mCameraServiceListener,
                                                      [&status, &cameraStatuses](Status s,
                                                                                 auto &retStatuses) {
                                                          status = s;
@@ -277,7 +277,15 @@
         }
 
         for (auto& c : cameraStatuses) {
-            onStatusChangedLocked(c);
+            onStatusChangedLocked(c.v2_0);
+
+            for (auto& unavailablePhysicalId : c.unavailPhysicalCameraIds) {
+                PhysicalCameraStatusAndId statusAndId;
+                statusAndId.deviceStatus = CameraDeviceStatus::STATUS_NOT_PRESENT;
+                statusAndId.cameraId = c.v2_0.cameraId;
+                statusAndId.physicalCameraId = unavailablePhysicalId;
+                onStatusChangedLocked(statusAndId);
+            }
         }
     }
     return mCameraService;
@@ -293,7 +301,7 @@
         for (auto& pair : cm->mDeviceStatusMap) {
             CameraStatusAndId cameraStatusAndId;
             cameraStatusAndId.cameraId = pair.first;
-            cameraStatusAndId.deviceStatus = pair.second;
+            cameraStatusAndId.deviceStatus = pair.second.getStatus();
             cm->onStatusChangedLocked(cameraStatusAndId);
         }
         cm->mCameraService.clear();
@@ -303,24 +311,7 @@
 
 void CameraManagerGlobal::registerAvailabilityCallback(
         const ACameraManager_AvailabilityCallbacks *callback) {
-    Mutex::Autolock _l(mLock);
-    Callback cb(callback);
-    auto pair = mCallbacks.insert(cb);
-    // Send initial callbacks if callback is newly registered
-    if (pair.second) {
-        for (auto& pair : mDeviceStatusMap) {
-            const hidl_string& cameraId = pair.first;
-            CameraDeviceStatus status = pair.second;
-
-            sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler);
-            ACameraManager_AvailabilityCallback cb = isStatusAvailable(status) ?
-                    callback->onCameraAvailable : callback->onCameraUnavailable;
-            msg->setPointer(kCallbackFpKey, (void *) cb);
-            msg->setPointer(kContextKey, callback->context);
-            msg->setString(kCameraIdKey, AString(cameraId.c_str()));
-            msg->post();
-        }
-    }
+    return registerAvailCallback<ACameraManager_AvailabilityCallbacks>(callback);
 }
 
 void CameraManagerGlobal::unregisterAvailabilityCallback(
@@ -330,14 +321,63 @@
     mCallbacks.erase(cb);
 }
 
+void CameraManagerGlobal::registerExtendedAvailabilityCallback(
+        const ACameraManager_ExtendedAvailabilityCallbacks *callback) {
+    return registerAvailCallback<ACameraManager_ExtendedAvailabilityCallbacks>(callback);
+}
+
+void CameraManagerGlobal::unregisterExtendedAvailabilityCallback(
+        const ACameraManager_ExtendedAvailabilityCallbacks *callback) {
+    Mutex::Autolock _l(mLock);
+    Callback cb(callback);
+    mCallbacks.erase(cb);
+}
+
+template <class T>
+void CameraManagerGlobal::registerAvailCallback(const T *callback) {
+    Mutex::Autolock _l(mLock);
+    Callback cb(callback);
+    auto pair = mCallbacks.insert(cb);
+    // Send initial callbacks if callback is newly registered
+    if (pair.second) {
+        for (auto& pair : mDeviceStatusMap) {
+            const hidl_string& cameraId = pair.first;
+            CameraDeviceStatus status = pair.second.getStatus();
+
+            // Camera available/unavailable callback
+            sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler);
+            ACameraManager_AvailabilityCallback cbFunc = isStatusAvailable(status) ?
+                    cb.mAvailable : cb.mUnavailable;
+            msg->setPointer(kCallbackFpKey, (void *) cbFunc);
+            msg->setPointer(kContextKey, cb.mContext);
+            msg->setString(kCameraIdKey, AString(cameraId.c_str()));
+            msg->post();
+
+            // Physical camera unavailable callback
+            std::set<hidl_string> unavailPhysicalIds = pair.second.getUnavailablePhysicalIds();
+            for (const auto& physicalCameraId : unavailPhysicalIds) {
+                sp<AMessage> msg = new AMessage(kWhatSendSinglePhysicalCameraCallback, mHandler);
+                ACameraManager_PhysicalCameraAvailabilityCallback cbFunc =
+                        cb.mPhysicalCamUnavailable;
+                msg->setPointer(kCallbackFpKey, (void *) cbFunc);
+                msg->setPointer(kContextKey, cb.mContext);
+                msg->setString(kCameraIdKey, AString(cameraId.c_str()));
+                msg->setString(kPhysicalCameraIdKey, AString(physicalCameraId.c_str()));
+                msg->post();
+            }
+        }
+    }
+}
+
 void CameraManagerGlobal::getCameraIdList(std::vector<hidl_string>* cameraIds) {
     // Ensure that we have initialized/refreshed the list of available devices
     auto cs = getCameraService();
     Mutex::Autolock _l(mLock);
 
     for(auto& deviceStatus : mDeviceStatusMap) {
-        if (deviceStatus.second == CameraDeviceStatus::STATUS_NOT_PRESENT ||
-                deviceStatus.second == CameraDeviceStatus::STATUS_ENUMERATING) {
+        CameraDeviceStatus status = deviceStatus.second.getStatus();
+        if (status == CameraDeviceStatus::STATUS_NOT_PRESENT ||
+                status == CameraDeviceStatus::STATUS_ENUMERATING) {
             continue;
         }
         cameraIds->push_back(deviceStatus.first);
@@ -391,6 +431,35 @@
             (*cb)(context, cameraId.c_str());
             break;
         }
+        case kWhatSendSinglePhysicalCameraCallback:
+        {
+            ACameraManager_PhysicalCameraAvailabilityCallback cb;
+            void* context;
+            AString cameraId;
+            AString physicalCameraId;
+            bool found = msg->findPointer(kCallbackFpKey, (void**) &cb);
+            if (!found) {
+                ALOGE("%s: Cannot find camera callback fp!", __FUNCTION__);
+                return;
+            }
+            found = msg->findPointer(kContextKey, &context);
+            if (!found) {
+                ALOGE("%s: Cannot find callback context!", __FUNCTION__);
+                return;
+            }
+            found = msg->findString(kCameraIdKey, &cameraId);
+            if (!found) {
+                ALOGE("%s: Cannot find camera ID!", __FUNCTION__);
+                return;
+            }
+            found = msg->findString(kPhysicalCameraIdKey, &physicalCameraId);
+            if (!found) {
+                ALOGE("%s: Cannot find physical camera ID!", __FUNCTION__);
+                return;
+            }
+            (*cb)(context, cameraId.c_str(), physicalCameraId.c_str());
+            break;
+        }
         default:
             ALOGE("%s: unknown message type %d", __FUNCTION__, msg->what());
             break;
@@ -426,7 +495,7 @@
     bool firstStatus = (mDeviceStatusMap.count(cameraId) == 0);
     CameraDeviceStatus oldStatus = firstStatus ?
             status : // first status
-            mDeviceStatusMap[cameraId];
+            mDeviceStatusMap[cameraId].getStatus();
 
     if (!firstStatus &&
             isStatusAvailable(status) == isStatusAvailable(oldStatus)) {
@@ -435,7 +504,7 @@
     }
 
     // Iterate through all registered callbacks
-    mDeviceStatusMap[cameraId] = status;
+    mDeviceStatusMap[cameraId].updateStatus(status);
     for (auto cb : mCallbacks) {
         sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler);
         ACameraManager_AvailabilityCallback cbFp = isStatusAvailable(status) ?
@@ -450,6 +519,98 @@
     }
 }
 
+hardware::Return<void> CameraManagerGlobal::CameraServiceListener::onPhysicalCameraStatusChanged(
+        const PhysicalCameraStatusAndId &statusAndId) {
+    sp<CameraManagerGlobal> cm = mCameraManager.promote();
+    if (cm != nullptr) {
+        cm->onStatusChanged(statusAndId);
+    } else {
+        ALOGE("Cannot deliver status change. Global camera manager died");
+    }
+    return Void();
+}
+
+void CameraManagerGlobal::onStatusChanged(
+        const PhysicalCameraStatusAndId &statusAndId) {
+    Mutex::Autolock _l(mLock);
+    onStatusChangedLocked(statusAndId);
+}
+
+void CameraManagerGlobal::onStatusChangedLocked(
+        const PhysicalCameraStatusAndId &statusAndId) {
+    hidl_string cameraId = statusAndId.cameraId;
+    hidl_string physicalCameraId = statusAndId.physicalCameraId;
+    CameraDeviceStatus status = statusAndId.deviceStatus;
+    if (!validStatus(status)) {
+        ALOGE("%s: Invalid status %d", __FUNCTION__, status);
+        return;
+    }
+
+    auto logicalStatus = mDeviceStatusMap.find(cameraId);
+    if (logicalStatus == mDeviceStatusMap.end()) {
+        ALOGE("%s: Physical camera id %s status change on a non-present id %s",
+                __FUNCTION__, physicalCameraId.c_str(), cameraId.c_str());
+        return;
+    }
+    CameraDeviceStatus logicalCamStatus = mDeviceStatusMap[cameraId].getStatus();
+    if (logicalCamStatus != CameraDeviceStatus::STATUS_PRESENT &&
+            logicalCamStatus != CameraDeviceStatus::STATUS_NOT_AVAILABLE) {
+        ALOGE("%s: Physical camera id %s status %d change for an invalid logical camera state %d",
+                __FUNCTION__, physicalCameraId.c_str(), status, logicalCamStatus);
+        return;
+    }
+
+    bool updated = false;
+    if (status == CameraDeviceStatus::STATUS_PRESENT) {
+        updated = mDeviceStatusMap[cameraId].removeUnavailablePhysicalId(physicalCameraId);
+    } else {
+        updated = mDeviceStatusMap[cameraId].addUnavailablePhysicalId(physicalCameraId);
+    }
+
+    // Iterate through all registered callbacks
+    if (updated) {
+        for (auto cb : mCallbacks) {
+            sp<AMessage> msg = new AMessage(kWhatSendSinglePhysicalCameraCallback, mHandler);
+            ACameraManager_PhysicalCameraAvailabilityCallback cbFp = isStatusAvailable(status) ?
+                    cb.mPhysicalCamAvailable : cb.mPhysicalCamUnavailable;
+            msg->setPointer(kCallbackFpKey, (void *) cbFp);
+            msg->setPointer(kContextKey, cb.mContext);
+            msg->setString(kCameraIdKey, AString(cameraId.c_str()));
+            msg->setString(kPhysicalCameraIdKey, AString(physicalCameraId.c_str()));
+            msg->post();
+        }
+    }
+}
+
+CameraDeviceStatus CameraManagerGlobal::CameraStatus::getStatus() {
+    std::lock_guard<std::mutex> lock(mLock);
+    return status;
+}
+
+void CameraManagerGlobal::CameraStatus::updateStatus(CameraDeviceStatus newStatus) {
+    std::lock_guard<std::mutex> lock(mLock);
+    status = newStatus;
+}
+
+bool CameraManagerGlobal::CameraStatus::addUnavailablePhysicalId(
+        const hidl_string& physicalCameraId) {
+    std::lock_guard<std::mutex> lock(mLock);
+    auto result = unavailablePhysicalIds.insert(physicalCameraId);
+    return result.second;
+}
+
+bool CameraManagerGlobal::CameraStatus::removeUnavailablePhysicalId(
+        const hidl_string& physicalCameraId) {
+    std::lock_guard<std::mutex> lock(mLock);
+    auto count = unavailablePhysicalIds.erase(physicalCameraId);
+    return count > 0;
+}
+
+std::set<hidl_string> CameraManagerGlobal::CameraStatus::getUnavailablePhysicalIds() {
+    std::lock_guard<std::mutex> lock(mLock);
+    return unavailablePhysicalIds;
+}
+
 } // namespace acam
 } // namespace android
 
diff --git a/camera/ndk/ndk_vendor/impl/ACameraManager.h b/camera/ndk/ndk_vendor/impl/ACameraManager.h
index 2c62d44..36c8e2b 100644
--- a/camera/ndk/ndk_vendor/impl/ACameraManager.h
+++ b/camera/ndk/ndk_vendor/impl/ACameraManager.h
@@ -21,6 +21,8 @@
 
 #include <android-base/parseint.h>
 #include <android/frameworks/cameraservice/service/2.0/ICameraService.h>
+#include <android/frameworks/cameraservice/service/2.1/ICameraService.h>
+#include <android/frameworks/cameraservice/service/2.1/ICameraServiceListener.h>
 
 #include <CameraMetadata.h>
 #include <utils/StrongPointer.h>
@@ -36,9 +38,10 @@
 namespace android {
 namespace acam {
 
-using ICameraService = frameworks::cameraservice::service::V2_0::ICameraService;
+using ICameraService = frameworks::cameraservice::service::V2_1::ICameraService;
 using CameraDeviceStatus = frameworks::cameraservice::service::V2_0::CameraDeviceStatus;
-using ICameraServiceListener = frameworks::cameraservice::service::V2_0::ICameraServiceListener;
+using ICameraServiceListener = frameworks::cameraservice::service::V2_1::ICameraServiceListener;
+using PhysicalCameraStatusAndId = frameworks::cameraservice::service::V2_1::PhysicalCameraStatusAndId;
 using CameraStatusAndId = frameworks::cameraservice::service::V2_0::CameraStatusAndId;
 using Status = frameworks::cameraservice::common::V2_0::Status;
 using VendorTagSection = frameworks::cameraservice::common::V2_0::VendorTagSection;
@@ -65,9 +68,9 @@
             const ACameraManager_AvailabilityCallbacks *callback);
 
     void registerExtendedAvailabilityCallback(
-            const ACameraManager_ExtendedAvailabilityCallbacks* /*callback*/) {}
+            const ACameraManager_ExtendedAvailabilityCallbacks* callback);
     void unregisterExtendedAvailabilityCallback(
-            const ACameraManager_ExtendedAvailabilityCallbacks* /*callback*/) {}
+            const ACameraManager_ExtendedAvailabilityCallbacks* callback);
 
     /**
      * Return camera IDs that support camera2
@@ -94,6 +97,8 @@
         explicit CameraServiceListener(CameraManagerGlobal* cm) : mCameraManager(cm) {}
         android::hardware::Return<void> onStatusChanged(
             const CameraStatusAndId &statusAndId) override;
+        android::hardware::Return<void> onPhysicalCameraStatusChanged(
+            const PhysicalCameraStatusAndId &statusAndId) override;
 
       private:
         const wp<CameraManagerGlobal> mCameraManager;
@@ -105,11 +110,25 @@
         explicit Callback(const ACameraManager_AvailabilityCallbacks *callback) :
             mAvailable(callback->onCameraAvailable),
             mUnavailable(callback->onCameraUnavailable),
+            mAccessPriorityChanged(nullptr),
+            mPhysicalCamAvailable(nullptr),
+            mPhysicalCamUnavailable(nullptr),
             mContext(callback->context) {}
 
+        explicit Callback(const ACameraManager_ExtendedAvailabilityCallbacks *callback) :
+            mAvailable(callback->availabilityCallbacks.onCameraAvailable),
+            mUnavailable(callback->availabilityCallbacks.onCameraUnavailable),
+            mAccessPriorityChanged(callback->onCameraAccessPrioritiesChanged),
+            mPhysicalCamAvailable(callback->onPhysicalCameraAvailable),
+            mPhysicalCamUnavailable(callback->onPhysicalCameraUnavailable),
+            mContext(callback->availabilityCallbacks.context) {}
+
         bool operator == (const Callback& other) const {
             return (mAvailable == other.mAvailable &&
                     mUnavailable == other.mUnavailable &&
+                    mAccessPriorityChanged == other.mAccessPriorityChanged &&
+                    mPhysicalCamAvailable == other.mPhysicalCamAvailable &&
+                    mPhysicalCamUnavailable == other.mPhysicalCamUnavailable &&
                     mContext == other.mContext);
         }
         bool operator != (const Callback& other) const {
@@ -119,6 +138,12 @@
             if (*this == other) return false;
             if (mContext != other.mContext) return mContext < other.mContext;
             if (mAvailable != other.mAvailable) return mAvailable < other.mAvailable;
+            if (mAccessPriorityChanged != other.mAccessPriorityChanged)
+                    return mAccessPriorityChanged < other.mAccessPriorityChanged;
+            if (mPhysicalCamAvailable != other.mPhysicalCamAvailable)
+                    return mPhysicalCamAvailable < other.mPhysicalCamAvailable;
+            if (mPhysicalCamUnavailable != other.mPhysicalCamUnavailable)
+                    return mPhysicalCamUnavailable < other.mPhysicalCamUnavailable;
             return mUnavailable < other.mUnavailable;
         }
         bool operator > (const Callback& other) const {
@@ -126,15 +151,20 @@
         }
         ACameraManager_AvailabilityCallback mAvailable;
         ACameraManager_AvailabilityCallback mUnavailable;
+        ACameraManager_AccessPrioritiesChangedCallback mAccessPriorityChanged;
+        ACameraManager_PhysicalCameraAvailabilityCallback mPhysicalCamAvailable;
+        ACameraManager_PhysicalCameraAvailabilityCallback mPhysicalCamUnavailable;
         void*                               mContext;
     };
     std::set<Callback> mCallbacks;
 
     // definition of handler and message
     enum {
-        kWhatSendSingleCallback
+        kWhatSendSingleCallback,
+        kWhatSendSinglePhysicalCameraCallback,
     };
     static const char* kCameraIdKey;
+    static const char* kPhysicalCameraIdKey;
     static const char* kCallbackFpKey;
     static const char* kContextKey;
     class CallbackHandler : public AHandler {
@@ -147,6 +177,8 @@
 
     void onStatusChanged(const CameraStatusAndId &statusAndId);
     void onStatusChangedLocked(const CameraStatusAndId &statusAndId);
+    void onStatusChanged(const PhysicalCameraStatusAndId &statusAndId);
+    void onStatusChangedLocked(const PhysicalCameraStatusAndId &statusAndId);
     bool setupVendorTags();
 
     // Utils for status
@@ -174,8 +206,27 @@
         }
     };
 
+    struct CameraStatus {
+      private:
+        CameraDeviceStatus status = CameraDeviceStatus::STATUS_NOT_PRESENT;
+        mutable std::mutex mLock;
+        std::set<hidl_string> unavailablePhysicalIds;
+      public:
+        CameraStatus(CameraDeviceStatus st): status(st) { };
+        CameraStatus() = default;
+
+        bool addUnavailablePhysicalId(const hidl_string& physicalCameraId);
+        bool removeUnavailablePhysicalId(const hidl_string& physicalCameraId);
+        CameraDeviceStatus getStatus();
+        void updateStatus(CameraDeviceStatus newStatus);
+        std::set<hidl_string> getUnavailablePhysicalIds();
+    };
+
+    template <class T>
+    void registerAvailCallback(const T *callback);
+
     // Map camera_id -> status
-    std::map<hidl_string, CameraDeviceStatus, CameraIdComparator> mDeviceStatusMap;
+    std::map<hidl_string, CameraStatus, CameraIdComparator> mDeviceStatusMap;
 
     // For the singleton instance
     static Mutex sLock;
diff --git a/camera/ndk/ndk_vendor/tests/ACameraManagerTest.cpp b/camera/ndk/ndk_vendor/tests/ACameraManagerTest.cpp
new file mode 100644
index 0000000..a20a290
--- /dev/null
+++ b/camera/ndk/ndk_vendor/tests/ACameraManagerTest.cpp
@@ -0,0 +1,238 @@
+/*
+ * Copyright (C) 2020 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_TAG "ACameraManagerTest"
+//#define LOG_NDEBUG 0
+
+#include <gtest/gtest.h>
+
+#include <mutex>
+#include <set>
+#include <string>
+
+#include <utils/Log.h>
+#include <camera/NdkCameraError.h>
+#include <camera/NdkCameraManager.h>
+
+namespace {
+
+class CameraServiceListener {
+  public:
+    typedef std::set<std::pair<std::string, std::string>> StringPairSet;
+
+    static void onAvailable(void* obj, const char* cameraId) {
+        ALOGV("Camera %s onAvailable", cameraId);
+        if (obj == nullptr) {
+            return;
+        }
+        CameraServiceListener* thiz = reinterpret_cast<CameraServiceListener*>(obj);
+        std::lock_guard<std::mutex> lock(thiz->mMutex);
+        thiz->mOnAvailableCount++;
+        thiz->mAvailableMap[cameraId] = true;
+        return;
+    }
+
+    static void onUnavailable(void* obj, const char* cameraId) {
+        ALOGV("Camera %s onUnavailable", cameraId);
+        if (obj == nullptr) {
+            return;
+        }
+        CameraServiceListener* thiz = reinterpret_cast<CameraServiceListener*>(obj);
+        std::lock_guard<std::mutex> lock(thiz->mMutex);
+        thiz->mOnUnavailableCount++;
+        thiz->mAvailableMap[cameraId] = false;
+        return;
+    }
+
+    static void onCameraAccessPrioritiesChanged(void* /*obj*/) {
+        return;
+    }
+
+    static void onPhysicalCameraAvailable(void* obj, const char* cameraId,
+            const char* physicalCameraId) {
+        ALOGV("Camera %s : %s onAvailable", cameraId, physicalCameraId);
+        if (obj == nullptr) {
+            return;
+        }
+        CameraServiceListener* thiz = reinterpret_cast<CameraServiceListener*>(obj);
+        std::lock_guard<std::mutex> lock(thiz->mMutex);
+        thiz->mOnPhysicalCameraAvailableCount++;
+        return;
+    }
+
+    static void onPhysicalCameraUnavailable(void* obj, const char* cameraId,
+            const char* physicalCameraId) {
+        ALOGV("Camera %s : %s onUnavailable", cameraId, physicalCameraId);
+        if (obj == nullptr) {
+            return;
+        }
+        CameraServiceListener* thiz = reinterpret_cast<CameraServiceListener*>(obj);
+        std::lock_guard<std::mutex> lock(thiz->mMutex);
+        thiz->mUnavailablePhysicalCameras.emplace(cameraId, physicalCameraId);
+        return;
+    }
+
+    void resetCount() {
+        std::lock_guard<std::mutex> lock(mMutex);
+        mOnAvailableCount = 0;
+        mOnUnavailableCount = 0;
+        mOnPhysicalCameraAvailableCount = 0;
+        mUnavailablePhysicalCameras.clear();
+        return;
+    }
+
+    int getAvailableCount() {
+        std::lock_guard<std::mutex> lock(mMutex);
+        return mOnAvailableCount;
+    }
+
+    int getUnavailableCount() {
+        std::lock_guard<std::mutex> lock(mMutex);
+        return mOnUnavailableCount;
+    }
+
+    int getPhysicalCameraAvailableCount() {
+        std::lock_guard<std::mutex> lock(mMutex);
+        return mOnPhysicalCameraAvailableCount;
+    }
+
+    StringPairSet getUnavailablePhysicalCameras() {
+        std::lock_guard<std::mutex> lock(mMutex);
+        return mUnavailablePhysicalCameras;
+    }
+
+    bool isAvailable(const char* cameraId) {
+        std::lock_guard<std::mutex> lock(mMutex);
+        if (mAvailableMap.count(cameraId) == 0) {
+            return false;
+        }
+        return mAvailableMap[cameraId];
+    }
+
+  private:
+    std::mutex mMutex;
+    int mOnAvailableCount = 0;
+    int mOnUnavailableCount = 0;
+    int mOnPhysicalCameraAvailableCount = 0;
+    std::map<std::string, bool> mAvailableMap;
+    StringPairSet mUnavailablePhysicalCameras;
+};
+
+class ACameraManagerTest : public ::testing::Test {
+  public:
+    void SetUp() override {
+        mCameraManager = ACameraManager_create();
+        if (mCameraManager == nullptr) {
+            ALOGE("Failed to create ACameraManager.");
+            return;
+        }
+
+        camera_status_t ret = ACameraManager_getCameraIdList(mCameraManager, &mCameraIdList);
+        if (ret != ACAMERA_OK) {
+            ALOGE("Failed to get cameraIdList: ret=%d", ret);
+            return;
+        }
+        if (mCameraIdList->numCameras < 1) {
+            ALOGW("Device has no camera on board.");
+            return;
+        }
+    }
+    void TearDown() override {
+        // Destroy camera manager
+        if (mCameraIdList) {
+            ACameraManager_deleteCameraIdList(mCameraIdList);
+            mCameraIdList = nullptr;
+        }
+        if (mCameraManager) {
+            ACameraManager_delete(mCameraManager);
+            mCameraManager = nullptr;
+        }
+    }
+
+    // Camera manager
+    ACameraManager* mCameraManager = nullptr;
+    ACameraIdList* mCameraIdList = nullptr;
+    CameraServiceListener mAvailabilityListener;
+    ACameraManager_ExtendedAvailabilityCallbacks mCbs = {
+        {
+            &mAvailabilityListener,
+                CameraServiceListener::onAvailable,
+                CameraServiceListener::onUnavailable
+        },
+        CameraServiceListener::onCameraAccessPrioritiesChanged,
+        CameraServiceListener::onPhysicalCameraAvailable,
+        CameraServiceListener::onPhysicalCameraUnavailable,
+        {}
+    };
+};
+
+TEST_F(ACameraManagerTest, testCameraManagerExtendedAvailabilityCallbacks) {
+    camera_status_t ret = ACameraManager_registerExtendedAvailabilityCallback(mCameraManager,
+            &mCbs);
+    ASSERT_EQ(ret, ACAMERA_OK);
+
+    sleep(1);
+
+    // Should at least get onAvailable for each camera once
+    ASSERT_EQ(mAvailabilityListener.getAvailableCount(), mCameraIdList->numCameras);
+
+    // Expect no available callbacks for physical cameras
+    int availablePhysicalCamera = mAvailabilityListener.getPhysicalCameraAvailableCount();
+    ASSERT_EQ(availablePhysicalCamera, 0);
+
+    CameraServiceListener::StringPairSet unavailablePhysicalCameras;
+    CameraServiceListener::StringPairSet physicalCameraIdPairs;
+
+    unavailablePhysicalCameras = mAvailabilityListener.getUnavailablePhysicalCameras();
+    for (int i = 0; i < mCameraIdList->numCameras; i++) {
+        const char* cameraId = mCameraIdList->cameraIds[i];
+        ASSERT_NE(cameraId, nullptr);
+        ASSERT_TRUE(mAvailabilityListener.isAvailable(cameraId));
+
+        ACameraMetadata* chars = nullptr;
+        ret = ACameraManager_getCameraCharacteristics(mCameraManager, cameraId, &chars);
+        ASSERT_EQ(ret, ACAMERA_OK);
+        ASSERT_NE(chars, nullptr);
+
+        size_t physicalCameraCnt = 0;
+        const char *const* physicalCameraIds = nullptr;
+        if (!ACameraMetadata_isLogicalMultiCamera(
+                chars, &physicalCameraCnt, &physicalCameraIds)) {
+            ACameraMetadata_free(chars);
+            continue;
+        }
+        for (size_t j = 0; j < physicalCameraCnt; j++) {
+            physicalCameraIdPairs.emplace(cameraId, physicalCameraIds[j]);
+        }
+        ACameraMetadata_free(chars);
+    }
+    for (const auto& unavailIdPair : unavailablePhysicalCameras) {
+        bool validPair = false;
+        for (const auto& idPair : physicalCameraIdPairs) {
+            if (idPair.first == unavailIdPair.first && idPair.second == unavailIdPair.second) {
+                validPair = true;
+                break;
+            }
+        }
+        // Expect valid unavailable physical cameras
+        ASSERT_TRUE(validPair);
+    }
+
+    ret = ACameraManager_unregisterExtendedAvailabilityCallback(mCameraManager, &mCbs);
+    ASSERT_EQ(ret, ACAMERA_OK);
+}
+
+}  // namespace
diff --git a/drm/libmediadrm/Android.bp b/drm/libmediadrm/Android.bp
index 6ba1b9c..1700a95 100644
--- a/drm/libmediadrm/Android.bp
+++ b/drm/libmediadrm/Android.bp
@@ -50,6 +50,7 @@
         "android.hardware.drm@1.0",
         "android.hardware.drm@1.1",
         "android.hardware.drm@1.2",
+        "android.hardware.drm@1.3",
         "libhidlallocatorutils",
         "libhidlbase",
     ],
diff --git a/drm/libmediadrm/DrmUtils.cpp b/drm/libmediadrm/DrmUtils.cpp
index 3549637..51c2e24 100644
--- a/drm/libmediadrm/DrmUtils.cpp
+++ b/drm/libmediadrm/DrmUtils.cpp
@@ -25,6 +25,8 @@
 #include <android/hardware/drm/1.1/IDrmFactory.h>
 #include <android/hardware/drm/1.2/ICryptoFactory.h>
 #include <android/hardware/drm/1.2/IDrmFactory.h>
+#include <android/hardware/drm/1.3/ICryptoFactory.h>
+#include <android/hardware/drm/1.3/IDrmFactory.h>
 #include <android/hidl/manager/1.0/IServiceManager.h>
 #include <hidl/HidlSupport.h>
 
@@ -144,6 +146,7 @@
     MakeHidlFactories<::V1_0::IDrmFactory>(uuid, drmFactories);
     MakeHidlFactories<::V1_1::IDrmFactory>(uuid, drmFactories);
     MakeHidlFactories<::V1_2::IDrmFactory>(uuid, drmFactories);
+    MakeHidlFactories<::V1_3::IDrmFactory>(uuid, drmFactories);
     return drmFactories;
 }
 
@@ -161,6 +164,7 @@
     MakeHidlFactories<::V1_0::ICryptoFactory>(uuid, cryptoFactories);
     MakeHidlFactories<::V1_1::ICryptoFactory>(uuid, cryptoFactories);
     MakeHidlFactories<::V1_2::ICryptoFactory>(uuid, cryptoFactories);
+    MakeHidlFactories<::V1_3::ICryptoFactory>(uuid, cryptoFactories);
     return cryptoFactories;
 }
 
diff --git a/media/codec2/TEST_MAPPING b/media/codec2/TEST_MAPPING
index e01f452..5a60243 100644
--- a/media/codec2/TEST_MAPPING
+++ b/media/codec2/TEST_MAPPING
@@ -1,31 +1,16 @@
 {
-  "presubmit": [
+  "postsubmit": [
     {
-      "name": "GtsMediaTestCases",
-      "options" : [
+      // TODO: move to presubmit once we verify the tests are not flaky
+      "name": "CtsMediaTestCases",
+      "options": [
         {
-	  "include-annotation": "android.platform.test.annotations.Presubmit"
+          "include-annotation": "android.platform.test.annotations.Presubmit"
         },
         {
-          "include-filter": "com.google.android.media.gts.WidevineGenericOpsTests"
+          "exclude-annotation": "android.platform.test.annotations.RequiresDevice"
         }
       ]
-    },
-    {
-      "name": "GtsExoPlayerTestCases",
-      "options" : [
-        {
-	  "include-annotation": "android.platform.test.annotations.SocPresubmit"
-        },
-        {
-          "include-filter": "com.google.android.exoplayer.gts.DashTest#testWidevine23FpsH264Fixed"
-        }
-      ]
-    }
-  ],
-  "imports": [
-    {
-      "path": "frameworks/av/drm/mediadrm/plugins"
     }
   ]
 }
diff --git a/media/codec2/hidl/1.0/utils/InputSurfaceConnection.cpp b/media/codec2/hidl/1.0/utils/InputSurfaceConnection.cpp
index 5cc0d53..5ec88ec 100644
--- a/media/codec2/hidl/1.0/utils/InputSurfaceConnection.cpp
+++ b/media/codec2/hidl/1.0/utils/InputSurfaceConnection.cpp
@@ -160,12 +160,12 @@
             return false;
         }
         for (int32_t i = 0; i < kBufferCount; ++i) {
-            if (!mSource->onInputBufferAdded(i).isOk()) {
+            if (mSource->onInputBufferAdded(i) != OK) {
                 LOG(WARNING) << "Impl::init: failed to populate GBS slots.";
                 return false;
             }
         }
-        if (!mSource->start().isOk()) {
+        if (mSource->start() != OK) {
             LOG(WARNING) << "Impl::init -- GBS failed to start.";
             return false;
         }
diff --git a/media/codec2/sfplugin/Android.bp b/media/codec2/sfplugin/Android.bp
index 94034b5..cb60a45 100644
--- a/media/codec2/sfplugin/Android.bp
+++ b/media/codec2/sfplugin/Android.bp
@@ -45,7 +45,7 @@
         "libmedia_codeclist",
         "libmedia_omx",
         "libsfplugin_ccodec_utils",
-        "libstagefright_bufferqueue_helper",
+        "libstagefright_bufferqueue_helper_client",
         "libstagefright_codecbase",
         "libstagefright_foundation",
         "libstagefright_omx",
diff --git a/media/extractors/tests/AndroidTest.xml b/media/extractors/tests/AndroidTest.xml
new file mode 100644
index 0000000..6bb2c8a
--- /dev/null
+++ b/media/extractors/tests/AndroidTest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.
+-->
+<configuration description="Test module config for extractor unit tests">
+    <option name="test-suite-tag" value="ExtractorUnitTest" />
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push" value="ExtractorUnitTest->/data/local/tmp/ExtractorUnitTest" />
+        <option name="push-file"
+            key="https://storage.googleapis.com/android_media/frameworks/av/media/extractors/tests/extractor.zip?unzip=true"
+            value="/data/local/tmp/ExtractorUnitTestRes/" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="ExtractorUnitTest" />
+        <option name="native-test-flag" value="-P /data/local/tmp/ExtractorUnitTestRes/" />
+    </test>
+</configuration>
diff --git a/media/extractors/tests/README.md b/media/extractors/tests/README.md
index 6e02d3e..69538b6 100644
--- a/media/extractors/tests/README.md
+++ b/media/extractors/tests/README.md
@@ -22,8 +22,8 @@
 adb push ${OUT}/data/nativetest/ExtractorUnitTest/ExtractorUnitTest /data/local/tmp/
 ```
 
-The resource file for the tests is taken from [here](https://drive.google.com/drive/folders/1Z9nCIRB6pGLvb5mPkF8BURa5Nc6cY9pY). Push these files into device for testing.
-Download extractor folder and push all the files in this folder to /data/local/tmp/ on the device.
+The resource file for the tests is taken from [here](https://storage.googleapis.com/android_media/frameworks/av/media/extractors/tests/extractor.zip). Download, unzip and push these files into device for testing.
+
 ```
 adb push extractor /data/local/tmp/
 ```
@@ -32,3 +32,8 @@
 ```
 adb shell /data/local/tmp/ExtractorUnitTest -P /data/local/tmp/extractor/
 ```
+Alternatively, the test can also be run using atest command.
+
+```
+atest ExtractorUnitTest -- --enable-module-dynamic-download=true
+```
diff --git a/media/libmediaplayerservice/datasource/PlayerServiceFileSource.cpp b/media/libmediaplayerservice/datasource/PlayerServiceFileSource.cpp
index bb4ba75..4d95de5 100644
--- a/media/libmediaplayerservice/datasource/PlayerServiceFileSource.cpp
+++ b/media/libmediaplayerservice/datasource/PlayerServiceFileSource.cpp
@@ -71,6 +71,9 @@
     Mutex::Autolock autoLock(mLock);
 
     if (mLength >= 0) {
+        if (offset < 0) {
+            return UNKNOWN_ERROR;
+        }
         if (offset >= mLength) {
             return 0;  // read beyond EOF.
         }
diff --git a/media/libmediatranscoding/include/media/AdjustableMaxPriorityQueue.h b/media/libmediatranscoding/include/media/AdjustableMaxPriorityQueue.h
new file mode 100644
index 0000000..0e8dcfd
--- /dev/null
+++ b/media/libmediatranscoding/include/media/AdjustableMaxPriorityQueue.h
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2020 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 ANDROID_MEDIA_ADJUSTABLE_MAX_PRIORITY_QUEUE_H
+#define ANDROID_MEDIA_ADJUSTABLE_MAX_PRIORITY_QUEUE_H
+
+#include <utils/Log.h>
+
+#include <functional>
+#include <iostream>
+#include <vector>
+
+namespace android {
+
+/*
+ * AdjustableMaxPriorityQueue is a custom max priority queue that helps managing jobs for
+ * MediaTranscodingService.
+ *
+ * AdjustableMaxPriorityQueue is a wrapper template around the STL's *_heap() functions.
+ * - Internally, it uses a std::vector<T> to store elements in a heap order.
+ * - Support adjusting item's priority while maintaining the heap property.
+ * - Support removing any item in the heap while maintaining the heap property. Note that the
+ *   removal complexity will be O(n) in worst case.
+ * - AdjustableMaxPriorityQueue needs T::operator<() at instantiation time
+ */
+template <class T, class Comparator = std::less<T>>
+class AdjustableMaxPriorityQueue {
+   public:
+    typedef typename std::vector<T>::iterator iterator;
+    typedef typename std::vector<T>::const_iterator const_iterator;
+
+    AdjustableMaxPriorityQueue();
+
+    /* Whether the queue is empty. */
+    bool empty() const;
+
+    /* Number of items in the queue. */
+    int size() const;
+
+    /* Return the top element in the queue. The queue still owns the element. */
+    const T& top() const;
+
+    /* Discards the element with highest value based on the given comparator. */
+    void pop();
+
+    /* Erases all the elements in the queue. */
+    void clear();
+
+    /*
+     * Returns the element with the highest value based on the given comparator. Queue transfer the
+     * ownership of the item to the caller. Client MUST call empty() to check whether there is
+     * element at the top before calling this.
+     */
+    T consume_top();
+
+    /* Adds an element to the heap. The queue will make a deep copy of the element. */
+    bool push(const T& item) { return pushInternal(item); }
+
+    /* Adds an element to the heap. The queue will take ownership of the element. */
+    bool push(T&& item) { return pushInternal(std::move(item)); }
+
+    /* Adds a new element to the AdjustableMaxPriorityQueue. This new element is constructed in
+     * place passing args as the arguments for its constructor. */
+    template <class... Args>
+    bool emplace(Args&&... args);
+
+    /* Remove an element from a AdjustableMaxPriorityQueue. */
+    void erase(iterator pos);
+
+    /*
+     * Rebuild a heap based on the given comparator. This MUST be called after changing the value
+     * of items.
+     */
+    void rebuild();
+
+    /*
+     * Iterators used for accessing and changing the priority.
+     * If you change the value of items through these access iterators BE SURE to call rebuild() to
+     * ensure the integrity of the heap is maintained.
+     * NOTE: The iterator pos will change after calling rebuild().
+     */
+    const iterator begin();
+    const iterator end();
+
+    /*
+     * Iterators used for accessing the priority.
+     */
+    const const_iterator begin() const;
+    const const_iterator end() const;
+
+    /* Return the backbone storage of this PriorityQueue. Mainly used for debugging. */
+    const std::vector<T>& getStorage() const { return mHeap; };
+
+   private:
+    std::vector<T> mHeap;
+
+    /* Implementation shared by both public push() methods. */
+    template <class Arg>
+    bool pushInternal(Arg&& item);
+};
+
+template <class T, class Comparator>
+AdjustableMaxPriorityQueue<T, Comparator>::AdjustableMaxPriorityQueue() {}
+
+template <class T, class Comparator>
+bool AdjustableMaxPriorityQueue<T, Comparator>::empty() const {
+    return mHeap.empty();
+}
+
+template <class T, class Comparator>
+int AdjustableMaxPriorityQueue<T, Comparator>::size() const {
+    return mHeap.size();
+}
+
+template <class T, class Comparator>
+const T& AdjustableMaxPriorityQueue<T, Comparator>::top() const {
+    DCHECK(!mHeap.empty());
+    return mHeap.front();
+}
+
+// Compares elements and potentially swaps (or moves) them until rearranged as a longer heap.
+// Complexity of this: Up to logarithmic in the distance between first and last.
+template <class T, class Comparator>
+template <class Arg>
+bool AdjustableMaxPriorityQueue<T, Comparator>::pushInternal(Arg&& item) {
+    mHeap.push_back(std::forward<Arg>(item));
+    std::push_heap(mHeap.begin(), mHeap.end(), Comparator());
+    return true;
+}
+
+template <class T, class Comparator>
+template <class... Args>
+bool AdjustableMaxPriorityQueue<T, Comparator>::emplace(Args&&... args) {
+    mHeap.emplace_back(std::forward<Args>(args)...);
+    std::push_heap(mHeap.begin(), mHeap.end(), Comparator());
+    return true;
+}
+
+// Compares elements and potentially swaps (or moves) them until rearranged as a shorter heap.
+// Complexity of this: Up to twice logarithmic in the distance between first and last.
+template <class T, class Comparator>
+void AdjustableMaxPriorityQueue<T, Comparator>::pop() {
+    DCHECK(!mHeap.empty());
+    std::pop_heap(mHeap.begin(), mHeap.end(), Comparator());
+    mHeap.pop_back();
+}
+
+// Compares elements and potentially swaps (or moves) them until rearranged as a shorter heap.
+// Complexity of this: Up to twice logarithmic in the distance between first and last.
+template <class T, class Comparator>
+T AdjustableMaxPriorityQueue<T, Comparator>::consume_top() {
+    DCHECK(!mHeap.empty());
+    std::pop_heap(mHeap.begin(), mHeap.end(), Comparator());
+    T to_return = std::move(mHeap.back());
+    mHeap.pop_back();
+    return to_return;
+}
+
+template <class T, class Comparator>
+const typename AdjustableMaxPriorityQueue<T, Comparator>::iterator
+AdjustableMaxPriorityQueue<T, Comparator>::begin() {
+    return mHeap.begin();
+}
+
+template <class T, class Comparator>
+const typename AdjustableMaxPriorityQueue<T, Comparator>::iterator
+AdjustableMaxPriorityQueue<T, Comparator>::end() {
+    return mHeap.end();
+}
+
+template <class T, class Comparator>
+const typename AdjustableMaxPriorityQueue<T, Comparator>::const_iterator
+AdjustableMaxPriorityQueue<T, Comparator>::begin() const {
+    return mHeap.begin();
+}
+
+template <class T, class Comparator>
+const typename AdjustableMaxPriorityQueue<T, Comparator>::const_iterator
+AdjustableMaxPriorityQueue<T, Comparator>::end() const {
+    return mHeap.end();
+}
+
+template <class T, class Comparator>
+void AdjustableMaxPriorityQueue<T, Comparator>::clear() {
+    mHeap.erase(mHeap.begin(), mHeap.end());
+}
+
+// Complexity of this: At most 3*std::distance(first, last) comparisons.
+template <class T, class Comparator>
+void AdjustableMaxPriorityQueue<T, Comparator>::rebuild() {
+    std::make_heap(mHeap.begin(), mHeap.end(), Comparator());
+}
+
+// Remove a random element from a AdjustableMaxPriorityQueue.
+template <class T, class Comparator>
+void AdjustableMaxPriorityQueue<T, Comparator>::erase(iterator pos) {
+    DCHECK(!mHeap.empty());
+    mHeap.erase(pos);
+    rebuild();
+}
+
+}  // namespace android
+#endif  // ANDROID_MEDIA_ADJUSTABLE_MAX_PRIORITY_QUEUE_H
\ No newline at end of file
diff --git a/media/libmediatranscoding/tests/AdjustableMaxPriorityQueue_tests.cpp b/media/libmediatranscoding/tests/AdjustableMaxPriorityQueue_tests.cpp
new file mode 100644
index 0000000..d58af4e
--- /dev/null
+++ b/media/libmediatranscoding/tests/AdjustableMaxPriorityQueue_tests.cpp
@@ -0,0 +1,289 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+// Unit Test for AdjustableMaxPriorityQueue
+
+#define LOG_NDEBUG 0
+#define LOG_TAG "AdjustableMaxPriorityQueueTest"
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <gtest/gtest.h>
+#include <media/AdjustableMaxPriorityQueue.h>
+#include <utils/Log.h>
+
+#include <algorithm>
+#include <functional>
+#include <iterator>
+#include <list>
+#include <queue>
+#include <unordered_map>
+
+namespace android {
+
+class IntUniquePtrComp {
+   public:
+    bool operator()(const std::unique_ptr<int>& lhs, const std::unique_ptr<int>& rhs) const {
+        return *lhs < *rhs;
+    }
+};
+
+// Test the heap property and make sure it is the same as std::priority_queue.
+TEST(AdjustableMaxPriorityQueueTest, BasicAPIS) {
+    AdjustableMaxPriorityQueue<std::pair<float, char*>> heap;
+    std::priority_queue<std::pair<float, char*>> pq;
+    AdjustableMaxPriorityQueue<std::pair<float, char*>> remove_queue;
+
+    // Push a set of values onto both AdjustableMaxPriorityQueue and priority_queue
+    // Also compute the sum of those values
+    double sum = 0;
+    for (int i = 0; i < 10; ++i) {
+        float value = 2.1 * i;
+        sum += value;
+        heap.push(std::pair<float, char*>(value, nullptr));
+        pq.push(std::pair<float, char*>(value, nullptr));
+        remove_queue.push(std::pair<float, char*>(value, nullptr));
+    }
+
+    // Test the iterator by using it to subtract all values from earlier sum
+    AdjustableMaxPriorityQueue<std::pair<float, char*>>::iterator it;
+    for (it = heap.begin(); it != heap.end(); ++it) {
+        sum -= it->first;
+    }
+    EXPECT_EQ(0, sum);
+
+    // Test the size();
+    EXPECT_EQ(10, heap.size());
+
+    // Testing pop() by popping values from both queues and compare if they are the same.
+    // Also check each pop is smaller than the previous pop max value.
+    float max = 1000;
+    while (!heap.empty()) {
+        float value = heap.top().first;
+        ALOGD("Value is %f ", value);
+        EXPECT_EQ(value, pq.top().first);
+        EXPECT_LE(value, max);
+        max = value;
+        heap.pop();
+        pq.pop();
+    }
+
+    // Test erase() by removing values and ensuring the heap
+    // condition is still met as miscellaneous elements are
+    // removed from the heap.
+    int iteration_mixer = 0;
+    float previous_value = remove_queue.top().first;
+
+    while (!remove_queue.empty()) {
+        int iteration_count = iteration_mixer % remove_queue.size();
+
+        AdjustableMaxPriorityQueue<std::pair<float, char*>>::iterator iterator =
+                remove_queue.begin();
+
+        // Empty loop as we just want to advance the iterator.
+        for (int i = 0; i < iteration_count; ++i, ++iterator) {
+        }
+
+        remove_queue.erase(iterator);
+        float value = remove_queue.top().first;
+        remove_queue.pop();
+
+        EXPECT_GE(previous_value, value);
+
+        ++iteration_mixer;
+        previous_value = value;
+    }
+}
+
+TEST(AdjustableMaxPriorityQueueTest, BasicWithMoveOnly) {
+    AdjustableMaxPriorityQueue<std::unique_ptr<int>, IntUniquePtrComp> heap;
+
+    auto smaller = std::make_unique<int>(1);
+    EXPECT_TRUE(heap.push(std::move(smaller)));
+    EXPECT_EQ(1, *heap.top());
+    EXPECT_EQ(1, heap.size());
+
+    auto bigger = std::make_unique<int>(2);
+    heap.push(std::move(bigger));
+    EXPECT_EQ(2, *heap.top());
+
+    auto biggest = std::make_unique<int>(3);
+    EXPECT_TRUE(heap.push(std::move(biggest)));
+
+    EXPECT_EQ(3, heap.size());
+    // Biggest should be on top.
+    EXPECT_EQ(3, *heap.top());
+
+    biggest = heap.consume_top();
+    EXPECT_EQ(3, *biggest);
+
+    bigger = heap.consume_top();
+    EXPECT_EQ(2, *bigger);
+
+    smaller = heap.consume_top();
+    EXPECT_EQ(1, *smaller);
+
+    EXPECT_TRUE(heap.empty());
+}
+
+TEST(AdjustableMaxPriorityQueueTest, TestChangingItem) {
+    AdjustableMaxPriorityQueue<std::unique_ptr<int>, IntUniquePtrComp> heap;
+    using HeapIterator =
+            AdjustableMaxPriorityQueue<std::unique_ptr<int>, IntUniquePtrComp>::iterator;
+
+    int testValues[] = {1, 2, 3};
+    // Map to save each value's position in the heap.
+    std::unordered_map<int, HeapIterator> itemToIterratorMap;
+
+    // Insert the test values into the heap.
+    for (auto value : testValues) {
+        auto item = std::make_unique<int>(value);
+        EXPECT_TRUE(heap.push(std::move(item)));
+    }
+
+    // Save each value and its pos in the heap into the map.
+    for (HeapIterator iter = heap.begin(); iter != heap.end(); iter++) {
+        itemToIterratorMap[*iter->get()] = iter;
+    }
+
+    // Change the item with value 1 -> 4. And expects the 4 to be the top of the HEAP after that.
+    // After changing, the heap should contain [2,3,4].
+    auto newValue = std::make_unique<int>(4);
+    itemToIterratorMap[1]->swap(newValue);
+    heap.rebuild();
+    EXPECT_EQ(4, *heap.top());
+
+    // Change the item with value 2 -> 5. And expects the 5 to be the top of the HEAP after that.
+    auto newValue2 = std::make_unique<int>(5);
+    itemToIterratorMap[2]->swap(newValue2);
+    heap.rebuild();
+    EXPECT_EQ(5, *heap.top());
+}
+
+TEST(AdjustableMaxPriorityQueueTest, TestErasingItem) {
+    AdjustableMaxPriorityQueue<std::unique_ptr<int>, IntUniquePtrComp> heap;
+    using HeapIterator =
+            AdjustableMaxPriorityQueue<std::unique_ptr<int>, IntUniquePtrComp>::iterator;
+
+    int testValues[] = {1, 2, 3};
+    // Map to save each value's position in the heap.
+    std::unordered_map<int, HeapIterator> itemToIterratorMap;
+
+    // Insert the test values into the heap.
+    for (auto value : testValues) {
+        auto item = std::make_unique<int>(value);
+        EXPECT_TRUE(heap.push(std::move(item)));
+    }
+
+    // Save each value and its pos in the heap into the map.
+    for (HeapIterator iter = heap.begin(); iter != heap.end(); iter++) {
+        itemToIterratorMap[*iter->get()] = iter;
+    }
+
+    // The top of the heap must be 3.
+    EXPECT_EQ(3, *heap.top());
+
+    // Remove 3 and the top of the heap should be 2.
+    heap.erase(itemToIterratorMap[3]);
+    EXPECT_EQ(2, *heap.top());
+
+    // Reset the iter pos in the heap.
+    itemToIterratorMap.clear();
+    for (HeapIterator iter = heap.begin(); iter != heap.end(); iter++) {
+        itemToIterratorMap[*iter->get()] = iter;
+    }
+
+    // Remove 2 and the top of the heap should be 1.
+    heap.erase(itemToIterratorMap[2]);
+    EXPECT_EQ(1, *heap.top());
+
+    // Reset the iter pos in the heap as iterator pos changed after
+    itemToIterratorMap.clear();
+    for (HeapIterator iter = heap.begin(); iter != heap.end(); iter++) {
+        itemToIterratorMap[*iter->get()] = iter;
+    }
+
+    // Remove 1 and the heap should be empty.
+    heap.erase(itemToIterratorMap[1]);
+    EXPECT_TRUE(heap.empty());
+}
+
+// Test the heap property and make sure it is the same as std::priority_queue.
+TEST(AdjustableMaxPriorityQueueTest, TranscodingJobTest) {
+    // Test data structure that mimics the Transcoding job.
+    struct TranscodingJob {
+        int32_t priority;
+        int64_t createTimeUs;
+    };
+
+    // The job is arranging according to priority with highest priority comes first.
+    // For the job with the same priority, the job with early createTime will come first.
+    class TranscodingJobComp {
+       public:
+        bool operator()(const std::unique_ptr<TranscodingJob>& lhs,
+                        const std::unique_ptr<TranscodingJob>& rhs) const {
+            if (lhs->priority != rhs->priority) {
+                return lhs->priority < rhs->priority;
+            }
+            return lhs->createTimeUs > rhs->createTimeUs;
+        }
+    };
+
+    // Map to save each value's position in the heap.
+    std::unordered_map<int, TranscodingJob*> jobIdToJobMap;
+
+    TranscodingJob testJobs[] = {
+            {1 /*priority*/, 66 /*createTimeUs*/},  // First job,
+            {2 /*priority*/, 67 /*createTimeUs*/},  // Second job,
+            {2 /*priority*/, 66 /*createTimeUs*/},  // Third job,
+            {3 /*priority*/, 68 /*createTimeUs*/},  // Fourth job.
+    };
+
+    AdjustableMaxPriorityQueue<std::unique_ptr<TranscodingJob>, TranscodingJobComp> jobQueue;
+
+    // Pushes all the jobs into the heap.
+    for (int jobId = 0; jobId < 4; ++jobId) {
+        auto newJob = std::make_unique<TranscodingJob>(testJobs[jobId]);
+        jobIdToJobMap[jobId] = newJob.get();
+        EXPECT_TRUE(jobQueue.push(std::move(newJob)));
+    }
+
+    // Check the job queue size.
+    EXPECT_EQ(4, jobQueue.size());
+
+    // Check the top and it should be Forth job: (3, 68)
+    const std::unique_ptr<TranscodingJob>& topJob = jobQueue.top();
+    EXPECT_EQ(3, topJob->priority);
+    EXPECT_EQ(68, topJob->createTimeUs);
+
+    // Consume the top.
+    std::unique_ptr<TranscodingJob> consumeJob = jobQueue.consume_top();
+
+    // Check the top and it should be Third Job (2, 66)
+    const std::unique_ptr<TranscodingJob>& topJob2 = jobQueue.top();
+    EXPECT_EQ(2, topJob2->priority);
+    EXPECT_EQ(66, topJob2->createTimeUs);
+
+    // Change the Second job's priority to 4 from (2, 67) -> (4, 67). It should becomes top of the
+    // queue.
+    jobIdToJobMap[1]->priority = 4;
+    jobQueue.rebuild();
+    const std::unique_ptr<TranscodingJob>& topJob3 = jobQueue.top();
+    EXPECT_EQ(4, topJob3->priority);
+    EXPECT_EQ(67, topJob3->createTimeUs);
+}
+}  // namespace android
\ No newline at end of file
diff --git a/media/libmediatranscoding/tests/Android.bp b/media/libmediatranscoding/tests/Android.bp
index f3cc4c5..8191b00 100644
--- a/media/libmediatranscoding/tests/Android.bp
+++ b/media/libmediatranscoding/tests/Android.bp
@@ -35,4 +35,14 @@
     defaults: ["libmediatranscoding_test_defaults"],
 
     srcs: ["TranscodingClientManager_tests.cpp"],
+}
+
+//
+// AdjustableMaxPriorityQueue unit test
+//
+cc_test {
+    name: "AdjustableMaxPriorityQueue_tests",
+    defaults: ["libmediatranscoding_test_defaults"],
+
+    srcs: ["AdjustableMaxPriorityQueue_tests.cpp"],
 }
\ No newline at end of file
diff --git a/media/libmediatranscoding/tests/build_and_run_all_unit_tests.sh b/media/libmediatranscoding/tests/build_and_run_all_unit_tests.sh
index 9832696..d8e4830 100644
--- a/media/libmediatranscoding/tests/build_and_run_all_unit_tests.sh
+++ b/media/libmediatranscoding/tests/build_and_run_all_unit_tests.sh
@@ -21,3 +21,6 @@
 
 echo "testing TranscodingClientManager"
 adb shell /data/nativetest64/TranscodingClientManager_tests/TranscodingClientManager_tests
+
+echo "testing AdjustableMaxPriorityQueue"
+adb shell /data/nativetest64/AdjustableMaxPriorityQueue_tests/AdjustableMaxPriorityQueue_tests
diff --git a/media/libstagefright/MediaTrack.cpp b/media/libstagefright/MediaTrack.cpp
index 89c9b25..24ba38a 100644
--- a/media/libstagefright/MediaTrack.cpp
+++ b/media/libstagefright/MediaTrack.cpp
@@ -183,6 +183,11 @@
             meta.setData(kKeyAudioPresentationInfo,
                     MetaDataBase::Type::TYPE_NONE, valbuf->data(), valbuf->size());
         }
+        if (format->mFormat->findBuffer("csd-0", &valbuf)) {
+            meta.setData(kKeyOpaqueCSD0,
+                    MetaDataBase::Type::TYPE_NONE, valbuf->data(), valbuf->size());
+        }
+
     } else {
         *buffer = nullptr;
     }
diff --git a/media/libstagefright/TEST_MAPPING b/media/libstagefright/TEST_MAPPING
index c1b270c..3c3fff7 100644
--- a/media/libstagefright/TEST_MAPPING
+++ b/media/libstagefright/TEST_MAPPING
@@ -1,10 +1,14 @@
 {
   "postsubmit": [
     {
+      // TODO: move to presubmit once we verify the tests are not flaky
       "name": "CtsMediaTestCases",
       "options": [
         {
-          "include-annotation": "android.platform.test.annotations.RequiresDevice"
+          "include-annotation": "android.platform.test.annotations.Presubmit"
+        },
+        {
+          "exclude-annotation": "android.platform.test.annotations.RequiresDevice"
         }
       ]
     },
diff --git a/media/libstagefright/bqhelper/Android.bp b/media/libstagefright/bqhelper/Android.bp
index 6719bab..f4548ff 100644
--- a/media/libstagefright/bqhelper/Android.bp
+++ b/media/libstagefright/bqhelper/Android.bp
@@ -1,9 +1,5 @@
-cc_library_shared {
-    name: "libstagefright_bufferqueue_helper",
-    vendor_available: true,
-    vndk: {
-        enabled: true,
-    },
+cc_defaults {
+    name: "libstagefright_bufferqueue-defaults",
     double_loadable: true,
     srcs: [
         "FrameDropper.cpp",
@@ -23,7 +19,7 @@
     ],
 
     shared_libs: [
-        "libbinder",
+        "libbase",
         "libcutils",
         "libhidlbase",
         "libhidlmemory",
@@ -33,24 +29,12 @@
         "libutils",
 
         "android.hardware.graphics.bufferqueue@1.0",
-        // Following libs are from libgui_bufferqueue_static
-        "android.hardware.graphics.bufferqueue@2.0",
-        "android.hidl.token@1.0-utils",
-        "libbase",
-        "libEGL",
-        "libnativewindow",
-        "libvndksupport",
-    ],
-    
-    static_libs: [
-        "libgui_bufferqueue_static"
     ],
 
     export_shared_lib_headers: [
         "libhidlmemory",
         "libstagefright_foundation",
         "android.hardware.graphics.bufferqueue@1.0",
-        "android.hardware.graphics.bufferqueue@2.0",
     ],
 
     cflags: [
@@ -68,3 +52,38 @@
         cfi: true,
     },
 }
+
+cc_library_shared {
+    name: "libstagefright_bufferqueue_helper",
+    defaults: ["libstagefright_bufferqueue-defaults"],
+    vendor_available: true,
+    vndk: {
+        enabled: true,
+    },
+    static_libs: [
+        "libgui_bufferqueue_static"
+    ],
+    shared_libs: [
+        "android.hardware.graphics.bufferqueue@2.0",
+        "android.hidl.token@1.0-utils",
+        "libEGL",
+        "libnativewindow",
+        "libvndksupport",
+    ],
+    export_shared_lib_headers: [
+        "android.hardware.graphics.bufferqueue@2.0",
+    ],
+    cflags: [
+        "-DNO_BINDER",
+    ],
+}
+
+cc_library_shared {
+    name: "libstagefright_bufferqueue_helper_client",
+    defaults: ["libstagefright_bufferqueue-defaults"],
+    vendor_available: false,
+    shared_libs: [
+        "libgui"
+    ],
+}
+
diff --git a/media/libstagefright/bqhelper/GraphicBufferSource.cpp b/media/libstagefright/bqhelper/GraphicBufferSource.cpp
index de9d12c..cff14ac 100644
--- a/media/libstagefright/bqhelper/GraphicBufferSource.cpp
+++ b/media/libstagefright/bqhelper/GraphicBufferSource.cpp
@@ -412,7 +412,7 @@
                     B2HGraphicBufferProducer(getIGraphicBufferProducer());
 }
 
-Status GraphicBufferSource::start() {
+status_t GraphicBufferSource::start() {
     Mutex::Autolock autoLock(mMutex);
     ALOGV("--> start; available=%zu, submittable=%zd",
             mAvailableBuffers.size(), mFreeCodecBuffers.size());
@@ -459,10 +459,10 @@
         }
     }
 
-    return Status::ok();
+    return OK;
 }
 
-Status GraphicBufferSource::stop() {
+status_t GraphicBufferSource::stop() {
     ALOGV("stop");
 
     Mutex::Autolock autoLock(mMutex);
@@ -472,10 +472,10 @@
         // not loaded->idle.
         mExecuting = false;
     }
-    return Status::ok();
+    return OK;
 }
 
-Status GraphicBufferSource::release(){
+status_t GraphicBufferSource::release(){
     sp<ALooper> looper;
     {
         Mutex::Autolock autoLock(mMutex);
@@ -501,26 +501,26 @@
     if (looper != NULL) {
         looper->stop();
     }
-    return Status::ok();
+    return OK;
 }
 
-Status GraphicBufferSource::onInputBufferAdded(codec_buffer_id bufferId) {
+status_t GraphicBufferSource::onInputBufferAdded(codec_buffer_id bufferId) {
     Mutex::Autolock autoLock(mMutex);
 
     if (mExecuting) {
         // This should never happen -- buffers can only be allocated when
         // transitioning from "loaded" to "idle".
         ALOGE("addCodecBuffer: buffer added while executing");
-        return Status::fromServiceSpecificError(INVALID_OPERATION);
+        return INVALID_OPERATION;
     }
 
     ALOGV("addCodecBuffer: bufferId=%u", bufferId);
 
     mFreeCodecBuffers.push_back(bufferId);
-    return Status::ok();
+    return OK;
 }
 
-Status GraphicBufferSource::onInputBufferEmptied(codec_buffer_id bufferId, int fenceFd) {
+status_t GraphicBufferSource::onInputBufferEmptied(codec_buffer_id bufferId, int fenceFd) {
     Mutex::Autolock autoLock(mMutex);
     FileDescriptor::Autoclose fence(fenceFd);
 
@@ -528,7 +528,7 @@
     if (cbi < 0) {
         // This should never happen.
         ALOGE("onInputBufferEmptied: buffer not recognized (bufferId=%u)", bufferId);
-        return Status::fromServiceSpecificError(BAD_VALUE);
+        return BAD_VALUE;
     }
 
     std::shared_ptr<AcquiredBuffer> buffer = mSubmittedCodecBuffers.valueAt(cbi);
@@ -548,13 +548,13 @@
             ALOGV("onInputBufferEmptied: EOS null buffer (bufferId=%u@%zd)", bufferId, cbi);
         }
         // No GraphicBuffer to deal with, no additional input or output is expected, so just return.
-        return Status::fromServiceSpecificError(BAD_VALUE);
+        return BAD_VALUE;
     }
 
     if (!mExecuting) {
         // this is fine since this could happen when going from Idle to Loaded
         ALOGV("onInputBufferEmptied: no longer executing (bufferId=%u@%zd)", bufferId, cbi);
-        return Status::fromServiceSpecificError(OK);
+        return OK;
     }
 
     ALOGV("onInputBufferEmptied: bufferId=%d@%zd [slot=%d, useCount=%ld, handle=%p] acquired=%d",
@@ -584,7 +584,7 @@
     }
 
     // releaseReleasableBuffers_l();
-    return Status::ok();
+    return OK;
 }
 
 void GraphicBufferSource::onDataspaceChanged_l(
diff --git a/media/libstagefright/bqhelper/include/media/stagefright/bqhelper/GraphicBufferSource.h b/media/libstagefright/bqhelper/include/media/stagefright/bqhelper/GraphicBufferSource.h
index ed5d7cb..fe6bcce 100644
--- a/media/libstagefright/bqhelper/include/media/stagefright/bqhelper/GraphicBufferSource.h
+++ b/media/libstagefright/bqhelper/include/media/stagefright/bqhelper/GraphicBufferSource.h
@@ -31,8 +31,6 @@
 
 namespace android {
 
-using ::android::binder::Status;
-
 struct FrameDropper;
 class BufferItem;
 class IGraphicBufferProducer;
@@ -99,26 +97,26 @@
     // This is called when component transitions to running state, which means
     // we can start handing it buffers.  If we already have buffers of data
     // sitting in the BufferQueue, this will send them to the codec.
-    Status start();
+    status_t start();
 
     // This is called when component transitions to stopped, indicating that
     // the codec is meant to return all buffers back to the client for them
     // to be freed. Do NOT submit any more buffers to the component.
-    Status stop();
+    status_t stop();
 
     // This is called when component transitions to released, indicating that
     // we are shutting down.
-    Status release();
+    status_t release();
 
     // A "codec buffer", i.e. a buffer that can be used to pass data into
     // the encoder, has been allocated.  (This call does not call back into
     // component.)
-    Status onInputBufferAdded(int32_t bufferId);
+    status_t onInputBufferAdded(int32_t bufferId);
 
     // Called when encoder is no longer using the buffer.  If we have a BQ
     // buffer available, fill it with a new frame of data; otherwise, just mark
     // it as available.
-    Status onInputBufferEmptied(int32_t bufferId, int fenceFd);
+    status_t onInputBufferEmptied(int32_t bufferId, int fenceFd);
 
     // IGraphicBufferSource interface
     // ------------------------------
diff --git a/media/libstagefright/omx/OmxGraphicBufferSource.cpp b/media/libstagefright/omx/OmxGraphicBufferSource.cpp
index 7b187f9..9484046 100644
--- a/media/libstagefright/omx/OmxGraphicBufferSource.cpp
+++ b/media/libstagefright/omx/OmxGraphicBufferSource.cpp
@@ -65,15 +65,18 @@
 }  // namespace
 
 Status OmxGraphicBufferSource::onOmxExecuting() {
-    return start();
+    status_t err = start();
+    return (OK == err) ? Status::ok() : Status::fromServiceSpecificError(err);
 }
 
 Status OmxGraphicBufferSource::onOmxIdle() {
-    return stop();
+    status_t err = stop();
+    return (OK == err) ? Status::ok() : Status::fromServiceSpecificError(err);
 }
 
 Status OmxGraphicBufferSource::onOmxLoaded(){
-    return release();
+    status_t err = release();
+    return (OK == err) ? Status::ok() : Status::fromServiceSpecificError(err);
 }
 
 status_t OmxGraphicBufferSource::configure(
diff --git a/media/libstagefright/tests/writer/AndroidTest.xml b/media/libstagefright/tests/writer/AndroidTest.xml
new file mode 100644
index 0000000..d831555
--- /dev/null
+++ b/media/libstagefright/tests/writer/AndroidTest.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Test module config for writer tests">
+    <option name="test-suite-tag" value="writerTest" />
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push" value="writerTest->/data/local/tmp/writerTest" />
+        <option name="push-file"
+            key="https://storage.googleapis.com/android_media/frameworks/av/media/libstagefright/tests/writer/Writer.zip?unzip=true"
+            value="/data/local/tmp/writerTestRes/" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="writerTest" />
+        <option name="native-test-flag" value="-P /data/local/tmp/writerTestRes/" />
+    </test>
+</configuration>
diff --git a/media/tests/benchmark/MediaBenchmarkTest/AndroidTest.xml b/media/tests/benchmark/MediaBenchmarkTest/AndroidTest.xml
index 1179d6c..1890661 100644
--- a/media/tests/benchmark/MediaBenchmarkTest/AndroidTest.xml
+++ b/media/tests/benchmark/MediaBenchmarkTest/AndroidTest.xml
@@ -14,6 +14,12 @@
      limitations under the License.
 -->
 <configuration description="Runs Media Benchmark Tests">
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push-file"
+            key="https://storage.googleapis.com/android_media/frameworks/av/media/tests/benchmark/MediaBenchmark.zip?unzip=true"
+            value="/data/local/tmp/MediaBenchmark/res/" />
+    </target_preparer>
     <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
         <option name="cleanup-apks" value="false" />
         <option name="test-file-name" value="MediaBenchmarkTest.apk" />
diff --git a/services/camera/libcameraservice/Android.bp b/services/camera/libcameraservice/Android.bp
index 883eb37..501d922 100644
--- a/services/camera/libcameraservice/Android.bp
+++ b/services/camera/libcameraservice/Android.bp
@@ -116,6 +116,7 @@
         "libyuv",
         "android.frameworks.cameraservice.common@2.0",
         "android.frameworks.cameraservice.service@2.0",
+        "android.frameworks.cameraservice.service@2.1",
         "android.frameworks.cameraservice.device@2.0",
         "android.hardware.camera.common@1.0",
         "android.hardware.camera.provider@2.4",
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 515ef32..453984e 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -457,10 +457,14 @@
     }
 
     if (updated) {
-        logDeviceRemoved(id, String8::format("Device %s-%s availability changed from %d to %d",
-                id.string(), physicalId.string(),
-                newStatus != StatusInternal::PRESENT,
-                newStatus == StatusInternal::PRESENT));
+        String8 idCombo = id + " : " + physicalId;
+        if (newStatus == StatusInternal::PRESENT) {
+            logDeviceAdded(idCombo,
+                    String8::format("Device status changed to %d", newStatus));
+        } else {
+            logDeviceRemoved(idCombo,
+                    String8::format("Device status changed to %d", newStatus));
+        }
 
         String16 id16(id), physicalId16(physicalId);
         Mutex::Autolock lock(mStatusListenerLock);
diff --git a/services/camera/libcameraservice/hidl/AidlCameraServiceListener.cpp b/services/camera/libcameraservice/hidl/AidlCameraServiceListener.cpp
index 110ef8e..8e619e1 100644
--- a/services/camera/libcameraservice/hidl/AidlCameraServiceListener.cpp
+++ b/services/camera/libcameraservice/hidl/AidlCameraServiceListener.cpp
@@ -25,6 +25,7 @@
 namespace implementation {
 
 using hardware::cameraservice::utils::conversion::convertToHidlCameraDeviceStatus;
+typedef frameworks::cameraservice::service::V2_1::ICameraServiceListener HCameraServiceListener2_1;
 
 binder::Status H2BCameraServiceListener::onStatusChanged(
     int32_t status, const ::android::String16& cameraId) {
@@ -40,6 +41,29 @@
   return binder::Status::ok();
 }
 
+binder::Status H2BCameraServiceListener::onPhysicalCameraStatusChanged(
+    int32_t status, const ::android::String16& cameraId,
+    const ::android::String16& physicalCameraId) {
+  auto cast2_1 = HCameraServiceListener2_1::castFrom(mBase);
+  sp<HCameraServiceListener2_1> interface2_1 = nullptr;
+  if (cast2_1.isOk()) {
+    interface2_1 = cast2_1;
+    if (interface2_1 != nullptr) {
+      HCameraDeviceStatus hCameraDeviceStatus = convertToHidlCameraDeviceStatus(status);
+      V2_1::PhysicalCameraStatusAndId cameraStatusAndId;
+      cameraStatusAndId.deviceStatus = hCameraDeviceStatus;
+      cameraStatusAndId.cameraId = String8(cameraId).string();
+      cameraStatusAndId.physicalCameraId = String8(physicalCameraId).string();
+      auto ret = interface2_1->onPhysicalCameraStatusChanged(cameraStatusAndId);
+      if (!ret.isOk()) {
+        ALOGE("%s OnPhysicalCameraStatusChanged callback failed due to %s",__FUNCTION__,
+            ret.description().c_str());
+      }
+    }
+  }
+  return binder::Status::ok();
+}
+
 ::android::binder::Status H2BCameraServiceListener::onTorchStatusChanged(
     int32_t, const ::android::String16&) {
   // We don't implement onTorchStatusChanged
diff --git a/services/camera/libcameraservice/hidl/AidlCameraServiceListener.h b/services/camera/libcameraservice/hidl/AidlCameraServiceListener.h
index 175eb8e..95493a1 100644
--- a/services/camera/libcameraservice/hidl/AidlCameraServiceListener.h
+++ b/services/camera/libcameraservice/hidl/AidlCameraServiceListener.h
@@ -19,6 +19,7 @@
 
 #include <android/frameworks/cameraservice/common/2.0/types.h>
 #include <android/frameworks/cameraservice/service/2.0/ICameraServiceListener.h>
+#include <android/frameworks/cameraservice/service/2.1/ICameraServiceListener.h>
 #include <android/frameworks/cameraservice/device/2.0/types.h>
 #include <android/hardware/BnCameraServiceListener.h>
 #include <android/hardware/BpCameraServiceListener.h>
@@ -47,17 +48,14 @@
 
     virtual ::android::binder::Status onStatusChanged(int32_t status,
             const ::android::String16& cameraId) override;
-    virtual ::android::binder::Status onPhysicalCameraStatusChanged(int32_t /*status*/,
-            const ::android::String16& /*cameraId*/,
-            const ::android::String16& /*physicalCameraId*/) override {
-        // no implementation yet.
-        return binder::Status::ok();
-    }
+    virtual ::android::binder::Status onPhysicalCameraStatusChanged(int32_t status,
+            const ::android::String16& cameraId,
+            const ::android::String16& physicalCameraId) override;
 
     virtual ::android::binder::Status onTorchStatusChanged(
             int32_t status, const ::android::String16& cameraId) override;
     virtual binder::Status onCameraAccessPrioritiesChanged() {
-        // TODO: no implementation yet. b/148146086
+        // TODO: no implementation yet.
         return binder::Status::ok();
     }
 };
diff --git a/services/camera/libcameraservice/hidl/Convert.cpp b/services/camera/libcameraservice/hidl/Convert.cpp
index 866c3b5..597147b 100644
--- a/services/camera/libcameraservice/hidl/Convert.cpp
+++ b/services/camera/libcameraservice/hidl/Convert.cpp
@@ -197,6 +197,23 @@
     return;
 }
 
+void convertToHidl(const std::vector<hardware::CameraStatus> &src,
+                   hidl_vec<frameworks::cameraservice::service::V2_1::CameraStatusAndId>* dst) {
+    dst->resize(src.size());
+    size_t i = 0;
+    for (const auto &statusAndId : src) {
+        auto &a = (*dst)[i++];
+        a.v2_0.cameraId = statusAndId.cameraId.c_str();
+        a.v2_0.deviceStatus = convertToHidlCameraDeviceStatus(statusAndId.status);
+        size_t numUnvailPhysicalCameras = statusAndId.unavailablePhysicalIds.size();
+        a.unavailPhysicalCameraIds.resize(numUnvailPhysicalCameras);
+        for (size_t j = 0; j < numUnvailPhysicalCameras; j++) {
+            a.unavailPhysicalCameraIds[j] = statusAndId.unavailablePhysicalIds[j].c_str();
+        }
+    }
+    return;
+}
+
 void convertToHidl(
     const hardware::camera2::utils::SubmitInfo &submitInfo,
     frameworks::cameraservice::device::V2_0::SubmitInfo *hSubmitInfo) {
diff --git a/services/camera/libcameraservice/hidl/Convert.h b/services/camera/libcameraservice/hidl/Convert.h
index 79683f6..82ffc48 100644
--- a/services/camera/libcameraservice/hidl/Convert.h
+++ b/services/camera/libcameraservice/hidl/Convert.h
@@ -23,6 +23,7 @@
 #include <android/frameworks/cameraservice/device/2.0/ICameraDeviceUser.h>
 #include <android/frameworks/cameraservice/common/2.0/types.h>
 #include <android/frameworks/cameraservice/service/2.0/types.h>
+#include <android/frameworks/cameraservice/service/2.1/types.h>
 #include <android/frameworks/cameraservice/device/2.0/types.h>
 #include <android/hardware/camera/common/1.0/types.h>
 #include <android/hardware/camera2/ICameraDeviceUser.h>
@@ -79,6 +80,9 @@
 void convertToHidl(const std::vector<hardware::CameraStatus> &src,
                    hidl_vec<HCameraStatusAndId>* dst);
 
+void convertToHidl(const std::vector<hardware::CameraStatus> &src,
+                   hidl_vec<frameworks::cameraservice::service::V2_1::CameraStatusAndId>* dst);
+
 void convertToHidl(const hardware::camera2::utils::SubmitInfo &submitInfo,
                    HSubmitInfo *hSubmitInfo);
 
diff --git a/services/camera/libcameraservice/hidl/HidlCameraService.cpp b/services/camera/libcameraservice/hidl/HidlCameraService.cpp
index 97ba9c4..a46133e 100644
--- a/services/camera/libcameraservice/hidl/HidlCameraService.cpp
+++ b/services/camera/libcameraservice/hidl/HidlCameraService.cpp
@@ -154,15 +154,50 @@
 
 Return<void> HidlCameraService::addListener(const sp<HCameraServiceListener>& hCsListener,
                                             addListener_cb _hidl_cb) {
-    if (mAidlICameraService == nullptr) {
-        _hidl_cb(HStatus::UNKNOWN_ERROR, {});
+    std::vector<hardware::CameraStatus> cameraStatusAndIds{};
+    HStatus status = addListenerInternal<HCameraServiceListener>(
+            hCsListener, &cameraStatusAndIds);
+    if (status != HStatus::NO_ERROR) {
+        _hidl_cb(status, {});
         return Void();
     }
-    if (hCsListener == nullptr) {
-        ALOGE("%s listener must not be NULL", __FUNCTION__);
-        _hidl_cb(HStatus::ILLEGAL_ARGUMENT, {});
+
+    hidl_vec<HCameraStatusAndId> hCameraStatusAndIds;
+    //Convert cameraStatusAndIds to HIDL and call callback
+    convertToHidl(cameraStatusAndIds, &hCameraStatusAndIds);
+    _hidl_cb(status, hCameraStatusAndIds);
+
+    return Void();
+}
+
+Return<void> HidlCameraService::addListener_2_1(const sp<HCameraServiceListener2_1>& hCsListener,
+                                                addListener_2_1_cb _hidl_cb) {
+    std::vector<hardware::CameraStatus> cameraStatusAndIds{};
+    HStatus status = addListenerInternal<HCameraServiceListener2_1>(
+            hCsListener, &cameraStatusAndIds);
+    if (status != HStatus::NO_ERROR) {
+        _hidl_cb(status, {});
         return Void();
     }
+
+    hidl_vec<frameworks::cameraservice::service::V2_1::CameraStatusAndId> hCameraStatusAndIds;
+    //Convert cameraStatusAndIds to HIDL and call callback
+    convertToHidl(cameraStatusAndIds, &hCameraStatusAndIds);
+    _hidl_cb(status, hCameraStatusAndIds);
+
+    return Void();
+}
+
+template<class T>
+HStatus HidlCameraService::addListenerInternal(const sp<T>& hCsListener,
+        std::vector<hardware::CameraStatus>* cameraStatusAndIds) {
+    if (mAidlICameraService == nullptr) {
+        return HStatus::UNKNOWN_ERROR;
+    }
+    if (hCsListener == nullptr || cameraStatusAndIds == nullptr) {
+        ALOGE("%s listener and cameraStatusAndIds must not be NULL", __FUNCTION__);
+        return HStatus::ILLEGAL_ARGUMENT;
+    }
     sp<hardware::ICameraServiceListener> csListener = nullptr;
     // Check the cache for previously registered callbacks
     {
@@ -177,33 +212,27 @@
         } else {
             ALOGE("%s: Trying to add a listener %p already registered",
                   __FUNCTION__, hCsListener.get());
-            _hidl_cb(HStatus::ILLEGAL_ARGUMENT, {});
-            return Void();
+            return HStatus::ILLEGAL_ARGUMENT;
         }
     }
-    std::vector<hardware::CameraStatus> cameraStatusAndIds{};
     binder::Status serviceRet =
-        mAidlICameraService->addListenerHelper(csListener, &cameraStatusAndIds, true);
+            mAidlICameraService->addListenerHelper(csListener, cameraStatusAndIds, true);
     HStatus status = HStatus::NO_ERROR;
     if (!serviceRet.isOk()) {
-      ALOGE("%s: Unable to add camera device status listener", __FUNCTION__);
-      status = B2HStatus(serviceRet);
-      _hidl_cb(status, {});
-      return Void();
+        ALOGE("%s: Unable to add camera device status listener", __FUNCTION__);
+        status = B2HStatus(serviceRet);
+        return status;
     }
-    cameraStatusAndIds.erase(std::remove_if(cameraStatusAndIds.begin(), cameraStatusAndIds.end(),
+    cameraStatusAndIds->erase(std::remove_if(cameraStatusAndIds->begin(), cameraStatusAndIds->end(),
             [this](const hardware::CameraStatus& s) {
-              bool supportsHAL3 = false;
-              binder::Status sRet =
+                bool supportsHAL3 = false;
+                binder::Status sRet =
                             mAidlICameraService->supportsCameraApi(String16(s.cameraId),
                                     hardware::ICameraService::API_VERSION_2, &supportsHAL3);
-              return !sRet.isOk() || !supportsHAL3;
-            }), cameraStatusAndIds.end());
-    hidl_vec<HCameraStatusAndId> hCameraStatusAndIds;
-    //Convert cameraStatusAndIds to HIDL and call callback
-    convertToHidl(cameraStatusAndIds, &hCameraStatusAndIds);
-    _hidl_cb(status, hCameraStatusAndIds);
-    return Void();
+                return !sRet.isOk() || !supportsHAL3;
+            }), cameraStatusAndIds->end());
+
+    return HStatus::NO_ERROR;
 }
 
 Return<HStatus> HidlCameraService::removeListener(const sp<HCameraServiceListener>& hCsListener) {
diff --git a/services/camera/libcameraservice/hidl/HidlCameraService.h b/services/camera/libcameraservice/hidl/HidlCameraService.h
index eead0bc..097f4c5 100644
--- a/services/camera/libcameraservice/hidl/HidlCameraService.h
+++ b/services/camera/libcameraservice/hidl/HidlCameraService.h
@@ -21,7 +21,7 @@
 #include <thread>
 
 #include <android/frameworks/cameraservice/common/2.0/types.h>
-#include <android/frameworks/cameraservice/service/2.0/ICameraService.h>
+#include <android/frameworks/cameraservice/service/2.1/ICameraService.h>
 #include <android/frameworks/cameraservice/service/2.0/types.h>
 #include <android/frameworks/cameraservice/device/2.0/types.h>
 
@@ -42,8 +42,9 @@
 
 using HCameraDeviceCallback = frameworks::cameraservice::device::V2_0::ICameraDeviceCallback;
 using HCameraMetadata = frameworks::cameraservice::service::V2_0::CameraMetadata;
-using HCameraService = frameworks::cameraservice::service::V2_0::ICameraService;
+using HCameraService = frameworks::cameraservice::service::V2_1::ICameraService;
 using HCameraServiceListener = frameworks::cameraservice::service::V2_0::ICameraServiceListener;
+using HCameraServiceListener2_1 = frameworks::cameraservice::service::V2_1::ICameraServiceListener;
 using HStatus = frameworks::cameraservice::common::V2_0::Status;
 using HCameraStatusAndId = frameworks::cameraservice::service::V2_0::CameraStatusAndId;
 
@@ -66,6 +67,9 @@
 
     Return<void> getCameraVendorTagSections(getCameraVendorTagSections_cb _hidl_cb) override;
 
+    Return<void> addListener_2_1(const sp<HCameraServiceListener2_1>& listener,
+                                 addListener_2_1_cb _hidl_cb) override;
+
     // This method should only be called by the cameraservers main thread to
     // instantiate the hidl cameraserver.
     static sp<HidlCameraService> getInstance(android::CameraService *cs);
@@ -76,6 +80,11 @@
     sp<hardware::ICameraServiceListener> searchListenerCacheLocked(
         sp<HCameraServiceListener> listener, /*removeIfFound*/ bool shouldRemove = false);
 
+
+    template<class T>
+    HStatus addListenerInternal(const sp<T>& listener,
+                                std::vector<hardware::CameraStatus>* cameraStatusAndIds);
+
     void addToListenerCacheLocked(sp<HCameraServiceListener> hListener,
                                   sp<hardware::ICameraServiceListener> csListener);