Merge "Change class and variable names"
diff --git a/CleanSpec.mk b/CleanSpec.mk
index fa711ca..1af439a 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -71,3 +71,4 @@
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/etc/init/android.hardware.configstore@1.1-service.rc)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/bin/hw/android.hardware.cas@1.0*)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/etc/init/android.hardware.cas@1.0*)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/etc/vintf/manifest/android.hardware.cas@1.0*)
diff --git a/OWNERS b/OWNERS
index 9fbcb47..1d7a8e1 100644
--- a/OWNERS
+++ b/OWNERS
@@ -3,3 +3,4 @@
 malchev@google.com
 smoreland@google.com
 yim@google.com  # vts tests
+guangzhu@google.com # vts tests
diff --git a/audio/5.0/Android.bp b/audio/5.0/Android.bp
index 3586b8e..7c2db1d 100644
--- a/audio/5.0/Android.bp
+++ b/audio/5.0/Android.bp
@@ -30,6 +30,7 @@
         "AudioMicrophoneDirectionality",
         "AudioMicrophoneLocation",
         "MessageQueueFlagBits",
+        "MicrophoneDirection",
         "MicrophoneInfo",
         "MmapBufferFlag",
         "MmapBufferInfo",
diff --git a/automotive/evs/1.0/IEvsEnumerator.hal b/automotive/evs/1.0/IEvsEnumerator.hal
index e1193d0..ee51e7e 100644
--- a/automotive/evs/1.0/IEvsEnumerator.hal
+++ b/automotive/evs/1.0/IEvsEnumerator.hal
@@ -57,7 +57,8 @@
      *
      * There can be at most one EVS display object for the system and this function
      * requests access to it. If the EVS display is not available or is already in use,
-     * a null pointer is returned.
+     * the old instance shall be closed and give the new caller exclusive
+     * access.
      * When done using the display, the caller may release it by calling closeDisplay().
      * TODO(b/36122635) Reliance on the sp<> going out of scope is not recommended because the
      * resources may not be released right away due to asynchronos behavior in the hardware binder.
diff --git a/biometrics/face/1.0/Android.bp b/biometrics/face/1.0/Android.bp
index 45dbad9..0f8c6e6 100644
--- a/biometrics/face/1.0/Android.bp
+++ b/biometrics/face/1.0/Android.bp
@@ -17,6 +17,7 @@
     types: [
         "FaceAcquiredInfo",
         "FaceError",
+        "Feature",
         "OptionalBool",
         "OptionalUint64",
         "Status",
diff --git a/biometrics/face/1.0/IBiometricsFace.hal b/biometrics/face/1.0/IBiometricsFace.hal
index 813f040..0499c5d 100644
--- a/biometrics/face/1.0/IBiometricsFace.hal
+++ b/biometrics/face/1.0/IBiometricsFace.hal
@@ -242,8 +242,10 @@
      * Reset lockout for the current user.
      *
      * @param hat A valid Hardware Authentication Token, generated when the
-     *     user authenticates with Pin/Pattern/Pass.
-     * @return true if lockout was reset, false otherwise.
+     *     user authenticates with Pin/Pattern/Pass. When the Hardware
+     *     Authentication Token is verified, lockout must be reset and
+     *     onLockoutChanged must be called with duration 0.
+     * @return status The status of this method call.
      */
-    resetLockout(vec<uint8_t> hat) generates (bool success);
+    resetLockout(vec<uint8_t> hat) generates (Status status);
 };
diff --git a/biometrics/face/1.0/IBiometricsFaceClientCallback.hal b/biometrics/face/1.0/IBiometricsFaceClientCallback.hal
index 93848c5..c9dd0e2 100644
--- a/biometrics/face/1.0/IBiometricsFaceClientCallback.hal
+++ b/biometrics/face/1.0/IBiometricsFaceClientCallback.hal
@@ -113,4 +113,19 @@
      */
     oneway onEnumerate(uint64_t deviceId, vec<uint32_t> faceIds,
         int32_t userId);
+
+    /**
+     * A callback invoked when the lockout state changes.
+     *
+     * This method must only be invoked when setActiveUser() is called,
+     * when lockout starts, and when lockout ends. When lockout starts,
+     * duration must be greater than 0, and when lockout ends, duration must
+     * be 0. This must be called before calling onError() with parameters
+     * LOCKOUT or LOCKOUT_PERMANENT. If the user is permanently locked out,
+     * the duration must be MAX_UINT64.
+     *
+     * @param duration the remaining lockout duration in milliseconds, or 0
+     *     if the user is not locked out.
+     */
+    oneway onLockoutChanged(uint64_t duration);
 };
diff --git a/bluetooth/audio/2.0/Android.bp b/bluetooth/audio/2.0/Android.bp
index 542c812..e72b6ab 100644
--- a/bluetooth/audio/2.0/Android.bp
+++ b/bluetooth/audio/2.0/Android.bp
@@ -15,6 +15,7 @@
     interfaces: [
         "android.hardware.audio.common@5.0",
         "android.hidl.base@1.0",
+        "android.hidl.safe_union@1.0",
     ],
     types: [
         "AacObjectType",
diff --git a/camera/common/1.0/default/CameraModule.cpp b/camera/common/1.0/default/CameraModule.cpp
index 08354b3..467c121 100644
--- a/camera/common/1.0/default/CameraModule.cpp
+++ b/camera/common/1.0/default/CameraModule.cpp
@@ -253,6 +253,14 @@
         }
         mCameraInfoMap.removeItemsAt(0);
     }
+
+    while (mPhysicalCameraInfoMap.size() > 0) {
+        camera_metadata_t* metadata = mPhysicalCameraInfoMap.editValueAt(0);
+        if (metadata != NULL) {
+            free_camera_metadata(metadata);
+        }
+        mPhysicalCameraInfoMap.removeItemsAt(0);
+    }
 }
 
 int CameraModule::init() {
@@ -351,7 +359,14 @@
             return ret;
         }
 
-        index = mPhysicalCameraInfoMap.add(physicalCameraId, info);
+        // The camera_metadata_t returned by get_physical_camera_info could be using
+        // more memory than necessary due to unused reserved space. Reduce the
+        // size by appending it to a new CameraMetadata object, which internally
+        // calls resizeIfNeeded.
+        CameraMetadata m;
+        m.append(info);
+        camera_metadata_t* derivedMetadata = m.release();
+        index = mPhysicalCameraInfoMap.add(physicalCameraId, derivedMetadata);
     }
 
     assert(index != NAME_NOT_FOUND);
@@ -462,6 +477,54 @@
     return res;
 }
 
+void CameraModule::notifyDeviceStateChange(uint64_t deviceState) {
+   if (getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_5 &&
+           mModule->notify_device_state_change != NULL) {
+       ATRACE_BEGIN("camera_module->notify_device_state_change");
+       ALOGI("%s: calling notify_device_state_change with state %" PRId64, __FUNCTION__,
+               deviceState);
+       mModule->notify_device_state_change(deviceState);
+       ATRACE_END();
+   }
+}
+
+bool CameraModule::isLogicalMultiCamera(
+        const common::V1_0::helper::CameraMetadata& metadata,
+        std::unordered_set<std::string>* physicalCameraIds) {
+    if (physicalCameraIds == nullptr) {
+        ALOGE("%s: physicalCameraIds must not be null", __FUNCTION__);
+        return false;
+    }
+
+    bool isLogicalMultiCamera = false;
+    camera_metadata_ro_entry_t capabilities =
+            metadata.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
+    for (size_t i = 0; i < capabilities.count; i++) {
+        if (capabilities.data.u8[i] ==
+                ANDROID_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA) {
+            isLogicalMultiCamera = true;
+            break;
+        }
+    }
+
+    if (isLogicalMultiCamera) {
+        camera_metadata_ro_entry_t entry =
+                metadata.find(ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS);
+        const uint8_t* ids = entry.data.u8;
+        size_t start = 0;
+        for (size_t i = 0; i < entry.count; ++i) {
+            if (ids[i] == '\0') {
+                if (start != i) {
+                    const char* physicalId = reinterpret_cast<const char*>(ids+start);
+                    physicalCameraIds->emplace(physicalId);
+                }
+                start = i + 1;
+            }
+        }
+    }
+    return isLogicalMultiCamera;
+}
+
 status_t CameraModule::filterOpenErrorCode(status_t err) {
     switch(err) {
         case NO_ERROR:
@@ -476,8 +539,24 @@
 }
 
 void CameraModule::removeCamera(int cameraId) {
-    free_camera_metadata(const_cast<camera_metadata_t*>(
-        mCameraInfoMap.valueFor(cameraId).static_camera_characteristics));
+    std::unordered_set<std::string> physicalIds;
+    camera_metadata_t *metadata = const_cast<camera_metadata_t*>(
+            mCameraInfoMap.valueFor(cameraId).static_camera_characteristics);
+    common::V1_0::helper::CameraMetadata hidlMetadata(metadata);
+
+    if (isLogicalMultiCamera(hidlMetadata, &physicalIds)) {
+        for (const auto& id : physicalIds) {
+            int idInt = std::stoi(id);
+            if (mPhysicalCameraInfoMap.indexOfKey(idInt) >= 0) {
+                free_camera_metadata(mPhysicalCameraInfoMap[idInt]);
+                mPhysicalCameraInfoMap.removeItem(idInt);
+            } else {
+                ALOGE("%s: Cannot find corresponding static metadata for physical id %s",
+                        __FUNCTION__, id.c_str());
+            }
+        }
+    }
+    free_camera_metadata(metadata);
     mCameraInfoMap.removeItem(cameraId);
     mDeviceVersionMap.removeItem(cameraId);
 }
diff --git a/camera/common/1.0/default/include/CameraModule.h b/camera/common/1.0/default/include/CameraModule.h
index ee75e72..c89e934 100644
--- a/camera/common/1.0/default/include/CameraModule.h
+++ b/camera/common/1.0/default/include/CameraModule.h
@@ -17,6 +17,9 @@
 #ifndef CAMERA_COMMON_1_0_CAMERAMODULE_H
 #define CAMERA_COMMON_1_0_CAMERAMODULE_H
 
+#include <string>
+#include <unordered_set>
+
 #include <hardware/camera.h>
 #include <utils/Mutex.h>
 #include <utils/KeyedVector.h>
@@ -67,6 +70,11 @@
     void removeCamera(int cameraId);
     int getPhysicalCameraInfo(int physicalCameraId, camera_metadata_t **physicalInfo);
     int isStreamCombinationSupported(int cameraId, camera_stream_combination_t *streams);
+    void notifyDeviceStateChange(uint64_t deviceState);
+
+    static bool isLogicalMultiCamera(
+            const common::V1_0::helper::CameraMetadata& metadata,
+            std::unordered_set<std::string>* physicalCameraIds);
 
 private:
     // Derive camera characteristics keys defined after HAL device version
diff --git a/camera/device/3.4/default/CameraDeviceSession.cpp b/camera/device/3.4/default/CameraDeviceSession.cpp
index e52577c..c937834 100644
--- a/camera/device/3.4/default/CameraDeviceSession.cpp
+++ b/camera/device/3.4/default/CameraDeviceSession.cpp
@@ -22,6 +22,7 @@
 #include <hardware/gralloc.h>
 #include <hardware/gralloc1.h>
 #include "CameraDeviceSession.h"
+#include "CameraModule.h"
 
 namespace android {
 namespace hardware {
@@ -30,6 +31,8 @@
 namespace V3_4 {
 namespace implementation {
 
+using ::android::hardware::camera::common::V1_0::helper::CameraModule;
+
 CameraDeviceSession::CameraDeviceSession(
     camera3_device_t* device,
     const camera_metadata_t* deviceInfo,
@@ -54,31 +57,9 @@
 
     mResultBatcher_3_4.setNumPartialResults(mNumPartialResults);
 
-    camera_metadata_entry_t capabilities =
-            mDeviceInfo.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
-    bool isLogicalMultiCamera = false;
-    for (size_t i = 0; i < capabilities.count; i++) {
-        if (capabilities.data.u8[i] ==
-                ANDROID_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA) {
-            isLogicalMultiCamera = true;
-            break;
-        }
-    }
-    if (isLogicalMultiCamera) {
-        camera_metadata_entry entry =
-                mDeviceInfo.find(ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS);
-        const uint8_t* ids = entry.data.u8;
-        size_t start = 0;
-        for (size_t i = 0; i < entry.count; ++i) {
-            if (ids[i] == '\0') {
-                if (start != i) {
-                    const char* physicalId = reinterpret_cast<const char*>(ids+start);
-                    mPhysicalCameraIds.emplace(physicalId);
-                }
-                start = i + 1;
-            }
-        }
-    }
+    // Parse and store current logical camera's physical ids.
+    (void)CameraModule::isLogicalMultiCamera(mDeviceInfo, &mPhysicalCameraIds);
+
 }
 
 CameraDeviceSession::~CameraDeviceSession() {
diff --git a/camera/device/3.5/Android.bp b/camera/device/3.5/Android.bp
index 2a9ba05..6d18367 100644
--- a/camera/device/3.5/Android.bp
+++ b/camera/device/3.5/Android.bp
@@ -23,6 +23,8 @@
     types: [
         "BufferRequest",
         "BufferRequestStatus",
+        "CameraBlob",
+        "CameraBlobId",
         "StreamBufferRequestError",
         "StreamBufferRet",
         "StreamBuffersVal",
diff --git a/camera/device/3.5/ICameraDeviceSession.hal b/camera/device/3.5/ICameraDeviceSession.hal
index b2b71cd..d0cfe39 100644
--- a/camera/device/3.5/ICameraDeviceSession.hal
+++ b/camera/device/3.5/ICameraDeviceSession.hal
@@ -17,6 +17,7 @@
 package android.hardware.camera.device@3.5;
 
 import android.hardware.camera.common@1.0::Status;
+import @3.2::CameraMetadata;
 import @3.4::ICameraDeviceSession;
 import @3.4::HalStreamConfiguration;
 
@@ -99,4 +100,49 @@
         vec<int32_t> streamIds,
         uint32_t streamConfigCounter
     );
+
+    /**
+     * isReconfigurationRequired:
+     *
+     * Check whether complete stream reconfiguration is required for possible new session
+     * parameter values.
+     *
+     * This method must be called by the camera framework in case the client changes
+     * the value of any advertised session parameters. Depending on the specific values
+     * the HAL can decide whether a complete stream reconfiguration is required. In case
+     * the HAL returns false, the camera framework must skip the internal reconfiguration.
+     * In case Hal returns true, the framework must reconfigure the streams and pass the
+     * new session parameter values accordingly.
+     * This call may be done by the framework some time before the request with new parameters
+     * is submitted to the HAL, and the request may be cancelled before it ever gets submitted.
+     * Therefore, the HAL must not use this query as an indication to change its behavior in any
+     * way.
+     * ------------------------------------------------------------------------
+     *
+     * Preconditions:
+     *
+     * The framework can call this method at any time after active
+     * session configuration. There must be no impact on the performance of
+     * pending camera requests in any way. In particular there must not be
+     * any glitches or delays during normal camera streaming.
+     *
+     * Performance requirements:
+     * HW and SW camera settings must not be changed and there must not be
+     * a user-visible impact on camera performance.
+     *
+     * @param oldSessionParams Before session parameters, usually the current session parameters.
+     * @param newSessionParams The new session parameters which may be set by client.
+     *
+     * @return Status Status code for the operation, one of:
+     *     OK:
+     *          On successful reconfiguration required query.
+     *     METHOD_NOT_SUPPORTED:
+     *          The camera device does not support the reconfiguration query.
+     *     INTERNAL_ERROR:
+     *          The reconfiguration query cannot complete due to internal
+     *          error.
+     * @return true in case the stream reconfiguration is required, false otherwise.
+     */
+    isReconfigurationRequired(CameraMetadata oldSessionParams, CameraMetadata newSessionParams)
+            generates(Status status, bool reconfigurationNeeded);
 };
diff --git a/camera/device/3.5/default/CameraDeviceSession.cpp b/camera/device/3.5/default/CameraDeviceSession.cpp
index 0770f04..d9c6eef 100644
--- a/camera/device/3.5/default/CameraDeviceSession.cpp
+++ b/camera/device/3.5/default/CameraDeviceSession.cpp
@@ -356,6 +356,35 @@
     d->returnStreamBuffers(num_buffers, buffers);
 }
 
+Return<void> CameraDeviceSession::isReconfigurationRequired(
+        const V3_2::CameraMetadata& oldSessionParams, const V3_2::CameraMetadata& newSessionParams,
+        ICameraDeviceSession::isReconfigurationRequired_cb _hidl_cb) {
+    if (mDevice->ops->is_reconfiguration_required != nullptr) {
+        const camera_metadata_t *oldParams, *newParams;
+        V3_2::implementation::convertFromHidl(oldSessionParams, &oldParams);
+        V3_2::implementation::convertFromHidl(newSessionParams, &newParams);
+        auto ret = mDevice->ops->is_reconfiguration_required(mDevice, oldParams, newParams);
+        switch (ret) {
+            case 0:
+                _hidl_cb(Status::OK, true);
+                break;
+            case -EINVAL:
+                _hidl_cb(Status::OK, false);
+                break;
+            case -ENOSYS:
+                _hidl_cb(Status::METHOD_NOT_SUPPORTED, true);
+                break;
+            default:
+                _hidl_cb(Status::INTERNAL_ERROR, true);
+                break;
+        };
+    } else {
+        _hidl_cb(Status::METHOD_NOT_SUPPORTED, true);
+    }
+
+    return Void();
+}
+
 } // namespace implementation
 }  // namespace V3_5
 }  // namespace device
diff --git a/camera/device/3.5/default/ExternalCameraDeviceSession.cpp b/camera/device/3.5/default/ExternalCameraDeviceSession.cpp
index ae7c45e..00c1d0d 100644
--- a/camera/device/3.5/default/ExternalCameraDeviceSession.cpp
+++ b/camera/device/3.5/default/ExternalCameraDeviceSession.cpp
@@ -295,6 +295,15 @@
     return 0;
 }
 
+Return<void> ExternalCameraDeviceSession::isReconfigurationRequired(
+        const V3_2::CameraMetadata& /*oldSessionParams*/,
+        const V3_2::CameraMetadata& /*newSessionParams*/,
+        ICameraDeviceSession::isReconfigurationRequired_cb _hidl_cb) {
+    //Stub implementation
+    _hidl_cb(Status::OK, true);
+    return Void();
+}
+
 } // namespace implementation
 }  // namespace V3_5
 }  // namespace device
diff --git a/camera/device/3.5/default/include/device_v3_5_impl/CameraDeviceSession.h b/camera/device/3.5/default/include/device_v3_5_impl/CameraDeviceSession.h
index 4f7284c..87d616c 100644
--- a/camera/device/3.5/default/include/device_v3_5_impl/CameraDeviceSession.h
+++ b/camera/device/3.5/default/include/device_v3_5_impl/CameraDeviceSession.h
@@ -93,6 +93,9 @@
             hidl_vec<buffer_handle_t*>& allBufPtrs,
             hidl_vec<int>& allFences) override;
 
+    Return<void> isReconfigurationRequired(const V3_2::CameraMetadata& oldSessionParams,
+            const V3_2::CameraMetadata& newSessionParams,
+            ICameraDeviceSession::isReconfigurationRequired_cb _hidl_cb);
     /**
      * Static callback forwarding methods from HAL to instance
      */
@@ -238,6 +241,11 @@
             return mParent->signalStreamFlush(requests, streamConfigCounter);
         }
 
+        virtual Return<void> isReconfigurationRequired(const V3_2::CameraMetadata& oldSessionParams,
+                const V3_2::CameraMetadata& newSessionParams,
+                ICameraDeviceSession::isReconfigurationRequired_cb _hidl_cb) override {
+            return mParent->isReconfigurationRequired(oldSessionParams, newSessionParams, _hidl_cb);
+        }
     private:
         sp<CameraDeviceSession> mParent;
     };
diff --git a/camera/device/3.5/default/include/ext_device_v3_5_impl/ExternalCameraDeviceSession.h b/camera/device/3.5/default/include/ext_device_v3_5_impl/ExternalCameraDeviceSession.h
index aa119fc..d2b5e89 100644
--- a/camera/device/3.5/default/include/ext_device_v3_5_impl/ExternalCameraDeviceSession.h
+++ b/camera/device/3.5/default/include/ext_device_v3_5_impl/ExternalCameraDeviceSession.h
@@ -106,6 +106,10 @@
             const hidl_vec<int32_t>& requests,
             uint32_t streamConfigCounter);
 
+    Return<void> isReconfigurationRequired(const V3_2::CameraMetadata& oldSessionParams,
+            const V3_2::CameraMetadata& newSessionParams,
+            ICameraDeviceSession::isReconfigurationRequired_cb _hidl_cb);
+
     virtual void initOutputThread() override;
     virtual void closeOutputThread() override;
     void closeOutputThreadImpl();
@@ -247,6 +251,12 @@
             return mParent->signalStreamFlush(requests, streamConfigCounter);
         }
 
+        virtual Return<void> isReconfigurationRequired(const V3_2::CameraMetadata& oldSessionParams,
+                const V3_2::CameraMetadata& newSessionParams,
+                ICameraDeviceSession::isReconfigurationRequired_cb _hidl_cb) override {
+            return mParent->isReconfigurationRequired(oldSessionParams, newSessionParams, _hidl_cb);
+        }
+
     private:
         sp<ExternalCameraDeviceSession> mParent;
     };
diff --git a/camera/metadata/3.4/Android.bp b/camera/metadata/3.4/Android.bp
index 388df68..d1cba14 100644
--- a/camera/metadata/3.4/Android.bp
+++ b/camera/metadata/3.4/Android.bp
@@ -14,7 +14,16 @@
         "android.hardware.camera.metadata@3.3",
     ],
     types: [
+        "CameraMetadataEnumAndroidDepthAvailableDynamicDepthStreamConfigurations",
+        "CameraMetadataEnumAndroidHeicAvailableHeicStreamConfigurations",
+        "CameraMetadataEnumAndroidHeicInfoSupported",
         "CameraMetadataEnumAndroidInfoSupportedBufferManagementVersion",
+        "CameraMetadataEnumAndroidRequestAvailableCapabilities",
+        "CameraMetadataEnumAndroidScalerAvailableFormats",
+        "CameraMetadataEnumAndroidScalerAvailableRecommendedStreamConfigurations",
+        "CameraMetadataEnumAndroidSensorInfoColorFilterArrangement",
+        "CameraMetadataSection",
+        "CameraMetadataSectionStart",
         "CameraMetadataTag",
     ],
     gen_java: true,
diff --git a/camera/provider/2.4/default/Android.bp b/camera/provider/2.4/default/Android.bp
index 81e5738..9d73934 100644
--- a/camera/provider/2.4/default/Android.bp
+++ b/camera/provider/2.4/default/Android.bp
@@ -1,46 +1,126 @@
 cc_library_shared {
-    name: "android.hardware.camera.provider@2.4-impl",
+    name: "android.hardware.camera.provider@2.4-legacy",
     defaults: ["hidl_defaults"],
     proprietary: true,
-    relative_install_path: "hw",
-    srcs: ["CameraProvider.cpp",
-           "ExternalCameraProvider.cpp"],
+    srcs: ["LegacyCameraProviderImpl_2_4.cpp"],
     shared_libs: [
-        "libhidlbase",
-        "libhidltransport",
-        "libutils",
-        "libcutils",
+        "android.hardware.camera.common@1.0",
         "android.hardware.camera.device@1.0",
         "android.hardware.camera.device@3.2",
         "android.hardware.camera.device@3.3",
         "android.hardware.camera.device@3.4",
         "android.hardware.camera.device@3.5",
+        "android.hardware.camera.provider@2.4",
+        "android.hardware.graphics.mapper@2.0",
+        "android.hidl.allocator@1.0",
+        "android.hidl.memory@1.0",
         "camera.device@1.0-impl",
         "camera.device@3.2-impl",
         "camera.device@3.3-impl",
         "camera.device@3.4-impl",
         "camera.device@3.5-impl",
-        "camera.device@3.4-external-impl",
-        "camera.device@3.5-external-impl",
-        "android.hardware.camera.provider@2.4",
-        "android.hardware.camera.common@1.0",
-        "android.hardware.graphics.mapper@2.0",
-        "android.hidl.allocator@1.0",
-        "android.hidl.memory@1.0",
-        "liblog",
-        "libhardware",
         "libcamera_metadata",
-        "libtinyxml2"
-    ],
-    header_libs: [
-        "camera.device@3.4-impl_headers",
-        "camera.device@3.5-impl_headers",
-        "camera.device@3.4-external-impl_headers",
-        "camera.device@3.5-external-impl_headers"
+        "libcutils",
+        "libhardware",
+        "libhidlbase",
+        "libhidltransport",
+        "liblog",
+        "libutils",
     ],
     static_libs: [
         "android.hardware.camera.common@1.0-helper",
     ],
+    header_libs: [
+        "camera.device@3.4-impl_headers",
+        "camera.device@3.5-impl_headers",
+    ],
+    export_include_dirs: ["."],
+}
+
+cc_library_shared {
+    name: "android.hardware.camera.provider@2.4-external",
+    proprietary: true,
+    srcs: ["ExternalCameraProviderImpl_2_4.cpp"],
+    shared_libs: [
+        "android.hardware.camera.common@1.0",
+        "android.hardware.camera.device@1.0",
+        "android.hardware.camera.device@3.2",
+        "android.hardware.camera.device@3.3",
+        "android.hardware.camera.device@3.4",
+        "android.hardware.camera.device@3.5",
+        "android.hardware.camera.provider@2.4",
+        "android.hardware.graphics.mapper@2.0",
+        "android.hidl.allocator@1.0",
+        "android.hidl.memory@1.0",
+        "camera.device@3.3-impl",
+        "camera.device@3.4-external-impl",
+        "camera.device@3.4-impl",
+        "camera.device@3.5-external-impl",
+        "camera.device@3.5-impl",
+        "libcamera_metadata",
+        "libcutils",
+        "libhardware",
+        "libhidlbase",
+        "libhidltransport",
+        "liblog",
+        "libtinyxml2",
+        "libutils",
+    ],
+    static_libs: [
+        "android.hardware.camera.common@1.0-helper",
+    ],
+    header_libs: [
+        "camera.device@3.4-external-impl_headers",
+        "camera.device@3.5-external-impl_headers"
+    ],
+    export_include_dirs: ["."],
+}
+
+cc_library_shared {
+    name: "android.hardware.camera.provider@2.4-impl",
+    defaults: ["hidl_defaults"],
+    proprietary: true,
+    relative_install_path: "hw",
+    srcs: ["CameraProvider_2_4.cpp"],
+    shared_libs: [
+        "android.hardware.camera.common@1.0",
+        "android.hardware.camera.device@1.0",
+        "android.hardware.camera.device@3.2",
+        "android.hardware.camera.device@3.3",
+        "android.hardware.camera.device@3.4",
+        "android.hardware.camera.device@3.5",
+        "android.hardware.camera.provider@2.4",
+        "android.hardware.camera.provider@2.4-external",
+        "android.hardware.camera.provider@2.4-legacy",
+        "android.hardware.graphics.mapper@2.0",
+        "android.hidl.allocator@1.0",
+        "android.hidl.memory@1.0",
+        "camera.device@1.0-impl",
+        "camera.device@3.2-impl",
+        "camera.device@3.3-impl",
+        "camera.device@3.4-external-impl",
+        "camera.device@3.4-impl",
+        "camera.device@3.5-external-impl",
+        "camera.device@3.5-impl",
+        "libcamera_metadata",
+        "libcutils",
+        "libhardware",
+        "libhidlbase",
+        "libhidltransport",
+        "liblog",
+        "libtinyxml2",
+        "libutils",
+    ],
+    header_libs: [
+        "camera.device@3.4-external-impl_headers",
+        "camera.device@3.4-impl_headers",
+        "camera.device@3.5-external-impl_headers",
+        "camera.device@3.5-impl_headers",
+    ],
+    static_libs: [
+        "android.hardware.camera.common@1.0-helper",
+    ],
+    export_include_dirs: ["."],
 }
 
 cc_defaults {
@@ -50,18 +130,32 @@
     relative_install_path: "hw",
     srcs: ["service.cpp"],
     shared_libs: [
-        "libhidlbase",
-        "libhidltransport",
-        "libbinder",
-        "liblog",
-        "libutils",
+        "android.hardware.camera.common@1.0",
         "android.hardware.camera.device@1.0",
         "android.hardware.camera.device@3.2",
         "android.hardware.camera.device@3.3",
         "android.hardware.camera.device@3.4",
         "android.hardware.camera.device@3.5",
         "android.hardware.camera.provider@2.4",
-        "android.hardware.camera.common@1.0",
+        "android.hardware.graphics.mapper@2.0",
+        "android.hidl.allocator@1.0",
+        "android.hidl.memory@1.0",
+        "libbinder",
+        "libcamera_metadata",
+        "libhardware",
+        "libhidlbase",
+        "libhidltransport",
+        "liblog",
+        "libutils",
+    ],
+    static_libs: [
+        "android.hardware.camera.common@1.0-helper",
+    ],
+    header_libs: [
+        "camera.device@3.4-external-impl_headers",
+        "camera.device@3.4-impl_headers",
+        "camera.device@3.5-external-impl_headers",
+        "camera.device@3.5-impl_headers",
     ],
 }
 
@@ -106,17 +200,24 @@
     compile_multilib: "32",
     init_rc: ["android.hardware.camera.provider@2.4-external-service.rc"],
     shared_libs: [
-        "libhidlbase",
-        "libhidltransport",
-        "libbinder",
-        "liblog",
-        "libutils",
+        "android.hardware.camera.common@1.0",
         "android.hardware.camera.device@1.0",
         "android.hardware.camera.device@3.2",
         "android.hardware.camera.device@3.3",
         "android.hardware.camera.device@3.4",
         "android.hardware.camera.device@3.5",
         "android.hardware.camera.provider@2.4",
-        "android.hardware.camera.common@1.0",
+        "libbinder",
+        "libhidlbase",
+        "libhidltransport",
+        "liblog",
+        "libtinyxml2",
+        "libutils",
+    ],
+    header_libs: [
+        "camera.device@3.4-external-impl_headers",
+        "camera.device@3.4-impl_headers",
+        "camera.device@3.5-external-impl_headers",
+        "camera.device@3.5-impl_headers",
     ],
 }
diff --git a/camera/provider/2.4/default/CameraProvider_2_4.cpp b/camera/provider/2.4/default/CameraProvider_2_4.cpp
new file mode 100644
index 0000000..15fc702
--- /dev/null
+++ b/camera/provider/2.4/default/CameraProvider_2_4.cpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright 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.
+ */
+
+#include "CameraProvider_2_4.h"
+#include "LegacyCameraProviderImpl_2_4.h"
+#include "ExternalCameraProviderImpl_2_4.h"
+
+const char *kLegacyProviderName = "legacy/0";
+const char *kExternalProviderName = "external/0";
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace provider {
+namespace V2_4 {
+namespace implementation {
+
+using android::hardware::camera::provider::V2_4::ICameraProvider;
+
+extern "C" ICameraProvider* HIDL_FETCH_ICameraProvider(const char* name);
+
+template<typename IMPL>
+CameraProvider<IMPL>* getProviderImpl() {
+    CameraProvider<IMPL> *provider = new CameraProvider<IMPL>();
+    if (provider == nullptr) {
+        ALOGE("%s: cannot allocate camera provider!", __FUNCTION__);
+        return nullptr;
+    }
+    if (provider->isInitFailed()) {
+        ALOGE("%s: camera provider init failed!", __FUNCTION__);
+        delete provider;
+        return nullptr;
+    }
+    return provider;
+}
+
+ICameraProvider* HIDL_FETCH_ICameraProvider(const char* name) {
+    using namespace android::hardware::camera::provider::V2_4::implementation;
+    ICameraProvider* provider = nullptr;
+    if (strcmp(name, kLegacyProviderName) == 0) {
+        provider = getProviderImpl<LegacyCameraProviderImpl_2_4>();
+    } else if (strcmp(name, kExternalProviderName) == 0) {
+        provider = getProviderImpl<ExternalCameraProviderImpl_2_4>();
+    } else {
+        ALOGE("%s: unknown instance name: %s", __FUNCTION__, name);
+    }
+
+    return provider;
+}
+
+}  // namespace implementation
+}  // namespace V2_4
+}  // namespace provider
+}  // namespace camera
+}  // namespace hardware
+}  // namespace android
diff --git a/camera/provider/2.4/default/CameraProvider_2_4.h b/camera/provider/2.4/default/CameraProvider_2_4.h
new file mode 100644
index 0000000..d2e5b94
--- /dev/null
+++ b/camera/provider/2.4/default/CameraProvider_2_4.h
@@ -0,0 +1,86 @@
+/*
+ * 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 ANDROID_HARDWARE_CAMERA_PROVIDER_V2_4_CAMERAPROVIDER_H
+#define ANDROID_HARDWARE_CAMERA_PROVIDER_V2_4_CAMERAPROVIDER_H
+
+#include <android/hardware/camera/provider/2.4/ICameraProvider.h>
+#include <hidl/Status.h>
+#include <hidl/MQDescriptor.h>
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace provider {
+namespace V2_4 {
+namespace implementation {
+
+using ::android::hardware::camera::common::V1_0::Status;
+using ::android::hardware::camera::provider::V2_4::ICameraProvider;
+using ::android::hardware::camera::provider::V2_4::ICameraProviderCallback;
+using ::android::hardware::Return;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+template<typename IMPL>
+struct CameraProvider : public ICameraProvider {
+    CameraProvider() : impl() {}
+    ~CameraProvider() {}
+
+    // Caller must use this method to check if CameraProvider ctor failed
+    bool isInitFailed() { return impl.isInitFailed(); }
+
+    // Methods from ::android::hardware::camera::provider::V2_4::ICameraProvider follow.
+    Return<Status> setCallback(const sp<ICameraProviderCallback>& callback) override {
+        return impl.setCallback(callback);
+    }
+
+    Return<void> getVendorTags(getVendorTags_cb _hidl_cb) override {
+        return impl.getVendorTags(_hidl_cb);
+    }
+
+    Return<void> getCameraIdList(getCameraIdList_cb _hidl_cb) override {
+        return impl.getCameraIdList(_hidl_cb);
+    }
+
+    Return<void> isSetTorchModeSupported(isSetTorchModeSupported_cb _hidl_cb) override {
+        return impl.isSetTorchModeSupported(_hidl_cb);
+    }
+
+    Return<void> getCameraDeviceInterface_V1_x(
+            const hidl_string& cameraDeviceName,
+            getCameraDeviceInterface_V1_x_cb _hidl_cb) override {
+        return impl.getCameraDeviceInterface_V1_x(cameraDeviceName, _hidl_cb);
+    }
+
+    Return<void> getCameraDeviceInterface_V3_x(
+            const hidl_string& cameraDeviceName,
+            getCameraDeviceInterface_V3_x_cb _hidl_cb) override {
+        return impl.getCameraDeviceInterface_V3_x(cameraDeviceName, _hidl_cb);
+    }
+
+private:
+    IMPL impl;
+};
+
+}  // namespace implementation
+}  // namespace V2_4
+}  // namespace provider
+}  // namespace camera
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_CAMERA_PROVIDER_V2_4_CAMERAPROVIDER_H
diff --git a/camera/provider/2.4/default/ExternalCameraProvider.cpp b/camera/provider/2.4/default/ExternalCameraProviderImpl_2_4.cpp
similarity index 87%
rename from camera/provider/2.4/default/ExternalCameraProvider.cpp
rename to camera/provider/2.4/default/ExternalCameraProviderImpl_2_4.cpp
index 604df5c..a6fd288 100644
--- a/camera/provider/2.4/default/ExternalCameraProvider.cpp
+++ b/camera/provider/2.4/default/ExternalCameraProviderImpl_2_4.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "CamPvdr@2.4-external"
+#define LOG_TAG "CamPrvdr@2.4-external"
 //#define LOG_NDEBUG 0
 #include <log/log.h>
 
@@ -22,10 +22,10 @@
 #include <sys/inotify.h>
 #include <errno.h>
 #include <linux/videodev2.h>
-#include "ExternalCameraProvider.h"
+#include <cutils/properties.h>
+#include "ExternalCameraProviderImpl_2_4.h"
 #include "ExternalCameraDevice_3_4.h"
 #include "ExternalCameraDevice_3_5.h"
-#include <cutils/properties.h>
 
 namespace android {
 namespace hardware {
@@ -34,6 +34,8 @@
 namespace V2_4 {
 namespace implementation {
 
+template struct CameraProvider<ExternalCameraProviderImpl_2_4>;
+
 namespace {
 // "device@<version>/external/<id>"
 const std::regex kDeviceNameRE("device@([0-9]+\\.[0-9]+)/external/(.+)");
@@ -60,7 +62,7 @@
 
 } // anonymous namespace
 
-ExternalCameraProvider::ExternalCameraProvider() :
+ExternalCameraProviderImpl_2_4::ExternalCameraProviderImpl_2_4() :
         mCfg(ExternalCameraConfig::loadFromCfg()),
         mHotPlugThread(this) {
     mHotPlugThread.run("ExtCamHotPlug", PRIORITY_BACKGROUND);
@@ -81,12 +83,12 @@
     }
 }
 
-ExternalCameraProvider::~ExternalCameraProvider() {
+ExternalCameraProviderImpl_2_4::~ExternalCameraProviderImpl_2_4() {
     mHotPlugThread.requestExit();
 }
 
 
-Return<Status> ExternalCameraProvider::setCallback(
+Return<Status> ExternalCameraProviderImpl_2_4::setCallback(
         const sp<ICameraProviderCallback>& callback) {
     {
         Mutex::Autolock _l(mLock);
@@ -105,14 +107,16 @@
     return Status::OK;
 }
 
-Return<void> ExternalCameraProvider::getVendorTags(getVendorTags_cb _hidl_cb) {
+Return<void> ExternalCameraProviderImpl_2_4::getVendorTags(
+        ICameraProvider::getVendorTags_cb _hidl_cb) {
     // No vendor tag support for USB camera
     hidl_vec<VendorTagSection> zeroSections;
     _hidl_cb(Status::OK, zeroSections);
     return Void();
 }
 
-Return<void> ExternalCameraProvider::getCameraIdList(getCameraIdList_cb _hidl_cb) {
+Return<void> ExternalCameraProviderImpl_2_4::getCameraIdList(
+        ICameraProvider::getCameraIdList_cb _hidl_cb) {
     // External camera HAL always report 0 camera, and extra cameras
     // are just reported via cameraDeviceStatusChange callbacks
     hidl_vec<hidl_string> hidlDeviceNameList;
@@ -120,25 +124,25 @@
     return Void();
 }
 
-Return<void> ExternalCameraProvider::isSetTorchModeSupported(
-        isSetTorchModeSupported_cb _hidl_cb) {
+Return<void> ExternalCameraProviderImpl_2_4::isSetTorchModeSupported(
+        ICameraProvider::isSetTorchModeSupported_cb _hidl_cb) {
     // setTorchMode API is supported, though right now no external camera device
     // has a flash unit.
     _hidl_cb (Status::OK, true);
     return Void();
 }
 
-Return<void> ExternalCameraProvider::getCameraDeviceInterface_V1_x(
+Return<void> ExternalCameraProviderImpl_2_4::getCameraDeviceInterface_V1_x(
         const hidl_string&,
-        getCameraDeviceInterface_V1_x_cb _hidl_cb) {
+        ICameraProvider::getCameraDeviceInterface_V1_x_cb _hidl_cb) {
     // External Camera HAL does not support HAL1
     _hidl_cb(Status::OPERATION_NOT_SUPPORTED, nullptr);
     return Void();
 }
 
-Return<void> ExternalCameraProvider::getCameraDeviceInterface_V3_x(
+Return<void> ExternalCameraProviderImpl_2_4::getCameraDeviceInterface_V3_x(
         const hidl_string& cameraDeviceName,
-        getCameraDeviceInterface_V3_x_cb _hidl_cb) {
+        ICameraProvider::getCameraDeviceInterface_V3_x_cb _hidl_cb) {
 
     std::string cameraId, deviceVersion;
     bool match = matchDeviceName(cameraDeviceName, &deviceVersion, &cameraId);
@@ -194,7 +198,7 @@
     return Void();
 }
 
-void ExternalCameraProvider::addExternalCamera(const char* devName) {
+void ExternalCameraProviderImpl_2_4::addExternalCamera(const char* devName) {
     ALOGI("ExtCam: adding %s to External Camera HAL!", devName);
     Mutex::Autolock _l(mLock);
     std::string deviceName;
@@ -209,7 +213,7 @@
     }
 }
 
-void ExternalCameraProvider::deviceAdded(const char* devName) {
+void ExternalCameraProviderImpl_2_4::deviceAdded(const char* devName) {
     {
         base::unique_fd fd(::open(devName, O_RDWR));
         if (fd.get() < 0) {
@@ -242,7 +246,7 @@
     return;
 }
 
-void ExternalCameraProvider::deviceRemoved(const char* devName) {
+void ExternalCameraProviderImpl_2_4::deviceRemoved(const char* devName) {
     Mutex::Autolock _l(mLock);
     std::string deviceName;
     if (mPreferredHal3MinorVersion == 5) {
@@ -260,14 +264,15 @@
     }
 }
 
-ExternalCameraProvider::HotplugThread::HotplugThread(ExternalCameraProvider* parent) :
+ExternalCameraProviderImpl_2_4::HotplugThread::HotplugThread(
+        ExternalCameraProviderImpl_2_4* parent) :
         Thread(/*canCallJava*/false),
         mParent(parent),
         mInternalDevices(parent->mCfg.mInternalDevices) {}
 
-ExternalCameraProvider::HotplugThread::~HotplugThread() {}
+ExternalCameraProviderImpl_2_4::HotplugThread::~HotplugThread() {}
 
-bool ExternalCameraProvider::HotplugThread::threadLoop() {
+bool ExternalCameraProviderImpl_2_4::HotplugThread::threadLoop() {
     // Find existing /dev/video* devices
     DIR* devdir = opendir(kDevicePath);
     if(devdir == 0) {
diff --git a/camera/provider/2.4/default/ExternalCameraProvider.h b/camera/provider/2.4/default/ExternalCameraProviderImpl_2_4.h
similarity index 72%
rename from camera/provider/2.4/default/ExternalCameraProvider.h
rename to camera/provider/2.4/default/ExternalCameraProviderImpl_2_4.h
index a69cf8b..8c79f68 100644
--- a/camera/provider/2.4/default/ExternalCameraProvider.h
+++ b/camera/provider/2.4/default/ExternalCameraProviderImpl_2_4.h
@@ -20,13 +20,14 @@
 #include <string>
 #include <unordered_map>
 #include <unordered_set>
-#include "utils/Mutex.h"
-#include "utils/Thread.h"
-#include <android/hardware/camera/provider/2.4/ICameraProvider.h>
+#include <utils/Mutex.h>
+#include <utils/Thread.h>
 #include <hidl/Status.h>
 #include <hidl/MQDescriptor.h>
 #include "ExternalCameraUtils.h"
 
+#include "CameraProvider_2_4.h"
+
 namespace android {
 namespace hardware {
 namespace camera {
@@ -47,25 +48,32 @@
 using ::android::sp;
 using ::android::Mutex;
 
-struct ExternalCameraProvider : public ICameraProvider {
-    ExternalCameraProvider();
-    ~ExternalCameraProvider();
+/**
+ * The implementation of external webcam CameraProvider 2.4, separated
+ * from the HIDL interface layer to allow for implementation reuse by later
+ * provider versions.
+ *
+ * This camera provider supports standard UVC webcameras via the Linux V4L2
+ * UVC driver.
+ */
+struct ExternalCameraProviderImpl_2_4 {
+    ExternalCameraProviderImpl_2_4();
+    ~ExternalCameraProviderImpl_2_4();
+
+    // Caller must use this method to check if CameraProvider ctor failed
+    bool isInitFailed() { return false;}
 
     // Methods from ::android::hardware::camera::provider::V2_4::ICameraProvider follow.
-    Return<Status> setCallback(const sp<ICameraProviderCallback>& callback) override;
-
-    Return<void> getVendorTags(getVendorTags_cb _hidl_cb) override;
-
-    Return<void> getCameraIdList(getCameraIdList_cb _hidl_cb) override;
-
-    Return<void> isSetTorchModeSupported(isSetTorchModeSupported_cb _hidl_cb) override;
-
+    Return<Status> setCallback(const sp<ICameraProviderCallback>& callback);
+    Return<void> getVendorTags(ICameraProvider::getVendorTags_cb _hidl_cb);
+    Return<void> getCameraIdList(ICameraProvider::getCameraIdList_cb _hidl_cb);
+    Return<void> isSetTorchModeSupported(ICameraProvider::isSetTorchModeSupported_cb _hidl_cb);
     Return<void> getCameraDeviceInterface_V1_x(
             const hidl_string&,
-            getCameraDeviceInterface_V1_x_cb) override;
+            ICameraProvider::getCameraDeviceInterface_V1_x_cb);
     Return<void> getCameraDeviceInterface_V3_x(
             const hidl_string&,
-            getCameraDeviceInterface_V3_x_cb) override;
+            ICameraProvider::getCameraDeviceInterface_V3_x_cb);
 
 private:
 
@@ -77,13 +85,13 @@
 
     class HotplugThread : public android::Thread {
     public:
-        HotplugThread(ExternalCameraProvider* parent);
+        HotplugThread(ExternalCameraProviderImpl_2_4* parent);
         ~HotplugThread();
 
         virtual bool threadLoop() override;
 
     private:
-        ExternalCameraProvider* mParent = nullptr;
+        ExternalCameraProviderImpl_2_4* mParent = nullptr;
         const std::unordered_set<std::string> mInternalDevices;
 
         int mINotifyFD = -1;
diff --git a/camera/provider/2.4/default/CameraProvider.cpp b/camera/provider/2.4/default/LegacyCameraProviderImpl_2_4.cpp
similarity index 89%
rename from camera/provider/2.4/default/CameraProvider.cpp
rename to camera/provider/2.4/default/LegacyCameraProviderImpl_2_4.cpp
index e02cc7e..4cff1b7 100644
--- a/camera/provider/2.4/default/CameraProvider.cpp
+++ b/camera/provider/2.4/default/LegacyCameraProviderImpl_2_4.cpp
@@ -14,21 +14,21 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "CamProvider@2.4-impl"
+#define LOG_TAG "CamPrvdr@2.4-legacy"
 //#define LOG_NDEBUG 0
 #include <android/log.h>
 
-#include "CameraProvider.h"
-#include "ExternalCameraProvider.h"
+#include "LegacyCameraProviderImpl_2_4.h"
 #include "CameraDevice_1_0.h"
 #include "CameraDevice_3_3.h"
 #include "CameraDevice_3_4.h"
 #include "CameraDevice_3_5.h"
+#include "CameraProvider_2_4.h"
 #include <cutils/properties.h>
+#include <regex>
 #include <string.h>
 #include <utils/Trace.h>
 
-
 namespace android {
 namespace hardware {
 namespace camera {
@@ -36,9 +36,9 @@
 namespace V2_4 {
 namespace implementation {
 
+template struct CameraProvider<LegacyCameraProviderImpl_2_4>;
+
 namespace {
-const char *kLegacyProviderName = "legacy/0";
-const char *kExternalProviderName = "external/0";
 // "device@<version>/legacy/<id>"
 const std::regex kDeviceNameRE("device@([0-9]+\\.[0-9]+)/legacy/(.+)");
 const char *kHAL3_4 = "3.4";
@@ -67,7 +67,7 @@
 using ::android::hardware::camera::common::V1_0::CameraMetadataType;
 using ::android::hardware::camera::common::V1_0::Status;
 
-void CameraProvider::addDeviceNames(int camera_id, CameraDeviceStatus status, bool cam_new)
+void LegacyCameraProviderImpl_2_4::addDeviceNames(int camera_id, CameraDeviceStatus status, bool cam_new)
 {
     char cameraId[kMaxCameraIdLen];
     snprintf(cameraId, sizeof(cameraId), "%d", camera_id);
@@ -107,7 +107,7 @@
     }
 }
 
-void CameraProvider::removeDeviceNames(int camera_id)
+void LegacyCameraProviderImpl_2_4::removeDeviceNames(int camera_id)
 {
     std::string cameraIdStr = std::to_string(camera_id);
 
@@ -134,13 +134,12 @@
 /**
  * static callback forwarding methods from HAL to instance
  */
-void CameraProvider::sCameraDeviceStatusChange(
+void LegacyCameraProviderImpl_2_4::sCameraDeviceStatusChange(
         const struct camera_module_callbacks* callbacks,
         int camera_id,
         int new_status) {
-    CameraProvider* cp = const_cast<CameraProvider*>(
-            static_cast<const CameraProvider*>(callbacks));
-
+    LegacyCameraProviderImpl_2_4* cp = const_cast<LegacyCameraProviderImpl_2_4*>(
+            static_cast<const LegacyCameraProviderImpl_2_4*>(callbacks));
     if (cp == nullptr) {
         ALOGE("%s: callback ops is null", __FUNCTION__);
         return;
@@ -181,12 +180,12 @@
     }
 }
 
-void CameraProvider::sTorchModeStatusChange(
+void LegacyCameraProviderImpl_2_4::sTorchModeStatusChange(
         const struct camera_module_callbacks* callbacks,
         const char* camera_id,
         int new_status) {
-    CameraProvider* cp = const_cast<CameraProvider*>(
-            static_cast<const CameraProvider*>(callbacks));
+    LegacyCameraProviderImpl_2_4* cp = const_cast<LegacyCameraProviderImpl_2_4*>(
+            static_cast<const LegacyCameraProviderImpl_2_4*>(callbacks));
 
     if (cp == nullptr) {
         ALOGE("%s: callback ops is null", __FUNCTION__);
@@ -206,7 +205,7 @@
     }
 }
 
-Status CameraProvider::getHidlStatus(int status) {
+Status LegacyCameraProviderImpl_2_4::getHidlStatus(int status) {
     switch (status) {
         case 0: return Status::OK;
         case -ENODEV: return Status::INTERNAL_ERROR;
@@ -217,13 +216,13 @@
     }
 }
 
-std::string CameraProvider::getLegacyCameraId(const hidl_string& deviceName) {
+std::string LegacyCameraProviderImpl_2_4::getLegacyCameraId(const hidl_string& deviceName) {
     std::string cameraId;
     matchDeviceName(deviceName, nullptr, &cameraId);
     return cameraId;
 }
 
-std::string CameraProvider::getHidlDeviceName(
+std::string LegacyCameraProviderImpl_2_4::getHidlDeviceName(
         std::string cameraId, int deviceVersion) {
     // Maybe consider create a version check method and SortedVec to speed up?
     if (deviceVersion != CAMERA_DEVICE_API_VERSION_1_0 &&
@@ -258,15 +257,15 @@
     return deviceName;
 }
 
-CameraProvider::CameraProvider() :
+LegacyCameraProviderImpl_2_4::LegacyCameraProviderImpl_2_4() :
         camera_module_callbacks_t({sCameraDeviceStatusChange,
                                    sTorchModeStatusChange}) {
     mInitFailed = initialize();
 }
 
-CameraProvider::~CameraProvider() {}
+LegacyCameraProviderImpl_2_4::~LegacyCameraProviderImpl_2_4() {}
 
-bool CameraProvider::initialize() {
+bool LegacyCameraProviderImpl_2_4::initialize() {
     camera_module_t *rawModule;
     int err = hw_get_module(CAMERA_HARDWARE_MODULE_ID,
             (const hw_module_t **)&rawModule);
@@ -343,7 +342,7 @@
 /**
  * Check that the device HAL version is still in supported.
  */
-int CameraProvider::checkCameraVersion(int id, camera_info info) {
+int LegacyCameraProviderImpl_2_4::checkCameraVersion(int id, camera_info info) {
     if (mModule == nullptr) {
         return NO_INIT;
     }
@@ -390,7 +389,7 @@
     return OK;
 }
 
-bool CameraProvider::setUpVendorTags() {
+bool LegacyCameraProviderImpl_2_4::setUpVendorTags() {
     ATRACE_CALL();
     vendor_tag_ops_t vOps = vendor_tag_ops_t();
 
@@ -447,11 +446,8 @@
 }
 
 // Methods from ::android::hardware::camera::provider::V2_4::ICameraProvider follow.
-Return<Status> CameraProvider::setCallback(const sp<ICameraProviderCallback>& callback)  {
-    if (callback == nullptr) {
-        return Status::ILLEGAL_ARGUMENT;
-    }
-
+Return<Status> LegacyCameraProviderImpl_2_4::setCallback(
+        const sp<ICameraProviderCallback>& callback) {
     Mutex::Autolock _l(mCbLock);
     mCallbacks = callback;
 
@@ -467,12 +463,14 @@
     return Status::OK;
 }
 
-Return<void> CameraProvider::getVendorTags(getVendorTags_cb _hidl_cb)  {
+Return<void> LegacyCameraProviderImpl_2_4::getVendorTags(
+        ICameraProvider::getVendorTags_cb _hidl_cb) {
     _hidl_cb(Status::OK, mVendorTagSections);
     return Void();
 }
 
-Return<void> CameraProvider::getCameraIdList(getCameraIdList_cb _hidl_cb)  {
+Return<void> LegacyCameraProviderImpl_2_4::getCameraIdList(
+        ICameraProvider::getCameraIdList_cb _hidl_cb) {
     std::vector<hidl_string> deviceNameList;
     for (auto const& deviceNamePair : mCameraDeviceNames) {
         if (std::stoi(deviceNamePair.first) >= mNumberOfLegacyCameras) {
@@ -489,14 +487,16 @@
     return Void();
 }
 
-Return<void> CameraProvider::isSetTorchModeSupported(isSetTorchModeSupported_cb _hidl_cb) {
+Return<void> LegacyCameraProviderImpl_2_4::isSetTorchModeSupported(
+        ICameraProvider::isSetTorchModeSupported_cb _hidl_cb) {
     bool support = mModule->isSetTorchModeSupported();
     _hidl_cb (Status::OK, support);
     return Void();
 }
 
-Return<void> CameraProvider::getCameraDeviceInterface_V1_x(
-        const hidl_string& cameraDeviceName, getCameraDeviceInterface_V1_x_cb _hidl_cb)  {
+Return<void> LegacyCameraProviderImpl_2_4::getCameraDeviceInterface_V1_x(
+        const hidl_string& cameraDeviceName,
+        ICameraProvider::getCameraDeviceInterface_V1_x_cb _hidl_cb)  {
     std::string cameraId, deviceVersion;
     bool match = matchDeviceName(cameraDeviceName, &deviceVersion, &cameraId);
     if (!match) {
@@ -548,8 +548,9 @@
     return Void();
 }
 
-Return<void> CameraProvider::getCameraDeviceInterface_V3_x(
-        const hidl_string& cameraDeviceName, getCameraDeviceInterface_V3_x_cb _hidl_cb)  {
+Return<void> LegacyCameraProviderImpl_2_4::getCameraDeviceInterface_V3_x(
+        const hidl_string& cameraDeviceName,
+        ICameraProvider::getCameraDeviceInterface_V3_x_cb _hidl_cb)  {
     std::string cameraId, deviceVersion;
     bool match = matchDeviceName(cameraDeviceName, &deviceVersion, &cameraId);
     if (!match) {
@@ -647,27 +648,6 @@
     return Void();
 }
 
-ICameraProvider* HIDL_FETCH_ICameraProvider(const char* name) {
-    if (strcmp(name, kLegacyProviderName) == 0) {
-        CameraProvider* provider = new CameraProvider();
-        if (provider == nullptr) {
-            ALOGE("%s: cannot allocate camera provider!", __FUNCTION__);
-            return nullptr;
-        }
-        if (provider->isInitFailed()) {
-            ALOGE("%s: camera provider init failed!", __FUNCTION__);
-            delete provider;
-            return nullptr;
-        }
-        return provider;
-    } else if (strcmp(name, kExternalProviderName) == 0) {
-        ExternalCameraProvider* provider = new ExternalCameraProvider();
-        return provider;
-    }
-    ALOGE("%s: unknown instance name: %s", __FUNCTION__, name);
-    return nullptr;
-}
-
 } // namespace implementation
 }  // namespace V2_4
 }  // namespace provider
diff --git a/camera/provider/2.4/default/CameraProvider.h b/camera/provider/2.4/default/LegacyCameraProviderImpl_2_4.h
similarity index 79%
rename from camera/provider/2.4/default/CameraProvider.h
rename to camera/provider/2.4/default/LegacyCameraProviderImpl_2_4.h
index 10e9b0d..b4914b3 100644
--- a/camera/provider/2.4/default/CameraProvider.h
+++ b/camera/provider/2.4/default/LegacyCameraProviderImpl_2_4.h
@@ -14,16 +14,14 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_HARDWARE_CAMERA_PROVIDER_V2_4_CAMERAPROVIDER_H
-#define ANDROID_HARDWARE_CAMERA_PROVIDER_V2_4_CAMERAPROVIDER_H
+#ifndef ANDROID_HARDWARE_CAMERA_PROVIDER_V2_4_LEGACYCAMERAPROVIDER_H
+#define ANDROID_HARDWARE_CAMERA_PROVIDER_V2_4_LEGACYCAMERAPROVIDER_H
 
-#include <regex>
+#include <android/hardware/camera/provider/2.4/ICameraProvider.h>
 #include "hardware/camera_common.h"
 #include "utils/Mutex.h"
 #include "utils/SortedVector.h"
-#include <android/hardware/camera/provider/2.4/ICameraProvider.h>
-#include <hidl/Status.h>
-#include <hidl/MQDescriptor.h>
+
 #include "CameraModule.h"
 #include "VendorTagDescriptor.h"
 
@@ -50,26 +48,34 @@
 using ::android::sp;
 using ::android::Mutex;
 
-struct CameraProvider : public ICameraProvider, public camera_module_callbacks_t {
-    CameraProvider();
-    ~CameraProvider();
+/**
+ * The implementation of legacy wrapper CameraProvider 2.4, separated
+ * from the HIDL interface layer to allow for implementation reuse by later
+ * provider versions.
+ *
+ * This implementation supports cameras implemented via the legacy libhardware
+ * camera HAL definitions.
+ */
+struct LegacyCameraProviderImpl_2_4 : public camera_module_callbacks_t {
+    LegacyCameraProviderImpl_2_4();
+    ~LegacyCameraProviderImpl_2_4();
 
     // Caller must use this method to check if CameraProvider ctor failed
     bool isInitFailed() { return mInitFailed; }
 
     // Methods from ::android::hardware::camera::provider::V2_4::ICameraProvider follow.
-    Return<Status> setCallback(const sp<ICameraProviderCallback>& callback) override;
-    Return<void> getVendorTags(getVendorTags_cb _hidl_cb) override;
-    Return<void> getCameraIdList(getCameraIdList_cb _hidl_cb) override;
-    Return<void> isSetTorchModeSupported(isSetTorchModeSupported_cb _hidl_cb) override;
+    Return<Status> setCallback(const sp<ICameraProviderCallback>& callback);
+    Return<void> getVendorTags(ICameraProvider::getVendorTags_cb _hidl_cb);
+    Return<void> getCameraIdList(ICameraProvider::getCameraIdList_cb _hidl_cb);
+    Return<void> isSetTorchModeSupported(ICameraProvider::isSetTorchModeSupported_cb _hidl_cb);
     Return<void> getCameraDeviceInterface_V1_x(
             const hidl_string& cameraDeviceName,
-            getCameraDeviceInterface_V1_x_cb _hidl_cb) override;
+            ICameraProvider::getCameraDeviceInterface_V1_x_cb _hidl_cb);
     Return<void> getCameraDeviceInterface_V3_x(
             const hidl_string& cameraDeviceName,
-            getCameraDeviceInterface_V3_x_cb _hidl_cb) override;
+            ICameraProvider::getCameraDeviceInterface_V3_x_cb _hidl_cb);
 
-private:
+protected:
     Mutex mCbLock;
     sp<ICameraProviderCallback> mCallbacks = nullptr;
 
@@ -115,9 +121,8 @@
     void addDeviceNames(int camera_id, CameraDeviceStatus status = CameraDeviceStatus::PRESENT,
                         bool cam_new = false);
     void removeDeviceNames(int camera_id);
-};
 
-extern "C" ICameraProvider* HIDL_FETCH_ICameraProvider(const char* name);
+};
 
 }  // namespace implementation
 }  // namespace V2_4
@@ -126,4 +131,4 @@
 }  // namespace hardware
 }  // namespace android
 
-#endif  // ANDROID_HARDWARE_CAMERA_PROVIDER_V2_4_CAMERAPROVIDER_H
+#endif  // ANDROID_HARDWARE_CAMERA_PROVIDER_V2_4_LEGACYCAMERAPROVIDER_H
diff --git a/camera/provider/2.4/default/service.cpp b/camera/provider/2.4/default/service.cpp
index 15d0ea6..4475f7d 100644
--- a/camera/provider/2.4/default/service.cpp
+++ b/camera/provider/2.4/default/service.cpp
@@ -21,9 +21,8 @@
 #endif
 
 #include <android/hardware/camera/provider/2.4/ICameraProvider.h>
-#include <hidl/LegacySupport.h>
-
 #include <binder/ProcessState.h>
+#include <hidl/LegacySupport.h>
 
 using android::status_t;
 using android::hardware::defaultLazyPassthroughServiceImplementation;
@@ -38,7 +37,7 @@
 
 int main()
 {
-    ALOGI("Camera provider Service is starting.");
+    ALOGI("CameraProvider@2.4 legacy service is starting.");
     // The camera HAL may communicate to other vendor components via
     // /dev/vndbinder
     android::ProcessState::initWithDriver("/dev/vndbinder");
diff --git a/camera/provider/2.4/vts/functional/Android.bp b/camera/provider/2.4/vts/functional/Android.bp
index f8f058e..5fb1fd8 100644
--- a/camera/provider/2.4/vts/functional/Android.bp
+++ b/camera/provider/2.4/vts/functional/Android.bp
@@ -40,6 +40,7 @@
         "android.hardware.camera.device@3.5",
 	"android.hardware.camera.metadata@3.4",
         "android.hardware.camera.provider@2.4",
+        "android.hardware.camera.provider@2.5",
         "android.hardware.graphics.allocator@2.0",
         "android.hardware.graphics.common@1.0",
         "android.hardware.graphics.mapper@2.0",
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index d5e1b39..3949346 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -35,6 +35,7 @@
 #include <android/hardware/camera/device/3.4/ICameraDeviceCallback.h>
 #include <android/hardware/camera/device/3.5/ICameraDeviceCallback.h>
 #include <android/hardware/camera/provider/2.4/ICameraProvider.h>
+#include <android/hardware/camera/provider/2.5/ICameraProvider.h>
 #include <android/hardware/camera/metadata/3.4/types.h>
 #include <android/hidl/manager/1.0/IServiceManager.h>
 #include <binder/MemoryHeapBase.h>
@@ -65,6 +66,7 @@
 using namespace ::android::hardware::camera::device;
 using ::android::hardware::Return;
 using ::android::hardware::Void;
+using ::android::hardware::hidl_bitfield;
 using ::android::hardware::hidl_handle;
 using ::android::hardware::hidl_string;
 using ::android::hardware::hidl_vec;
@@ -543,6 +545,9 @@
 
      uint32_t id;
      ASSERT_TRUE(parseProviderName(service_name, &mProviderType, &id));
+
+     castProvider(mProvider, &mProvider2_5);
+     notifyDeviceState(provider::V2_5::DeviceState::NORMAL);
  }
  virtual void TearDown() override {}
 
@@ -680,6 +685,8 @@
         CameraHidlTest *mParent;               // Parent object
     };
 
+    void notifyDeviceState(::android::hardware::camera::provider::V2_5::DeviceState newState);
+
     void openCameraDevice(const std::string &name, sp<ICameraProvider> provider,
             sp<::android::hardware::camera::device::V1_0::ICameraDevice> *device /*out*/);
     void setupPreviewWindow(
@@ -709,6 +716,8 @@
             sp<ICameraDeviceSession> *session /*out*/,
             camera_metadata_t **staticMeta /*out*/,
             ::android::sp<ICameraDevice> *device = nullptr/*out*/);
+    void castProvider(const sp<provider::V2_4::ICameraProvider> &provider,
+            sp<provider::V2_5::ICameraProvider> *provider2_5 /*out*/);
     void castSession(const sp<ICameraDeviceSession> &session, int32_t deviceVersion,
             sp<device::V3_3::ICameraDeviceSession> *session3_3 /*out*/,
             sp<device::V3_4::ICameraDeviceSession> *session3_4 /*out*/,
@@ -770,6 +779,9 @@
             hidl_vec<int32_t> streamIds, sp<DeviceCb> cb,
             uint32_t streamConfigCounter = 0);
 
+    void verifySessionReconfigurationQuery(sp<device::V3_5::ICameraDeviceSession> session3_5,
+            camera_metadata* oldSessionParams, camera_metadata* newSessionParams);
+
     static Status getAvailableOutputStreams(camera_metadata_t *staticMeta,
             std::vector<AvailableStream> &outputStreams,
             const AvailableStream *threshold = nullptr);
@@ -898,6 +910,8 @@
 
     // Camera provider service
     sp<ICameraProvider> mProvider;
+    sp<::android::hardware::camera::provider::V2_5::ICameraProvider> mProvider2_5;
+
     // Camera provider type.
     std::string mProviderType;
 };
@@ -3292,7 +3306,8 @@
         }
 
         android::hardware::camera::common::V1_0::helper::CameraMetadata previewRequestSettings;
-        android::hardware::camera::common::V1_0::helper::CameraMetadata sessionParams;
+        android::hardware::camera::common::V1_0::helper::CameraMetadata sessionParams,
+                modifiedSessionParams;
         constructFilteredSettings(session, availableSessionKeys, RequestTemplate::PREVIEW,
                 &previewRequestSettings, &sessionParams);
         if (sessionParams.isEmpty()) {
@@ -3323,13 +3338,28 @@
         ::android::hardware::camera::device::V3_5::StreamConfiguration config3_5;
         config.streams = streams;
         config.operationMode = StreamConfigurationMode::NORMAL_MODE;
-        const camera_metadata_t *sessionParamsBuffer = sessionParams.getAndLock();
-        config.sessionParams.setToExternal(
-                reinterpret_cast<uint8_t *> (const_cast<camera_metadata_t *> (sessionParamsBuffer)),
+        modifiedSessionParams = sessionParams;
+        auto sessionParamsBuffer = sessionParams.release();
+        config.sessionParams.setToExternal(reinterpret_cast<uint8_t *> (sessionParamsBuffer),
                 get_camera_metadata_size(sessionParamsBuffer));
         config3_5.v3_4 = config;
         config3_5.streamConfigCounter = 0;
         if (session3_5 != nullptr) {
+            bool newSessionParamsAvailable = false;
+            for (const auto& it : availableSessionKeys) {
+                if (modifiedSessionParams.exists(it)) {
+                    modifiedSessionParams.erase(it);
+                    newSessionParamsAvailable = true;
+                    break;
+                }
+            }
+            if (newSessionParamsAvailable) {
+                auto modifiedSessionParamsBuffer = modifiedSessionParams.release();
+                verifySessionReconfigurationQuery(session3_5, sessionParamsBuffer,
+                        modifiedSessionParamsBuffer);
+                modifiedSessionParams.acquire(modifiedSessionParamsBuffer);
+            }
+
             ret = session3_5->configureStreams_3_5(config3_5,
                     [](Status s, device::V3_4::HalStreamConfiguration halConfig) {
                         ASSERT_EQ(Status::OK, s);
@@ -3342,7 +3372,7 @@
                         ASSERT_EQ(1u, halConfig.streams.size());
                     });
         }
-
+        sessionParams.acquire(sessionParamsBuffer);
         ASSERT_TRUE(ret.isOk());
 
         free_camera_metadata(staticMetaBuffer);
@@ -4681,6 +4711,13 @@
     }
 }
 
+// Test camera provider@2.5 notify method
+TEST_F(CameraHidlTest, providerDeviceStateNotification) {
+
+    notifyDeviceState(provider::V2_5::DeviceState::BACK_COVERED);
+    notifyDeviceState(provider::V2_5::DeviceState::NORMAL);
+}
+
 // Retrieve all valid output stream resolutions from the camera
 // static characteristics.
 Status CameraHidlTest::getAvailableOutputStreams(camera_metadata_t *staticMeta,
@@ -5362,6 +5399,16 @@
     }
 }
 
+//Cast camera provider to corresponding version if available
+void CameraHidlTest::castProvider(const sp<ICameraProvider> &provider,
+        sp<provider::V2_5::ICameraProvider> *provider2_5 /*out*/) {
+    ASSERT_NE(nullptr, provider2_5);
+    auto castResult = provider::V2_5::ICameraProvider::castFrom(provider);
+    if (castResult.isOk()) {
+        *provider2_5 = castResult;
+    }
+}
+
 //Cast camera device session to corresponding version
 void CameraHidlTest::castSession(const sp<ICameraDeviceSession> &session, int32_t deviceVersion,
         sp<device::V3_3::ICameraDeviceSession> *session3_3 /*out*/,
@@ -5809,6 +5856,13 @@
     ASSERT_TRUE(ret.isOk());
 }
 
+void CameraHidlTest::notifyDeviceState(provider::V2_5::DeviceState newState) {
+    if (mProvider2_5.get() == nullptr) return;
+
+    mProvider2_5->notifyDeviceStateChange(
+            static_cast<hidl_bitfield<provider::V2_5::DeviceState>>(newState));
+}
+
 // Open a particular camera device.
 void CameraHidlTest::openCameraDevice(const std::string &name,
         sp<ICameraProvider> provider,
@@ -6061,6 +6115,35 @@
     }
 }
 
+void CameraHidlTest::verifySessionReconfigurationQuery(
+        sp<device::V3_5::ICameraDeviceSession> session3_5, camera_metadata* oldSessionParams,
+        camera_metadata* newSessionParams) {
+    ASSERT_NE(nullptr, session3_5.get());
+    ASSERT_NE(nullptr, oldSessionParams);
+    ASSERT_NE(nullptr, newSessionParams);
+
+    android::hardware::hidl_vec<uint8_t> oldParams, newParams;
+    oldParams.setToExternal(reinterpret_cast<uint8_t*>(oldSessionParams),
+            get_camera_metadata_size(oldSessionParams));
+    newParams.setToExternal(reinterpret_cast<uint8_t*>(newSessionParams),
+            get_camera_metadata_size(newSessionParams));
+    android::hardware::camera::common::V1_0::Status callStatus;
+    auto hidlCb = [&callStatus] (android::hardware::camera::common::V1_0::Status s,
+            bool /*requiredFlag*/) {
+        callStatus = s;
+    };
+    auto ret = session3_5->isReconfigurationRequired(oldParams, newParams, hidlCb);
+    ASSERT_TRUE(ret.isOk());
+    switch (callStatus) {
+        case android::hardware::camera::common::V1_0::Status::OK:
+        case android::hardware::camera::common::V1_0::Status::METHOD_NOT_SUPPORTED:
+            break;
+        case android::hardware::camera::common::V1_0::Status::INTERNAL_ERROR:
+        default:
+            ADD_FAILURE() << "Query calllback failed";
+    }
+}
+
 int main(int argc, char **argv) {
   ::testing::AddGlobalTestEnvironment(CameraHidlEnvironment::Instance());
   ::testing::InitGoogleTest(&argc, argv);
diff --git a/camera/provider/2.5/Android.bp b/camera/provider/2.5/Android.bp
new file mode 100644
index 0000000..3de010a
--- /dev/null
+++ b/camera/provider/2.5/Android.bp
@@ -0,0 +1,25 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+    name: "android.hardware.camera.provider@2.5",
+    root: "android.hardware",
+    vndk: {
+        enabled: true,
+    },
+    srcs: [
+        "types.hal",
+        "ICameraProvider.hal",
+    ],
+    interfaces: [
+        "android.hardware.camera.common@1.0",
+        "android.hardware.camera.device@1.0",
+        "android.hardware.camera.device@3.2",
+        "android.hardware.camera.provider@2.4",
+        "android.hidl.base@1.0",
+    ],
+    types: [
+        "DeviceState",
+    ],
+    gen_java: false,
+}
+
diff --git a/camera/provider/2.5/ICameraProvider.hal b/camera/provider/2.5/ICameraProvider.hal
new file mode 100644
index 0000000..b4cda6a
--- /dev/null
+++ b/camera/provider/2.5/ICameraProvider.hal
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+package android.hardware.camera.provider@2.5;
+
+import android.hardware.camera.common@1.0::Status;
+import android.hardware.camera.provider@2.4::ICameraProvider;
+
+/**
+ * Camera provider HAL
+ *
+ * Version 2.5 adds support for the notifyDeviceStateChange method
+ */
+interface ICameraProvider extends @2.4::ICameraProvider {
+
+    /**
+     * notifyDeviceStateChange:
+     *
+     * Notify the HAL provider that the state of the overall device has
+     * changed in some way that the HAL may want to know about.
+     *
+     * For example, a physical shutter may have been uncovered or covered,
+     * or a camera may have been covered or uncovered by an add-on keyboard
+     * or other accessory.
+     *
+     * The state is a bitfield of potential states, and some physical configurations
+     * could plausibly correspond to multiple different combinations of state bits.
+     * The HAL must ignore any state bits it is not actively using to determine
+     * the appropriate camera configuration.
+     *
+     * For example, on some devices the FOLDED state could mean that
+     * backward-facing cameras are covered by the fold, so FOLDED by itself implies
+     * BACK_COVERED. But other devices may support folding but not cover any cameras
+     * when folded, so for those FOLDED would not imply any of the other flags.
+     * Since these relationships are very device-specific, it is difficult to specify
+     * a comprehensive policy.  But as a recommendation, it is suggested that if a flag
+     * necessarily implies other flags are set as well, then those flags should be set.
+     * So even though FOLDED would be enough to infer BACK_COVERED on some devices, the
+     * BACK_COVERED flag should also be set for clarity.
+     *
+     * This method may be invoked by the HAL client at any time. It must not
+     * cause any active camera device sessions to be closed, but may dynamically
+     * change which physical camera a logical multi-camera is using for its
+     * active and future output.
+     *
+     * The method must be invoked by the HAL client at least once before the
+     * client calls ICameraDevice::open on any camera device interfaces listed
+     * by this provider, to establish the initial device state.
+     *
+     * @param newState
+     *    The new state of the device.
+     */
+    notifyDeviceStateChange(bitfield<DeviceState> newState);
+
+};
diff --git a/camera/provider/2.5/default/Android.bp b/camera/provider/2.5/default/Android.bp
new file mode 100644
index 0000000..cd1caeb
--- /dev/null
+++ b/camera/provider/2.5/default/Android.bp
@@ -0,0 +1,187 @@
+cc_library_shared {
+    name: "android.hardware.camera.provider@2.5-legacy",
+    proprietary: true,
+    srcs: ["LegacyCameraProviderImpl_2_5.cpp"],
+    shared_libs: [
+        "android.hardware.camera.common@1.0",
+        "android.hardware.camera.device@1.0",
+        "android.hardware.camera.device@3.2",
+        "android.hardware.camera.device@3.3",
+        "android.hardware.camera.device@3.4",
+        "android.hardware.camera.device@3.5",
+        "android.hardware.camera.provider@2.4",
+        "android.hardware.camera.provider@2.4-legacy",
+        "android.hardware.camera.provider@2.5",
+        "android.hardware.graphics.mapper@2.0",
+        "android.hidl.allocator@1.0",
+        "android.hidl.memory@1.0",
+        "camera.device@1.0-impl",
+        "camera.device@3.2-impl",
+        "camera.device@3.3-impl",
+        "camera.device@3.4-impl",
+        "camera.device@3.5-impl",
+        "libcamera_metadata",
+        "libcutils",
+        "libhardware",
+        "libhidlbase",
+        "libhidltransport",
+        "liblog",
+        "libutils",
+    ],
+    static_libs: [
+        "android.hardware.camera.common@1.0-helper",
+    ],
+    header_libs: [
+        "camera.device@3.4-impl_headers",
+        "camera.device@3.5-impl_headers",
+    ],
+    export_include_dirs: ["."],
+}
+
+cc_library_shared {
+    name: "android.hardware.camera.provider@2.5-external",
+    proprietary: true,
+    srcs: ["ExternalCameraProviderImpl_2_5.cpp"],
+    shared_libs: [
+        "android.hardware.camera.common@1.0",
+        "android.hardware.camera.device@1.0",
+        "android.hardware.camera.device@3.2",
+        "android.hardware.camera.device@3.3",
+        "android.hardware.camera.device@3.4",
+        "android.hardware.camera.device@3.5",
+        "android.hardware.camera.provider@2.4",
+        "android.hardware.camera.provider@2.4-external",
+        "android.hardware.camera.provider@2.5",
+        "android.hardware.graphics.mapper@2.0",
+        "android.hidl.allocator@1.0",
+        "android.hidl.memory@1.0",
+        "camera.device@3.3-impl",
+        "camera.device@3.4-external-impl",
+        "camera.device@3.4-impl",
+        "camera.device@3.5-external-impl",
+        "camera.device@3.5-impl",
+        "libcamera_metadata",
+        "libcutils",
+        "libhardware",
+        "libhidlbase",
+        "libhidltransport",
+        "liblog",
+        "libtinyxml2",
+        "libutils",
+    ],
+    static_libs: [
+        "android.hardware.camera.common@1.0-helper",
+    ],
+    header_libs: [
+        "camera.device@3.4-external-impl_headers",
+        "camera.device@3.5-external-impl_headers"
+    ],
+    export_include_dirs: ["."],
+}
+
+cc_defaults {
+    name: "camera_service_2_5_defaults",
+    defaults: ["hidl_defaults"],
+    proprietary: true,
+    relative_install_path: "hw",
+    srcs: ["service.cpp"],
+    shared_libs: [
+        "android.hardware.camera.common@1.0",
+        "android.hardware.camera.device@1.0",
+        "android.hardware.camera.device@3.2",
+        "android.hardware.camera.device@3.3",
+        "android.hardware.camera.device@3.4",
+        "android.hardware.camera.device@3.5",
+        "android.hardware.camera.provider@2.4",
+        "android.hardware.camera.provider@2.4-legacy",
+        "android.hardware.camera.provider@2.5",
+        "android.hardware.camera.provider@2.5-legacy",
+        "android.hardware.graphics.mapper@2.0",
+        "android.hidl.allocator@1.0",
+        "android.hidl.memory@1.0",
+        "libbinder",
+        "libcamera_metadata",
+        "libhardware",
+        "libhidlbase",
+        "libhidltransport",
+        "liblog",
+        "libutils",
+    ],
+    static_libs: [
+        "android.hardware.camera.common@1.0-helper",
+    ],
+    header_libs: [
+        "camera.device@3.4-impl_headers",
+        "camera.device@3.5-impl_headers"
+    ],
+}
+
+cc_binary {
+    name: "android.hardware.camera.provider@2.5-service",
+    defaults: ["camera_service_2_5_defaults"],
+    compile_multilib: "32",
+    init_rc: ["android.hardware.camera.provider@2.5-service.rc"],
+}
+
+cc_binary {
+    name: "android.hardware.camera.provider@2.5-service_64",
+    defaults: ["camera_service_2_5_defaults"],
+    compile_multilib: "64",
+    init_rc: ["android.hardware.camera.provider@2.5-service_64.rc"],
+}
+
+cc_binary {
+    name: "android.hardware.camera.provider@2.5-service-lazy",
+    overrides: ["android.hardware.camera.provider@2.5-service"],
+    defaults: ["camera_service_2_5_defaults"],
+    compile_multilib: "32",
+    init_rc: ["android.hardware.camera.provider@2.5-service-lazy.rc"],
+    cflags: ["-DLAZY_SERVICE"],
+}
+
+cc_binary {
+    name: "android.hardware.camera.provider@2.5-service-lazy_64",
+    overrides: ["android.hardware.camera.provider@2.5-service_64"],
+    defaults: ["camera_service_2_5_defaults"],
+    compile_multilib: "64",
+    init_rc: ["android.hardware.camera.provider@2.5-service-lazy_64.rc"],
+    cflags: ["-DLAZY_SERVICE"],
+}
+
+cc_binary {
+    name: "android.hardware.camera.provider@2.5-external-service",
+    defaults: ["hidl_defaults"],
+    proprietary: true,
+    relative_install_path: "hw",
+    srcs: ["external-service.cpp"],
+    compile_multilib: "32",
+    init_rc: ["android.hardware.camera.provider@2.5-external-service.rc"],
+    shared_libs: [
+        "android.hardware.camera.common@1.0",
+        "android.hardware.camera.device@1.0",
+        "android.hardware.camera.device@3.2",
+        "android.hardware.camera.device@3.3",
+        "android.hardware.camera.device@3.4",
+        "android.hardware.camera.device@3.5",
+        "android.hardware.camera.provider@2.4",
+        "android.hardware.camera.provider@2.4-external",
+        "android.hardware.camera.provider@2.5",
+        "android.hardware.camera.provider@2.5-external",
+        "android.hardware.graphics.mapper@2.0",
+        "libbinder",
+        "libhidlbase",
+        "libhidltransport",
+        "liblog",
+        "libtinyxml2",
+        "libutils",
+    ],
+    static_libs: [
+        "android.hardware.camera.common@1.0-helper",
+    ],
+    header_libs: [
+        "camera.device@3.4-external-impl_headers",
+        "camera.device@3.4-impl_headers",
+        "camera.device@3.5-external-impl_headers",
+        "camera.device@3.5-impl_headers",
+    ],
+}
diff --git a/camera/provider/2.5/default/CameraProvider_2_5.h b/camera/provider/2.5/default/CameraProvider_2_5.h
new file mode 100644
index 0000000..d0f1dda
--- /dev/null
+++ b/camera/provider/2.5/default/CameraProvider_2_5.h
@@ -0,0 +1,94 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_HARDWARE_CAMERA_PROVIDER_V2_5_CAMERAPROVIDER_H
+#define ANDROID_HARDWARE_CAMERA_PROVIDER_V2_5_CAMERAPROVIDER_H
+
+#include <android/hardware/camera/provider/2.5/ICameraProvider.h>
+#include <hidl/Status.h>
+#include <hidl/MQDescriptor.h>
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace provider {
+namespace V2_5 {
+namespace implementation {
+
+using ::android::hardware::camera::common::V1_0::Status;
+using ::android::hardware::camera::provider::V2_5::ICameraProvider;
+using ::android::hardware::camera::provider::V2_4::ICameraProviderCallback;
+using ::android::hardware::Return;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+// Default recommended RPC thread count for camera provider implementations
+const int HWBINDER_THREAD_COUNT = 6;
+
+template<typename IMPL>
+struct CameraProvider : public ICameraProvider {
+    CameraProvider() : impl() {}
+    ~CameraProvider() {}
+
+    // Caller must use this method to check if CameraProvider ctor failed
+    bool isInitFailed() { return impl.isInitFailed(); }
+
+    // Methods from ::android::hardware::camera::provider::V2_4::ICameraProvider follow.
+    Return<Status> setCallback(const sp<ICameraProviderCallback>& callback) override {
+        return impl.setCallback(callback);
+    }
+
+    Return<void> getVendorTags(getVendorTags_cb _hidl_cb) override {
+        return impl.getVendorTags(_hidl_cb);
+    }
+
+    Return<void> getCameraIdList(getCameraIdList_cb _hidl_cb) override {
+        return impl.getCameraIdList(_hidl_cb);
+    }
+
+    Return<void> isSetTorchModeSupported(isSetTorchModeSupported_cb _hidl_cb) override {
+        return impl.isSetTorchModeSupported(_hidl_cb);
+    }
+
+    Return<void> getCameraDeviceInterface_V1_x(
+            const hidl_string& cameraDeviceName,
+            getCameraDeviceInterface_V1_x_cb _hidl_cb) override {
+        return impl.getCameraDeviceInterface_V1_x(cameraDeviceName, _hidl_cb);
+    }
+
+    Return<void> getCameraDeviceInterface_V3_x(
+            const hidl_string& cameraDeviceName,
+            getCameraDeviceInterface_V3_x_cb _hidl_cb) override {
+        return impl.getCameraDeviceInterface_V3_x(cameraDeviceName, _hidl_cb);
+    }
+
+    // Methods from ::android::hardware::camera::provider::V2_5::ICameraProvider follow.
+    Return<void> notifyDeviceStateChange(hardware::hidl_bitfield<DeviceState> newState) override {
+        return impl.notifyDeviceStateChange(newState);
+    }
+
+private:
+    IMPL impl;
+};
+
+}  // namespace implementation
+}  // namespace V2_5
+}  // namespace provider
+}  // namespace camera
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_CAMERA_PROVIDER_V2_5_CAMERAPROVIDER_H
diff --git a/camera/provider/2.5/default/ExternalCameraProviderImpl_2_5.cpp b/camera/provider/2.5/default/ExternalCameraProviderImpl_2_5.cpp
new file mode 100644
index 0000000..87851cd
--- /dev/null
+++ b/camera/provider/2.5/default/ExternalCameraProviderImpl_2_5.cpp
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2018 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 "CamPrvdr@2.5-external"
+//#define LOG_NDEBUG 0
+#include <log/log.h>
+
+#include "ExternalCameraProviderImpl_2_5.h"
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace provider {
+namespace V2_5 {
+namespace implementation {
+
+ExternalCameraProviderImpl_2_5::ExternalCameraProviderImpl_2_5() :
+        ExternalCameraProviderImpl_2_4() {
+}
+
+ExternalCameraProviderImpl_2_5::~ExternalCameraProviderImpl_2_5() {
+}
+
+Return<void> ExternalCameraProviderImpl_2_5::notifyDeviceStateChange(
+        hidl_bitfield<DeviceState> /*newState*/) {
+    return Void();
+}
+
+}  // namespace implementation
+}  // namespace V2_5
+}  // namespace provider
+}  // namespace camera
+}  // namespace hardware
+}  // namespace android
diff --git a/camera/provider/2.5/default/ExternalCameraProviderImpl_2_5.h b/camera/provider/2.5/default/ExternalCameraProviderImpl_2_5.h
new file mode 100644
index 0000000..eeaa7cc
--- /dev/null
+++ b/camera/provider/2.5/default/ExternalCameraProviderImpl_2_5.h
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_HARDWARE_CAMERA_PROVIDER_V2_5_EXTCAMERAPROVIDER_H
+#define ANDROID_HARDWARE_CAMERA_PROVIDER_V2_5_EXTCAMERAPROVIDER_H
+
+#include <ExternalCameraProviderImpl_2_4.h>
+
+#include <android/hardware/camera/provider/2.5/ICameraProvider.h>
+#include <hidl/Status.h>
+#include <hidl/MQDescriptor.h>
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace provider {
+namespace V2_5 {
+namespace implementation {
+
+using namespace ::android::hardware::camera::provider;
+
+using ::android::hardware::camera::common::V1_0::CameraDeviceStatus;
+using ::android::hardware::camera::common::V1_0::Status;
+using ::android::hardware::camera::common::V1_0::VendorTagSection;
+using ::android::hardware::camera::external::common::ExternalCameraConfig;
+using ::android::hardware::camera::provider::V2_5::ICameraProvider;
+using ::android::hardware::camera::provider::V2_4::ICameraProviderCallback;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_bitfield;
+
+struct ExternalCameraProviderImpl_2_5 :
+        public V2_4::implementation::ExternalCameraProviderImpl_2_4 {
+    ExternalCameraProviderImpl_2_5();
+    ~ExternalCameraProviderImpl_2_5();
+
+    // Methods from ::android::hardware::camera::provider::V2_5::ICameraProvider follow.
+    Return<void> notifyDeviceStateChange(hidl_bitfield<DeviceState> newState);
+private:
+};
+
+}  // namespace implementation
+}  // namespace V2_5
+}  // namespace provider
+}  // namespace camera
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_CAMERA_PROVIDER_V2_5_EXTCAMERAPROVIDER_H
diff --git a/camera/provider/2.5/default/LegacyCameraProviderImpl_2_5.cpp b/camera/provider/2.5/default/LegacyCameraProviderImpl_2_5.cpp
new file mode 100644
index 0000000..5233397
--- /dev/null
+++ b/camera/provider/2.5/default/LegacyCameraProviderImpl_2_5.cpp
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "CamPrvdr@2.5-legacy"
+//#define LOG_NDEBUG 0
+#include <android/log.h>
+#include <inttypes.h>
+
+#include "LegacyCameraProviderImpl_2_5.h"
+#include "CameraProvider_2_5.h"
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace provider {
+namespace V2_5 {
+namespace implementation {
+
+template struct CameraProvider<LegacyCameraProviderImpl_2_5>;
+
+LegacyCameraProviderImpl_2_5::LegacyCameraProviderImpl_2_5() :
+        LegacyCameraProviderImpl_2_4() {
+}
+
+LegacyCameraProviderImpl_2_5::~LegacyCameraProviderImpl_2_5() {}
+
+Return<void> LegacyCameraProviderImpl_2_5::notifyDeviceStateChange(
+        hidl_bitfield<DeviceState> newState) {
+    ALOGD("%s: New device state: 0x%" PRIx64, __FUNCTION__, newState);
+    uint64_t state = static_cast<uint64_t>(newState);
+    mModule->notifyDeviceStateChange(state);
+    return Void();
+}
+
+}  // namespace implementation
+}  // namespace V2_5
+}  // namespace provider
+}  // namespace camera
+}  // namespace hardware
+}  // namespace android
diff --git a/camera/provider/2.5/default/LegacyCameraProviderImpl_2_5.h b/camera/provider/2.5/default/LegacyCameraProviderImpl_2_5.h
new file mode 100644
index 0000000..62dd97f
--- /dev/null
+++ b/camera/provider/2.5/default/LegacyCameraProviderImpl_2_5.h
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_HARDWARE_CAMERA_PROVIDER_V2_5_LEGACYCAMERAPROVIDER_H
+#define ANDROID_HARDWARE_CAMERA_PROVIDER_V2_5_LEGACYCAMERAPROVIDER_H
+
+#include <LegacyCameraProviderImpl_2_4.h>
+
+#include <android/hardware/camera/provider/2.5/ICameraProvider.h>
+#include <hidl/Status.h>
+#include <hidl/MQDescriptor.h>
+
+namespace android {
+namespace hardware {
+namespace camera {
+namespace provider {
+namespace V2_5 {
+namespace implementation {
+
+using namespace ::android::hardware::camera::provider;
+
+using ::android::hardware::camera::common::V1_0::CameraDeviceStatus;
+using ::android::hardware::camera::common::V1_0::Status;
+using ::android::hardware::camera::common::V1_0::TorchModeStatus;
+using ::android::hardware::camera::common::V1_0::VendorTag;
+using ::android::hardware::camera::common::V1_0::VendorTagSection;
+using ::android::hardware::camera::common::V1_0::helper::CameraModule;
+using ::android::hardware::camera::common::V1_0::helper::VendorTagDescriptor;
+using ::android::hardware::camera::provider::V2_5::DeviceState;
+using ::android::hardware::hidl_bitfield;
+using ::android::hardware::Return;
+
+struct LegacyCameraProviderImpl_2_5 : public V2_4::implementation::LegacyCameraProviderImpl_2_4 {
+    LegacyCameraProviderImpl_2_5();
+    ~LegacyCameraProviderImpl_2_5();
+
+    // Methods from ::android::hardware::camera::provider::V2_5::ICameraProvider follow.
+    Return<void> notifyDeviceStateChange(hidl_bitfield<DeviceState> newState);
+private:
+};
+
+}  // namespace implementation
+}  // namespace V2_5
+}  // namespace provider
+}  // namespace camera
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_CAMERA_PROVIDER_V2_5_CAMERAPROVIDER_H
diff --git a/camera/provider/2.5/default/OWNERS b/camera/provider/2.5/default/OWNERS
new file mode 100644
index 0000000..369b204
--- /dev/null
+++ b/camera/provider/2.5/default/OWNERS
@@ -0,0 +1,7 @@
+cychen@google.com
+epeev@google.com
+etalvala@google.com
+jchowdhary@google.com
+shuzhenwang@google.com
+yinchiayeh@google.com
+zhijunhe@google.com
diff --git a/camera/provider/2.5/default/android.hardware.camera.provider@2.5-external-service.rc b/camera/provider/2.5/default/android.hardware.camera.provider@2.5-external-service.rc
new file mode 100644
index 0000000..107097e
--- /dev/null
+++ b/camera/provider/2.5/default/android.hardware.camera.provider@2.5-external-service.rc
@@ -0,0 +1,9 @@
+service vendor.camera-provider-2-5-ext /vendor/bin/hw/android.hardware.camera.provider@2.5-external-service
+    interface android.hardware.camera.provider@2.5::ICameraProvider external/0
+    interface android.hardware.camera.provider@2.4::ICameraProvider external/0
+    class hal
+    user cameraserver
+    group audio camera input drmrpc usb
+    ioprio rt 4
+    capabilities SYS_NICE
+    writepid /dev/cpuset/camera-daemon/tasks /dev/stune/top-app/tasks
diff --git a/camera/provider/2.5/default/android.hardware.camera.provider@2.5-service-lazy.rc b/camera/provider/2.5/default/android.hardware.camera.provider@2.5-service-lazy.rc
new file mode 100644
index 0000000..b45158a
--- /dev/null
+++ b/camera/provider/2.5/default/android.hardware.camera.provider@2.5-service-lazy.rc
@@ -0,0 +1,11 @@
+service vendor.camera-provider-2-5 /vendor/bin/hw/android.hardware.camera.provider@2.5-service-lazy
+    interface android.hardware.camera.provider@2.5::ICameraProvider legacy/0
+    interface android.hardware.camera.provider@2.4::ICameraProvider legacy/0
+    oneshot
+    disabled
+    class hal
+    user cameraserver
+    group audio camera input drmrpc
+    ioprio rt 4
+    capabilities SYS_NICE
+    writepid /dev/cpuset/camera-daemon/tasks /dev/stune/top-app/tasks
diff --git a/camera/provider/2.5/default/android.hardware.camera.provider@2.5-service-lazy_64.rc b/camera/provider/2.5/default/android.hardware.camera.provider@2.5-service-lazy_64.rc
new file mode 100644
index 0000000..aa070d9
--- /dev/null
+++ b/camera/provider/2.5/default/android.hardware.camera.provider@2.5-service-lazy_64.rc
@@ -0,0 +1,11 @@
+service vendor.camera-provider-2-5 /vendor/bin/hw/android.hardware.camera.provider@2.5-service-lazy_64
+    interface android.hardware.camera.provider@2.5::ICameraProvider legacy/0
+    interface android.hardware.camera.provider@2.5::ICameraProvider legacy/0
+    oneshot
+    disabled
+    class hal
+    user cameraserver
+    group audio camera input drmrpc
+    ioprio rt 4
+    capabilities SYS_NICE
+    writepid /dev/cpuset/camera-daemon/tasks /dev/stune/top-app/tasks
diff --git a/camera/provider/2.5/default/android.hardware.camera.provider@2.5-service.rc b/camera/provider/2.5/default/android.hardware.camera.provider@2.5-service.rc
new file mode 100644
index 0000000..c065815
--- /dev/null
+++ b/camera/provider/2.5/default/android.hardware.camera.provider@2.5-service.rc
@@ -0,0 +1,9 @@
+service vendor.camera-provider-2-5 /vendor/bin/hw/android.hardware.camera.provider@2.5-service
+    interface android.hardware.camera.provider@2.5::ICameraProvider legacy/0
+    interface android.hardware.camera.provider@2.4::ICameraProvider legacy/0
+    class hal
+    user cameraserver
+    group audio camera input drmrpc
+    ioprio rt 4
+    capabilities SYS_NICE
+    writepid /dev/cpuset/camera-daemon/tasks /dev/stune/top-app/tasks
diff --git a/camera/provider/2.5/default/android.hardware.camera.provider@2.5-service_64.rc b/camera/provider/2.5/default/android.hardware.camera.provider@2.5-service_64.rc
new file mode 100644
index 0000000..63dd11d
--- /dev/null
+++ b/camera/provider/2.5/default/android.hardware.camera.provider@2.5-service_64.rc
@@ -0,0 +1,9 @@
+service vendor.camera-provider-2-5 /vendor/bin/hw/android.hardware.camera.provider@2.5-service_64
+    interface android.hardware.camera.provider@2.5::ICameraProvider legacy/0
+    interface android.hardware.camera.provider@2.4::ICameraProvider legacy/0
+    class hal
+    user cameraserver
+    group audio camera input drmrpc
+    ioprio rt 4
+    capabilities SYS_NICE
+    writepid /dev/cpuset/camera-daemon/tasks /dev/stune/top-app/tasks
diff --git a/camera/provider/2.5/default/external-service.cpp b/camera/provider/2.5/default/external-service.cpp
new file mode 100644
index 0000000..8788916
--- /dev/null
+++ b/camera/provider/2.5/default/external-service.cpp
@@ -0,0 +1,46 @@
+/*
+ * Copyright 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.
+ */
+
+#define LOG_TAG "android.hardware.camera.provider@2.5-external-service"
+
+#include <android/hardware/camera/provider/2.5/ICameraProvider.h>
+#include <binder/ProcessState.h>
+#include <hidl/HidlTransportSupport.h>
+
+#include "CameraProvider_2_5.h"
+#include "ExternalCameraProviderImpl_2_5.h"
+
+using android::status_t;
+using android::hardware::camera::provider::V2_5::ICameraProvider;
+
+int main()
+{
+    using namespace android::hardware::camera::provider::V2_5::implementation;
+
+    ALOGI("CameraProvider@2.5 external webcam service is starting.");
+
+    ::android::hardware::configureRpcThreadpool(/*threads*/ HWBINDER_THREAD_COUNT, /*willJoin*/ true);
+
+    ::android::sp<ICameraProvider> provider = new CameraProvider<ExternalCameraProviderImpl_2_5>();
+
+    status_t status = provider->registerAsService("external/0");
+    LOG_ALWAYS_FATAL_IF(status != android::OK, "Error while registering provider service: %d",
+            status);
+
+    ::android::hardware::joinRpcThreadpool();
+
+    return 0;
+}
diff --git a/camera/provider/2.5/default/service.cpp b/camera/provider/2.5/default/service.cpp
new file mode 100644
index 0000000..604215d
--- /dev/null
+++ b/camera/provider/2.5/default/service.cpp
@@ -0,0 +1,63 @@
+/*
+ * Copyright 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.
+ */
+
+#ifdef LAZY_SERVICE
+#define LOG_TAG "android.hardware.camera.provider@2.5-service-lazy"
+#else
+#define LOG_TAG "android.hardware.camera.provider@2.5-service"
+#endif
+
+#include <android/hardware/camera/provider/2.5/ICameraProvider.h>
+#include <binder/ProcessState.h>
+#include <hidl/HidlLazyUtils.h>
+#include <hidl/HidlTransportSupport.h>
+
+#include "CameraProvider_2_5.h"
+#include "LegacyCameraProviderImpl_2_5.h"
+
+using android::status_t;
+using android::hardware::camera::provider::V2_5::ICameraProvider;
+
+#ifdef LAZY_SERVICE
+const bool kLazyService = true;
+#else
+const bool kLazyService = false;
+#endif
+
+int main()
+{
+    using namespace android::hardware::camera::provider::V2_5::implementation;
+
+    ALOGI("CameraProvider@2.5 legacy service is starting.");
+
+    ::android::hardware::configureRpcThreadpool(/*threads*/ HWBINDER_THREAD_COUNT, /*willJoin*/ true);
+
+    ::android::sp<ICameraProvider> provider = new CameraProvider<LegacyCameraProviderImpl_2_5>();
+
+    status_t status;
+    if (kLazyService) {
+        auto serviceRegistrar = std::make_shared<::android::hardware::LazyServiceRegistrar>();
+        status = serviceRegistrar->registerService(provider, "legacy/0");
+    } else {
+        status = provider->registerAsService("legacy/0");
+    }
+    LOG_ALWAYS_FATAL_IF(status != android::OK, "Error while registering provider service: %d",
+            status);
+
+    ::android::hardware::joinRpcThreadpool();
+
+    return 0;
+}
diff --git a/camera/provider/2.5/types.hal b/camera/provider/2.5/types.hal
new file mode 100644
index 0000000..6a8ae83
--- /dev/null
+++ b/camera/provider/2.5/types.hal
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+package android.hardware.camera.provider@2.5;
+
+/**
+ * DeviceState:
+ *
+ * Possible physical states of the overall device, for use with
+ * ICameraProvider::notifyDeviceStateChange.
+ *
+ */
+enum DeviceState : uint64_t {
+    /**
+     * The device is in its normal physical configuration. This is the default if the
+     * device does not support multiple different states.
+     */
+    NORMAL = 0,
+
+    /**
+     * Camera device(s) facing backward are covered.
+     */
+    BACK_COVERED = 1 << 0,
+
+    /**
+     * Camera device(s) facing foward are covered.
+     */
+    FRONT_COVERED = 1 << 1,
+
+    /**
+     * The device is folded.  If not set, the device is unfolded or does not
+     * support folding.
+     *
+     * The exact point when this status change happens during the folding
+     * operation is device-specific.
+     */
+    FOLDED = 1 << 2,
+
+};
diff --git a/cas/1.1/default/MediaCasService.cpp b/cas/1.1/default/MediaCasService.cpp
index e2d3357..eb3fa6b 100644
--- a/cas/1.1/default/MediaCasService.cpp
+++ b/cas/1.1/default/MediaCasService.cpp
@@ -32,6 +32,34 @@
 namespace V1_1 {
 namespace implementation {
 
+class Wrapper : public V1_1::ICasListener {
+  public:
+    static sp<V1_1::ICasListener> wrap(sp<V1_0::ICasListener> impl) {
+        sp<V1_1::ICasListener> cast = V1_1::ICasListener::castFrom(impl);
+        if (cast == NULL) {
+            cast = new Wrapper(impl);
+        }
+        return cast;
+    }
+
+    virtual Return<void> onEvent(int32_t event, int32_t arg,
+                                 const hidl_vec<uint8_t>& data) override {
+        mImpl->onEvent(event, arg, data);
+        return Void();
+    }
+
+    virtual Return<void> onSessionEvent(const hidl_vec<uint8_t>& /* sessionId */,
+                                        int32_t /* event */, int32_t /* arg */,
+                                        const hidl_vec<uint8_t>& /*data*/) override {
+        ALOGV("Do nothing on Session Event for cas@1.0 client in cas@1.1");
+        return Void();
+    }
+
+  private:
+    Wrapper(sp<V1_0::ICasListener> impl) : mImpl(impl){};
+    sp<V1_0::ICasListener> mImpl;
+};
+
 MediaCasService::MediaCasService()
     : mCasLoader("createCasFactory"), mDescramblerLoader("createDescramblerFactory") {}
 
@@ -53,30 +81,23 @@
     return mCasLoader.findFactoryForScheme(CA_system_id);
 }
 
-Return<sp<V1_0::ICas>> MediaCasService::createPlugin(int32_t /* CA_system_id */,
-                                                     const sp<V1_0::ICasListener>& /* listener */) {
-    ALOGE("%s:Use createPluginExt to create plugin with cas@1.1", __FUNCTION__);
+Return<sp<V1_0::ICas>> MediaCasService::createPlugin(int32_t CA_system_id,
+                                                     const sp<V1_0::ICasListener>& listener) {
+    ALOGV("%s:Use createPluginExt to create plugin in cas@1.1", __FUNCTION__);
 
-    sp<V1_0::ICas> result;
-    /*
-        CasFactory *factory;
-        sp<SharedLibrary> library;
-        if (mCasLoader.findFactoryForScheme(CA_system_id, &library, &factory)) {
-            CasPlugin *plugin = NULL;
-            sp<CasImpl> casImpl = new CasImpl(listener);
-            if (factory->createPlugin(CA_system_id, casImpl.get(),
-                    CasImpl::OnEvent, &plugin) == OK && plugin != NULL) {
-                casImpl->init(library, plugin);
-                result = casImpl;
-            }
-        }
-    */
+    sp<ICas> result;
+
+    sp<V1_1::ICasListener> listenerV1_1 = Wrapper::wrap(listener);
+
+    result = createPluginExt(CA_system_id, listenerV1_1);
+
     return result;
 }
 
 Return<sp<ICas>> MediaCasService::createPluginExt(int32_t CA_system_id,
                                                   const sp<ICasListener>& listener) {
     ALOGV("%s: CA_system_id=%d", __FUNCTION__, CA_system_id);
+    if (listener == NULL) ALOGV("%s: Listener is NULL", __FUNCTION__);
 
     sp<ICas> result;
 
diff --git a/cas/1.1/vts/functional/Android.bp b/cas/1.1/vts/functional/Android.bp
new file mode 100644
index 0000000..8afd19a
--- /dev/null
+++ b/cas/1.1/vts/functional/Android.bp
@@ -0,0 +1,35 @@
+//
+// 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.
+//
+
+cc_test {
+    name: "VtsHalCasV1_1TargetTest",
+    defaults: ["VtsHalTargetTestDefaults"],
+    srcs: ["VtsHalCasV1_1TargetTest.cpp"],
+    static_libs: [
+        "android.hardware.cas@1.0",
+        "android.hardware.cas@1.1",
+        "android.hardware.cas.native@1.0",
+        "android.hidl.allocator@1.0",
+        "android.hidl.memory@1.0",
+        "libhidlallocatorutils",
+        "libhidlmemory",
+    ],
+    shared_libs: [
+        "libbinder",
+    ],
+    test_suites: ["general-tests"],
+}
+
diff --git a/cas/1.1/vts/functional/OWNERS b/cas/1.1/vts/functional/OWNERS
new file mode 100644
index 0000000..29246ed
--- /dev/null
+++ b/cas/1.1/vts/functional/OWNERS
@@ -0,0 +1,3 @@
+nchalko@google.com
+chz@google.com
+quxiangfang@google.com
diff --git a/cas/1.1/vts/functional/VtsHalCasV1_1TargetTest.cpp b/cas/1.1/vts/functional/VtsHalCasV1_1TargetTest.cpp
new file mode 100644
index 0000000..88f1fb0
--- /dev/null
+++ b/cas/1.1/vts/functional/VtsHalCasV1_1TargetTest.cpp
@@ -0,0 +1,571 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "mediacas_hidl_hal_test"
+
+#include <VtsHalHidlTargetTestBase.h>
+#include <VtsHalHidlTargetTestEnvBase.h>
+#include <android-base/logging.h>
+#include <android/hardware/cas/1.0/IDescramblerBase.h>
+#include <android/hardware/cas/1.0/types.h>
+#include <android/hardware/cas/1.1/ICas.h>
+#include <android/hardware/cas/1.1/ICasListener.h>
+#include <android/hardware/cas/1.1/IMediaCasService.h>
+#include <android/hardware/cas/native/1.0/IDescrambler.h>
+#include <android/hardware/cas/native/1.0/types.h>
+#include <binder/MemoryDealer.h>
+#include <hidl/HidlSupport.h>
+#include <hidl/HidlTransportSupport.h>
+#include <hidl/Status.h>
+#include <hidlmemory/FrameworkUtils.h>
+#include <utils/Condition.h>
+#include <utils/Mutex.h>
+
+#define CLEAR_KEY_SYSTEM_ID 0xF6D8
+#define INVALID_SYSTEM_ID 0
+#define WAIT_TIMEOUT 3000000000
+
+#define PROVISION_STR                                      \
+    "{                                                   " \
+    "  \"id\": 21140844,                                 " \
+    "  \"name\": \"Test Title\",                         " \
+    "  \"lowercase_organization_name\": \"Android\",     " \
+    "  \"asset_key\": {                                  " \
+    "  \"encryption_key\": \"nezAr3CHFrmBR9R8Tedotw==\"  " \
+    "  },                                                " \
+    "  \"cas_type\": 1,                                  " \
+    "  \"track_types\": [ ]                              " \
+    "}                                                   "
+
+using android::Condition;
+using android::IMemory;
+using android::IMemoryHeap;
+using android::MemoryDealer;
+using android::Mutex;
+using android::sp;
+using android::hardware::fromHeap;
+using android::hardware::hidl_string;
+using android::hardware::hidl_vec;
+using android::hardware::HidlMemory;
+using android::hardware::Return;
+using android::hardware::Void;
+using android::hardware::cas::native::V1_0::BufferType;
+using android::hardware::cas::native::V1_0::DestinationBuffer;
+using android::hardware::cas::native::V1_0::IDescrambler;
+using android::hardware::cas::native::V1_0::ScramblingControl;
+using android::hardware::cas::native::V1_0::SharedBuffer;
+using android::hardware::cas::native::V1_0::SubSample;
+using android::hardware::cas::V1_0::HidlCasPluginDescriptor;
+using android::hardware::cas::V1_0::IDescramblerBase;
+using android::hardware::cas::V1_0::Status;
+using android::hardware::cas::V1_1::ICas;
+using android::hardware::cas::V1_1::ICasListener;
+using android::hardware::cas::V1_1::IMediaCasService;
+
+namespace {
+
+const uint8_t kEcmBinaryBuffer[] = {
+        0x00, 0x00, 0x01, 0xf0, 0x00, 0x50, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x46, 0x00,
+        0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x27, 0x10, 0x02, 0x00,
+        0x01, 0x77, 0x01, 0x42, 0x95, 0x6c, 0x0e, 0xe3, 0x91, 0xbc, 0xfd, 0x05, 0xb1, 0x60, 0x4f,
+        0x17, 0x82, 0xa4, 0x86, 0x9b, 0x23, 0x56, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+        0x27, 0x10, 0x02, 0x00, 0x01, 0x77, 0x01, 0x42, 0x95, 0x6c, 0xd7, 0x43, 0x62, 0xf8, 0x1c,
+        0x62, 0x19, 0x05, 0xc7, 0x3a, 0x42, 0xcd, 0xfd, 0xd9, 0x13, 0x48,
+};
+
+const SubSample kSubSamples[] = {{162, 0}, {0, 184}, {0, 184}};
+
+const uint8_t kInBinaryBuffer[] = {
+        0x00, 0x00, 0x00, 0x01, 0x09, 0xf0, 0x00, 0x00, 0x00, 0x01, 0x67, 0x42, 0xc0, 0x1e, 0xdb,
+        0x01, 0x40, 0x16, 0xec, 0x04, 0x40, 0x00, 0x00, 0x03, 0x00, 0x40, 0x00, 0x00, 0x0f, 0x03,
+        0xc5, 0x8b, 0xb8, 0x00, 0x00, 0x00, 0x01, 0x68, 0xca, 0x8c, 0xb2, 0x00, 0x00, 0x01, 0x06,
+        0x05, 0xff, 0xff, 0x70, 0xdc, 0x45, 0xe9, 0xbd, 0xe6, 0xd9, 0x48, 0xb7, 0x96, 0x2c, 0xd8,
+        0x20, 0xd9, 0x23, 0xee, 0xef, 0x78, 0x32, 0x36, 0x34, 0x20, 0x2d, 0x20, 0x63, 0x6f, 0x72,
+        0x65, 0x20, 0x31, 0x34, 0x32, 0x20, 0x2d, 0x20, 0x48, 0x2e, 0x32, 0x36, 0x34, 0x2f, 0x4d,
+        0x50, 0x45, 0x47, 0x2d, 0x34, 0x20, 0x41, 0x56, 0x43, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x63,
+        0x20, 0x2d, 0x20, 0x43, 0x6f, 0x70, 0x79, 0x6c, 0x65, 0x66, 0x74, 0x20, 0x32, 0x30, 0x30,
+        0x33, 0x2d, 0x32, 0x30, 0x31, 0x34, 0x20, 0x2d, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
+        0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x6c, 0x61, 0x6e, 0x2e, 0x6f,
+        0x72, 0x67, 0x2f, 0x78, 0x32, 0x36, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x6e, 0x45, 0x21,
+        0x82, 0x38, 0xf0, 0x9d, 0x7d, 0x96, 0xe6, 0x94, 0xae, 0xe2, 0x87, 0x8f, 0x04, 0x49, 0xe5,
+        0xf6, 0x8c, 0x8b, 0x9a, 0x10, 0x18, 0xba, 0x94, 0xe9, 0x22, 0x31, 0x04, 0x7e, 0x60, 0x5b,
+        0xc4, 0x24, 0x00, 0x90, 0x62, 0x0d, 0xdc, 0x85, 0x74, 0x75, 0x78, 0xd0, 0x14, 0x08, 0xcb,
+        0x02, 0x1d, 0x7d, 0x9d, 0x34, 0xe8, 0x81, 0xb9, 0xf7, 0x09, 0x28, 0x79, 0x29, 0x8d, 0xe3,
+        0x14, 0xed, 0x5f, 0xca, 0xaf, 0xf4, 0x1c, 0x49, 0x15, 0xe1, 0x80, 0x29, 0x61, 0x76, 0x80,
+        0x43, 0xf8, 0x58, 0x53, 0x40, 0xd7, 0x31, 0x6d, 0x61, 0x81, 0x41, 0xe9, 0x77, 0x9f, 0x9c,
+        0xe1, 0x6d, 0xf2, 0xee, 0xd9, 0xc8, 0x67, 0xd2, 0x5f, 0x48, 0x73, 0xe3, 0x5c, 0xcd, 0xa7,
+        0x45, 0x58, 0xbb, 0xdd, 0x28, 0x1d, 0x68, 0xfc, 0xb4, 0xc6, 0xf6, 0x92, 0xf6, 0x30, 0x03,
+        0xaa, 0xe4, 0x32, 0xf6, 0x34, 0x51, 0x4b, 0x0f, 0x8c, 0xf9, 0xac, 0x98, 0x22, 0xfb, 0x49,
+        0xc8, 0xbf, 0xca, 0x8c, 0x80, 0x86, 0x5d, 0xd7, 0xa4, 0x52, 0xb1, 0xd9, 0xa6, 0x04, 0x4e,
+        0xb3, 0x2d, 0x1f, 0xb8, 0x35, 0xcc, 0x45, 0x6d, 0x9c, 0x20, 0xa7, 0xa4, 0x34, 0x59, 0x72,
+        0xe3, 0xae, 0xba, 0x49, 0xde, 0xd1, 0xaa, 0xee, 0x3d, 0x77, 0xfc, 0x5d, 0xc6, 0x1f, 0x9d,
+        0xac, 0xc2, 0x15, 0x66, 0xb8, 0xe1, 0x54, 0x4e, 0x74, 0x93, 0xdb, 0x9a, 0x24, 0x15, 0x6e,
+        0x20, 0xa3, 0x67, 0x3e, 0x5a, 0x24, 0x41, 0x5e, 0xb0, 0xe6, 0x35, 0x87, 0x1b, 0xc8, 0x7a,
+        0xf9, 0x77, 0x65, 0xe0, 0x01, 0xf2, 0x4c, 0xe4, 0x2b, 0xa9, 0x64, 0x96, 0x96, 0x0b, 0x46,
+        0xca, 0xea, 0x79, 0x0e, 0x78, 0xa3, 0x5f, 0x43, 0xfc, 0x47, 0x6a, 0x12, 0xfa, 0xc4, 0x33,
+        0x0e, 0x88, 0x1c, 0x19, 0x3a, 0x00, 0xc3, 0x4e, 0xb5, 0xd8, 0xfa, 0x8e, 0xf1, 0xbc, 0x3d,
+        0xb2, 0x7e, 0x50, 0x8d, 0x67, 0xc3, 0x6b, 0xed, 0xe2, 0xea, 0xa6, 0x1f, 0x25, 0x24, 0x7c,
+        0x94, 0x74, 0x50, 0x49, 0xe3, 0xc6, 0x58, 0x2e, 0xfd, 0x28, 0xb4, 0xc6, 0x73, 0xb1, 0x53,
+        0x74, 0x27, 0x94, 0x5c, 0xdf, 0x69, 0xb7, 0xa1, 0xd7, 0xf5, 0xd3, 0x8a, 0x2c, 0x2d, 0xb4,
+        0x5e, 0x8a, 0x16, 0x14, 0x54, 0x64, 0x6e, 0x00, 0x6b, 0x11, 0x59, 0x8a, 0x63, 0x38, 0x80,
+        0x76, 0xc3, 0xd5, 0x59, 0xf7, 0x3f, 0xd2, 0xfa, 0xa5, 0xca, 0x82, 0xff, 0x4a, 0x62, 0xf0,
+        0xe3, 0x42, 0xf9, 0x3b, 0x38, 0x27, 0x8a, 0x89, 0xaa, 0x50, 0x55, 0x4b, 0x29, 0xf1, 0x46,
+        0x7c, 0x75, 0xef, 0x65, 0xaf, 0x9b, 0x0d, 0x6d, 0xda, 0x25, 0x94, 0x14, 0xc1, 0x1b, 0xf0,
+        0xc5, 0x4c, 0x24, 0x0e, 0x65,
+};
+
+const uint8_t kOutRefBinaryBuffer[] = {
+        0x00, 0x00, 0x00, 0x01, 0x09, 0xf0, 0x00, 0x00, 0x00, 0x01, 0x67, 0x42, 0xc0, 0x1e, 0xdb,
+        0x01, 0x40, 0x16, 0xec, 0x04, 0x40, 0x00, 0x00, 0x03, 0x00, 0x40, 0x00, 0x00, 0x0f, 0x03,
+        0xc5, 0x8b, 0xb8, 0x00, 0x00, 0x00, 0x01, 0x68, 0xca, 0x8c, 0xb2, 0x00, 0x00, 0x01, 0x06,
+        0x05, 0xff, 0xff, 0x70, 0xdc, 0x45, 0xe9, 0xbd, 0xe6, 0xd9, 0x48, 0xb7, 0x96, 0x2c, 0xd8,
+        0x20, 0xd9, 0x23, 0xee, 0xef, 0x78, 0x32, 0x36, 0x34, 0x20, 0x2d, 0x20, 0x63, 0x6f, 0x72,
+        0x65, 0x20, 0x31, 0x34, 0x32, 0x20, 0x2d, 0x20, 0x48, 0x2e, 0x32, 0x36, 0x34, 0x2f, 0x4d,
+        0x50, 0x45, 0x47, 0x2d, 0x34, 0x20, 0x41, 0x56, 0x43, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x63,
+        0x20, 0x2d, 0x20, 0x43, 0x6f, 0x70, 0x79, 0x6c, 0x65, 0x66, 0x74, 0x20, 0x32, 0x30, 0x30,
+        0x33, 0x2d, 0x32, 0x30, 0x31, 0x34, 0x20, 0x2d, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
+        0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x6c, 0x61, 0x6e, 0x2e, 0x6f,
+        0x72, 0x67, 0x2f, 0x78, 0x32, 0x36, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20, 0x2d, 0x20,
+        0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3a, 0x20, 0x63, 0x61, 0x62, 0x61, 0x63, 0x3d,
+        0x30, 0x20, 0x72, 0x65, 0x66, 0x3d, 0x32, 0x20, 0x64, 0x65, 0x62, 0x6c, 0x6f, 0x63, 0x6b,
+        0x3d, 0x31, 0x3a, 0x30, 0x3a, 0x30, 0x20, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x65, 0x3d,
+        0x30, 0x78, 0x31, 0x3a, 0x30, 0x78, 0x31, 0x31, 0x31, 0x20, 0x6d, 0x65, 0x3d, 0x68, 0x65,
+        0x78, 0x20, 0x73, 0x75, 0x62, 0x6d, 0x65, 0x3d, 0x37, 0x20, 0x70, 0x73, 0x79, 0x3d, 0x31,
+        0x20, 0x70, 0x73, 0x79, 0x5f, 0x72, 0x64, 0x3d, 0x31, 0x2e, 0x30, 0x30, 0x3a, 0x30, 0x2e,
+        0x30, 0x30, 0x20, 0x6d, 0x69, 0x78, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x66, 0x3d, 0x31, 0x20,
+        0x6d, 0x65, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x3d, 0x31, 0x36, 0x20, 0x63, 0x68, 0x72,
+        0x6f, 0x6d, 0x61, 0x5f, 0x6d, 0x65, 0x3d, 0x31, 0x20, 0x74, 0x72, 0x65, 0x6c, 0x6c, 0x69,
+        0x73, 0x3d, 0x31, 0x20, 0x38, 0x78, 0x38, 0x64, 0x63, 0x74, 0x3d, 0x30, 0x20, 0x63, 0x71,
+        0x6d, 0x3d, 0x30, 0x20, 0x64, 0x65, 0x61, 0x64, 0x7a, 0x6f, 0x6e, 0x65, 0x3d, 0x32, 0x31,
+        0x2c, 0x31, 0x31, 0x20, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x73, 0x6b, 0x69, 0x70, 0x3d,
+        0x31, 0x20, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x61, 0x5f, 0x71, 0x70, 0x5f, 0x6f, 0x66, 0x66,
+        0x73, 0x65, 0x74, 0x3d, 0x2d, 0x32, 0x20, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x3d,
+        0x36, 0x30, 0x20, 0x6c, 0x6f, 0x6f, 0x6b, 0x61, 0x68, 0x65, 0x61, 0x64, 0x5f, 0x74, 0x68,
+        0x72, 0x65, 0x61, 0x64, 0x73, 0x3d, 0x35, 0x20, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x64, 0x5f,
+        0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x3d, 0x30, 0x20, 0x6e, 0x72, 0x3d, 0x30, 0x20,
+        0x64, 0x65, 0x63, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x3d, 0x31, 0x20, 0x69, 0x6e, 0x74, 0x65,
+        0x72, 0x6c, 0x61, 0x63, 0x65, 0x64, 0x3d, 0x30, 0x20, 0x62, 0x6c, 0x75, 0x72, 0x61, 0x79,
+        0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x3d, 0x30, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74,
+        0x72, 0x61, 0x69, 0x6e, 0x65, 0x64, 0x5f, 0x69, 0x6e, 0x74, 0x72, 0x61, 0x3d, 0x30, 0x20,
+        0x62, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x3d, 0x30, 0x20, 0x77, 0x65, 0x69, 0x67, 0x68,
+        0x74, 0x70, 0x3d, 0x30, 0x20, 0x6b, 0x65, 0x79, 0x69, 0x6e, 0x74, 0x3d, 0x32, 0x35, 0x30,
+        0x20, 0x6b, 0x65, 0x79, 0x69, 0x6e, 0x74, 0x5f, 0x6d, 0x69, 0x6e, 0x3d, 0x32, 0x35, 0x20,
+        0x73, 0x63, 0x65, 0x6e, 0x65,
+};
+
+class MediaCasListener : public ICasListener {
+  public:
+    virtual Return<void> onEvent(int32_t event, int32_t arg,
+                                 const hidl_vec<uint8_t>& data) override {
+        android::Mutex::Autolock autoLock(mMsgLock);
+        mEvent = event;
+        mEventArg = arg;
+        mEventData = data;
+
+        mEventReceived = true;
+        mMsgCondition.signal();
+        return Void();
+    }
+
+    virtual Return<void> onSessionEvent(const hidl_vec<uint8_t>& sessionId, int32_t event,
+                                        int32_t arg, const hidl_vec<uint8_t>& data) override {
+        android::Mutex::Autolock autoLock(mMsgLock);
+        mSessionId = sessionId;
+        mEvent = event;
+        mEventArg = arg;
+        mEventData = data;
+
+        mEventReceived = true;
+        mMsgCondition.signal();
+        return Void();
+    }
+
+    void testEventEcho(sp<ICas>& mediaCas, int32_t& event, int32_t& eventArg,
+                       hidl_vec<uint8_t>& eventData);
+
+    void testSessionEventEcho(sp<ICas>& mediaCas, const hidl_vec<uint8_t>& sessionId,
+                              int32_t& event, int32_t& eventArg, hidl_vec<uint8_t>& eventData);
+
+  private:
+    int32_t mEvent = -1;
+    int32_t mEventArg = -1;
+    bool mEventReceived = false;
+    hidl_vec<uint8_t> mEventData;
+    hidl_vec<uint8_t> mSessionId;
+    android::Mutex mMsgLock;
+    android::Condition mMsgCondition;
+};
+
+void MediaCasListener::testEventEcho(sp<ICas>& mediaCas, int32_t& event, int32_t& eventArg,
+                                     hidl_vec<uint8_t>& eventData) {
+    mEventReceived = false;
+    auto returnStatus = mediaCas->sendEvent(event, eventArg, eventData);
+    EXPECT_TRUE(returnStatus.isOk());
+    EXPECT_EQ(Status::OK, returnStatus);
+
+    android::Mutex::Autolock autoLock(mMsgLock);
+    while (!mEventReceived) {
+        if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) {
+            EXPECT_TRUE(false) << "event not received within timeout";
+            return;
+        }
+    }
+
+    EXPECT_EQ(mEvent, event);
+    EXPECT_EQ(mEventArg, eventArg);
+    EXPECT_TRUE(mEventData == eventData);
+}
+
+void MediaCasListener::testSessionEventEcho(sp<ICas>& mediaCas, const hidl_vec<uint8_t>& sessionId,
+                                            int32_t& event, int32_t& eventArg,
+                                            hidl_vec<uint8_t>& eventData) {
+    mEventReceived = false;
+    auto returnStatus = mediaCas->sendSessionEvent(sessionId, event, eventArg, eventData);
+    EXPECT_TRUE(returnStatus.isOk());
+    EXPECT_EQ(Status::OK, returnStatus);
+
+    android::Mutex::Autolock autoLock(mMsgLock);
+    while (!mEventReceived) {
+        if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) {
+            EXPECT_TRUE(false) << "event not received within timeout";
+            return;
+        }
+    }
+
+    EXPECT_TRUE(mSessionId == sessionId);
+    EXPECT_EQ(mEvent, event);
+    EXPECT_EQ(mEventArg, eventArg);
+    EXPECT_TRUE(mEventData == eventData);
+}
+
+// Test environment for Cas HIDL HAL.
+class CasHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
+  public:
+    // get the test environment singleton
+    static CasHidlEnvironment* Instance() {
+        static CasHidlEnvironment* instance = new CasHidlEnvironment;
+        return instance;
+    }
+
+    virtual void registerTestServices() override { registerTestService<IMediaCasService>(); }
+};
+
+class MediaCasHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+  public:
+    virtual void SetUp() override {
+        mService = ::testing::VtsHalHidlTargetTestBase::getService<IMediaCasService>(
+                CasHidlEnvironment::Instance()->getServiceName<IMediaCasService>());
+        ASSERT_NE(mService, nullptr);
+    }
+
+    sp<IMediaCasService> mService;
+
+  protected:
+    static void description(const std::string& description) {
+        RecordProperty("description", description);
+    }
+
+    sp<ICas> mMediaCas;
+    sp<IDescramblerBase> mDescramblerBase;
+    sp<MediaCasListener> mCasListener;
+    typedef struct _OobInputTestParams {
+        const SubSample* subSamples;
+        uint32_t numSubSamples;
+        size_t imemSizeActual;
+        uint64_t imemOffset;
+        uint64_t imemSize;
+        uint64_t srcOffset;
+        uint64_t dstOffset;
+    } OobInputTestParams;
+
+    ::testing::AssertionResult createCasPlugin(int32_t caSystemId);
+    ::testing::AssertionResult openCasSession(std::vector<uint8_t>* sessionId);
+    ::testing::AssertionResult descrambleTestInputBuffer(const sp<IDescrambler>& descrambler,
+                                                         Status* descrambleStatus,
+                                                         sp<IMemory>* hidlInMemory);
+    ::testing::AssertionResult descrambleTestOobInput(const sp<IDescrambler>& descrambler,
+                                                      Status* descrambleStatus,
+                                                      const OobInputTestParams& params);
+};
+
+::testing::AssertionResult MediaCasHidlTest::createCasPlugin(int32_t caSystemId) {
+    auto status = mService->isSystemIdSupported(caSystemId);
+    if (!status.isOk() || !status) {
+        return ::testing::AssertionFailure();
+    }
+    status = mService->isDescramblerSupported(caSystemId);
+    if (!status.isOk() || !status) {
+        return ::testing::AssertionFailure();
+    }
+
+    mCasListener = new MediaCasListener();
+    auto pluginStatus = mService->createPluginExt(caSystemId, mCasListener);
+    if (!pluginStatus.isOk()) {
+        return ::testing::AssertionFailure();
+    }
+    mMediaCas = pluginStatus;
+    if (mMediaCas == nullptr) {
+        return ::testing::AssertionFailure();
+    }
+
+    auto descramblerStatus = mService->createDescrambler(caSystemId);
+    if (!descramblerStatus.isOk()) {
+        return ::testing::AssertionFailure();
+    }
+    mDescramblerBase = descramblerStatus;
+    return ::testing::AssertionResult(mDescramblerBase != nullptr);
+}
+
+::testing::AssertionResult MediaCasHidlTest::openCasSession(std::vector<uint8_t>* sessionId) {
+    Status sessionStatus;
+    auto returnVoid = mMediaCas->openSession([&](Status status, const hidl_vec<uint8_t>& id) {
+        sessionStatus = status;
+        *sessionId = id;
+    });
+    return ::testing::AssertionResult(returnVoid.isOk() && (Status::OK == sessionStatus));
+}
+
+::testing::AssertionResult MediaCasHidlTest::descrambleTestInputBuffer(
+        const sp<IDescrambler>& descrambler, Status* descrambleStatus, sp<IMemory>* inMemory) {
+    hidl_vec<SubSample> hidlSubSamples;
+    hidlSubSamples.setToExternal(const_cast<SubSample*>(kSubSamples),
+                                 (sizeof(kSubSamples) / sizeof(SubSample)), false /*own*/);
+
+    sp<MemoryDealer> dealer = new MemoryDealer(sizeof(kInBinaryBuffer), "vts-cas");
+    if (nullptr == dealer.get()) {
+        ALOGE("couldn't get MemoryDealer!");
+        return ::testing::AssertionFailure();
+    }
+
+    sp<IMemory> mem = dealer->allocate(sizeof(kInBinaryBuffer));
+    if (nullptr == mem.get()) {
+        ALOGE("couldn't allocate IMemory!");
+        return ::testing::AssertionFailure();
+    }
+    *inMemory = mem;
+
+    // build HidlMemory from memory heap
+    ssize_t offset;
+    size_t size;
+    sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
+    if (nullptr == heap.get()) {
+        ALOGE("couldn't get memory heap!");
+        return ::testing::AssertionFailure();
+    }
+
+    uint8_t* ipBuffer = static_cast<uint8_t*>(static_cast<void*>(mem->pointer()));
+    memcpy(ipBuffer, kInBinaryBuffer, sizeof(kInBinaryBuffer));
+
+    // hidlMemory is not to be passed out of scope!
+    sp<HidlMemory> hidlMemory = fromHeap(heap);
+
+    SharedBuffer srcBuffer = {
+            .heapBase = *hidlMemory, .offset = (uint64_t)offset, .size = (uint64_t)size};
+
+    DestinationBuffer dstBuffer;
+    dstBuffer.type = BufferType::SHARED_MEMORY;
+    dstBuffer.nonsecureMemory = srcBuffer;
+
+    uint32_t outBytes;
+    hidl_string detailedError;
+    auto returnVoid = descrambler->descramble(
+            ScramblingControl::EVENKEY /*2*/, hidlSubSamples, srcBuffer, 0, dstBuffer, 0,
+            [&](Status status, uint32_t bytesWritten, const hidl_string& detailedErr) {
+                *descrambleStatus = status;
+                outBytes = bytesWritten;
+                detailedError = detailedErr;
+            });
+    if (!returnVoid.isOk() || *descrambleStatus != Status::OK) {
+        ALOGI("descramble failed, trans=%s, status=%d, outBytes=%u, error=%s",
+              returnVoid.description().c_str(), *descrambleStatus, outBytes, detailedError.c_str());
+    }
+    return ::testing::AssertionResult(returnVoid.isOk());
+}
+
+::testing::AssertionResult MediaCasHidlTest::descrambleTestOobInput(
+        const sp<IDescrambler>& descrambler, Status* descrambleStatus,
+        const OobInputTestParams& params) {
+    hidl_vec<SubSample> hidlSubSamples;
+    hidlSubSamples.setToExternal(const_cast<SubSample*>(params.subSamples), params.numSubSamples,
+                                 false /*own*/);
+
+    sp<MemoryDealer> dealer = new MemoryDealer(params.imemSizeActual, "vts-cas");
+    if (nullptr == dealer.get()) {
+        ALOGE("couldn't get MemoryDealer!");
+        return ::testing::AssertionFailure();
+    }
+
+    sp<IMemory> mem = dealer->allocate(params.imemSizeActual);
+    if (nullptr == mem.get()) {
+        ALOGE("couldn't allocate IMemory!");
+        return ::testing::AssertionFailure();
+    }
+
+    // build HidlMemory from memory heap
+    ssize_t offset;
+    size_t size;
+    sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
+    if (nullptr == heap.get()) {
+        ALOGE("couldn't get memory heap!");
+        return ::testing::AssertionFailure();
+    }
+
+    // hidlMemory is not to be passed out of scope!
+    sp<HidlMemory> hidlMemory = fromHeap(heap);
+
+    SharedBuffer srcBuffer = {
+            .heapBase = *hidlMemory,
+            .offset = (uint64_t)offset + params.imemOffset,
+            .size = (uint64_t)params.imemSize,
+    };
+
+    DestinationBuffer dstBuffer;
+    dstBuffer.type = BufferType::SHARED_MEMORY;
+    dstBuffer.nonsecureMemory = srcBuffer;
+
+    uint32_t outBytes;
+    hidl_string detailedError;
+    auto returnVoid = descrambler->descramble(
+            ScramblingControl::EVENKEY /*2*/, hidlSubSamples, srcBuffer, params.srcOffset,
+            dstBuffer, params.dstOffset,
+            [&](Status status, uint32_t bytesWritten, const hidl_string& detailedErr) {
+                *descrambleStatus = status;
+                outBytes = bytesWritten;
+                detailedError = detailedErr;
+            });
+    if (!returnVoid.isOk() || *descrambleStatus != Status::OK) {
+        ALOGI("descramble failed, trans=%s, status=%d, outBytes=%u, error=%s",
+              returnVoid.description().c_str(), *descrambleStatus, outBytes, detailedError.c_str());
+    }
+    return ::testing::AssertionResult(returnVoid.isOk());
+}
+
+TEST_F(MediaCasHidlTest, TestClearKeyApisWithSession) {
+    description("Test that valid call sequences with SessionEvent send and receive");
+
+    ASSERT_TRUE(createCasPlugin(CLEAR_KEY_SYSTEM_ID));
+
+    auto returnStatus = mMediaCas->provision(hidl_string(PROVISION_STR));
+    EXPECT_TRUE(returnStatus.isOk());
+    EXPECT_EQ(Status::OK, returnStatus);
+
+    hidl_vec<uint8_t> hidlPvtData;
+    hidlPvtData.resize(256);
+    returnStatus = mMediaCas->setPrivateData(hidlPvtData);
+    EXPECT_TRUE(returnStatus.isOk());
+    EXPECT_EQ(Status::OK, returnStatus);
+
+    std::vector<uint8_t> sessionId;
+    ASSERT_TRUE(openCasSession(&sessionId));
+    returnStatus = mMediaCas->setSessionPrivateData(sessionId, hidlPvtData);
+    EXPECT_TRUE(returnStatus.isOk());
+    EXPECT_EQ(Status::OK, returnStatus);
+
+    std::vector<uint8_t> streamSessionId;
+    ASSERT_TRUE(openCasSession(&streamSessionId));
+    returnStatus = mMediaCas->setSessionPrivateData(streamSessionId, hidlPvtData);
+    EXPECT_TRUE(returnStatus.isOk());
+    EXPECT_EQ(Status::OK, returnStatus);
+
+    returnStatus = mDescramblerBase->setMediaCasSession(sessionId);
+    EXPECT_TRUE(returnStatus.isOk());
+    EXPECT_EQ(Status::OK, returnStatus);
+
+    returnStatus = mDescramblerBase->setMediaCasSession(streamSessionId);
+    EXPECT_TRUE(returnStatus.isOk());
+    EXPECT_EQ(Status::OK, returnStatus);
+
+    hidl_vec<uint8_t> hidlNullPtr;
+    hidlNullPtr.setToExternal(static_cast<uint8_t*>(nullptr), 0);
+    returnStatus = mMediaCas->refreshEntitlements(3, hidlNullPtr);
+    EXPECT_TRUE(returnStatus.isOk());
+    EXPECT_EQ(Status::OK, returnStatus);
+
+    uint8_t refreshData[] = {0, 1, 2, 3};
+    hidl_vec<uint8_t> hidlRefreshData;
+    hidlRefreshData.setToExternal(static_cast<uint8_t*>(refreshData), sizeof(refreshData));
+    returnStatus = mMediaCas->refreshEntitlements(10, hidlRefreshData);
+    EXPECT_TRUE(returnStatus.isOk());
+    EXPECT_EQ(Status::OK, returnStatus);
+
+    int32_t eventID = 1;
+    int32_t eventArg = 2;
+    mCasListener->testEventEcho(mMediaCas, eventID, eventArg, hidlNullPtr);
+    mCasListener->testSessionEventEcho(mMediaCas, sessionId, eventID, eventArg, hidlNullPtr);
+
+    eventID = 3;
+    eventArg = 4;
+    uint8_t eventData[] = {'e', 'v', 'e', 'n', 't', 'd', 'a', 't', 'a'};
+    hidl_vec<uint8_t> hidlEventData;
+    hidlEventData.setToExternal(static_cast<uint8_t*>(eventData), sizeof(eventData));
+    mCasListener->testEventEcho(mMediaCas, eventID, eventArg, hidlEventData);
+    mCasListener->testSessionEventEcho(mMediaCas, sessionId, eventID, eventArg, hidlEventData);
+
+    uint8_t clearKeyEmmData[] = {'c', 'l', 'e', 'a', 'r', 'k', 'e', 'y', 'e', 'm', 'm'};
+    hidl_vec<uint8_t> hidlClearKeyEmm;
+    hidlClearKeyEmm.setToExternal(static_cast<uint8_t*>(clearKeyEmmData), sizeof(clearKeyEmmData));
+    returnStatus = mMediaCas->processEmm(hidlClearKeyEmm);
+    EXPECT_TRUE(returnStatus.isOk());
+    EXPECT_EQ(Status::OK, returnStatus);
+
+    hidl_vec<uint8_t> hidlEcm;
+    hidlEcm.setToExternal(const_cast<uint8_t*>(kEcmBinaryBuffer), sizeof(kEcmBinaryBuffer));
+    returnStatus = mMediaCas->processEcm(sessionId, hidlEcm);
+    EXPECT_TRUE(returnStatus.isOk());
+    EXPECT_EQ(Status::OK, returnStatus);
+    returnStatus = mMediaCas->processEcm(streamSessionId, hidlEcm);
+    EXPECT_TRUE(returnStatus.isOk());
+    EXPECT_EQ(Status::OK, returnStatus);
+
+    EXPECT_FALSE(mDescramblerBase->requiresSecureDecoderComponent("video/avc"));
+
+    sp<IDescrambler> descrambler;
+    descrambler = IDescrambler::castFrom(mDescramblerBase);
+    ASSERT_NE(descrambler, nullptr);
+
+    Status descrambleStatus = Status::OK;
+    sp<IMemory> dataMemory;
+
+    ASSERT_TRUE(descrambleTestInputBuffer(descrambler, &descrambleStatus, &dataMemory));
+    EXPECT_EQ(Status::OK, descrambleStatus);
+
+    ASSERT_NE(nullptr, dataMemory.get());
+    uint8_t* opBuffer = static_cast<uint8_t*>(static_cast<void*>(dataMemory->pointer()));
+
+    int compareResult =
+            memcmp(static_cast<const void*>(opBuffer),
+                   static_cast<const void*>(kOutRefBinaryBuffer), sizeof(kOutRefBinaryBuffer));
+    EXPECT_EQ(0, compareResult);
+
+    returnStatus = mDescramblerBase->release();
+    EXPECT_TRUE(returnStatus.isOk());
+    EXPECT_EQ(Status::OK, returnStatus);
+
+    returnStatus = mMediaCas->release();
+    EXPECT_TRUE(returnStatus.isOk());
+    EXPECT_EQ(Status::OK, returnStatus);
+}
+
+}  // anonymous namespace
+
+int main(int argc, char** argv) {
+    ::testing::AddGlobalTestEnvironment(CasHidlEnvironment::Instance());
+    ::testing::InitGoogleTest(&argc, argv);
+    CasHidlEnvironment::Instance()->init(&argc, argv);
+    int status = RUN_ALL_TESTS();
+    LOG(INFO) << "Test result = " << status;
+    return status;
+}
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index 0540ef1..2f9fb6e 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -113,7 +113,7 @@
     </hal>
     <hal format="hidl" optional="true">
         <name>android.hardware.camera.provider</name>
-        <version>2.4</version>
+        <version>2.4-5</version>
         <interface>
             <name>ICameraProvider</name>
             <regex-instance>[^/]+/[0-9]+</regex-instance>
@@ -153,19 +153,7 @@
     </hal>
     <hal format="hidl" optional="true">
         <name>android.hardware.drm</name>
-        <version>1.0-1</version>
-        <interface>
-            <name>ICryptoFactory</name>
-            <regex-instance>.*</regex-instance>
-        </interface>
-        <interface>
-            <name>IDrmFactory</name>
-            <regex-instance>.*</regex-instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="false">
-        <name>android.hardware.drm</name>
-        <version>1.2</version>
+        <version>1.0-2</version>
         <interface>
             <name>ICryptoFactory</name>
             <regex-instance>.*</regex-instance>
diff --git a/current.txt b/current.txt
index 478cbc5..fd55d7c 100644
--- a/current.txt
+++ b/current.txt
@@ -406,3 +406,150 @@
 3d01e29e8129186f7567c4f9c8bee7480a0768e587b1be9b28adb0a6cbec6bf2 android.hardware.tv.cec@1.0::types
 1722ad002317b1fae1400de709e90f442d94ef22864e05f7a12af48c32e8edc8 android.hardware.usb@1.1::types
 29c8da7a13c40d488f569c812441d5754ee45bdcdb8ce6564f524b708d10a057 android.hardware.vibrator@1.1::types
+
+# HALs released in Android Q
+438dc52ab820befb7a11e953e82110f0d8c91cdf96ef62be921efc64f5a3d580 android.hardware.atrace@1.0::IAtraceDevice
+20b9f81bb0b1f812f150ec94d42648b01087f2344ea91df0416bce0fb6cdfbd4 android.hardware.atrace@1.0::types
+dfdb4d04b65dc363e5621c85bfdf3023c277b75c31d821d8e71b3f44f198e214 android.hardware.audio@5.0::IDevice
+0a911297821854985cfcdb17b63d7948af0f0f51ce8c68cc86367c185bbc772e android.hardware.audio@5.0::IDevicesFactory
+ce2e8c6c8559fd42bd69e0dee27b4d9c93cd9b2eff487b4e6b6395b6a1a993d6 android.hardware.audio@5.0::IPrimaryDevice
+4a4e5e5d9357004a1256bde8d36010ee00c51cea811a1c1e0dd969a9fc0bf862 android.hardware.audio@5.0::IStream
+e05e48c583de14c1e5a6fa9d48ea50244e3e0924b76b342374e7471dc8007ba9 android.hardware.audio@5.0::IStreamIn
+9471b12b1c255bb530695720bc4174bd74987b75b1f820854af8944bc8c215c9 android.hardware.audio@5.0::IStreamOut
+1b0500367ed2b32a841667ac3200edf3d3a164e8004aca445ff1b085ac831e93 android.hardware.audio@5.0::IStreamOutCallback
+83e365479cc77d8717c155e1787ee668cd2ae4c557b467cf75b8e7cd53697ad8 android.hardware.audio@5.0::types
+edda213e520f387a3e367834b0772978b308a0f59b54479990aa9411aee9bcc4 android.hardware.audio.common@5.0::types
+f269297866765b95ddd1825676cc8a772f0c7c9863286df596fc302781a42ff5 android.hardware.audio.effect@5.0::IAcousticEchoCancelerEffect
+fa187b602d8939644ef708ed7627f2e3deac97899a4bda1de07f2ff126abe243 android.hardware.audio.effect@5.0::IAutomaticGainControlEffect
+e1bf864ccb8458c0da1dcc74a2e748b1dca8ac360df590591cf82d98292d7981 android.hardware.audio.effect@5.0::IBassBoostEffect
+d3867dcf1f46f1962d258c56151b5afb2ef26e9835fef73f01115492d58da5b7 android.hardware.audio.effect@5.0::IDownmixEffect
+445a65ea2edd1ccba8a8d8e1c88d24c6ea67e57d355fa446ab390e20f0db14aa android.hardware.audio.effect@5.0::IEffect
+0ac2e951f359e87644dcf642f488194f6b02563f89cfe8dd668ab7c422be89b1 android.hardware.audio.effect@5.0::IEffectBufferProviderCallback
+9019e7ac057b8105a9b9ac8974b13e1ded46d1006e5a544aec510dfaf92755c6 android.hardware.audio.effect@5.0::IEffectsFactory
+c8e5a7e450a5b201c286814d484d04c7b9c6cab71b4982b34b84177e818909db android.hardware.audio.effect@5.0::IEnvironmentalReverbEffect
+cf356f430a1bb42fd91af65f105e07fa84a5927dc45c36d8ffce5b6c132c1f3c android.hardware.audio.effect@5.0::IEqualizerEffect
+8c31b0cad211968dc6008dcb2b116bf5f12079c8dce920e79242e7839104138e android.hardware.audio.effect@5.0::ILoudnessEnhancerEffect
+6f0f86b549e30382619877784857c40d4c64978c1e9eef3c034bdd367aac7468 android.hardware.audio.effect@5.0::INoiseSuppressionEffect
+ca15a738dedc2f4981925f7d7ff29c22bc3f8a848403dcf0c592c167de09d9af android.hardware.audio.effect@5.0::IPresetReverbEffect
+443659bb9e27221e5da0d16c7a0ecb2dc3a9a03acc8a0b2196b47c50735e2d2e android.hardware.audio.effect@5.0::IVirtualizerEffect
+78fed26a781cdca1b3bcb37520bff705d7764ee81db9cfd37014953c7ad2596e android.hardware.audio.effect@5.0::IVisualizerEffect
+6385b6accab8a544e2ee54ba7bf5aa55dff6153bcedd80fdaae16fe9e0be7050 android.hardware.audio.effect@5.0::types
+2f11e4c10ebe2b600426e0695f3c720d21663501c1c9449537055f13f37600d3 android.hardware.biometrics.face@1.0::IBiometricsFace
+dfb0666af59eb306c82a6f576c65a160e6829d3324211a10429fd63768df70df android.hardware.biometrics.face@1.0::IBiometricsFaceClientCallback
+cc40d308f38b6a218fcf99f264ebb49544fce670a6abdf294c617357a3d83dad android.hardware.biometrics.face@1.0::types
+ecedc58dbcdb13503c19c0ab160ac1dd0530bb1471164149282dd1463c684185 android.hardware.bluetooth.audio@2.0::IBluetoothAudioPort
+fb9c40e4deab40be5476477078fe3d8a4a4495fd9deef4321878d169d675c633 android.hardware.bluetooth.audio@2.0::IBluetoothAudioProvider
+f7431f3e3e4e3387fc6f27a6cf423eddcd824a395dc4349d302c995ab44a9895 android.hardware.bluetooth.audio@2.0::IBluetoothAudioProvidersFactory
+447a5c9bb0f1a5ed3f1dfe5216afe4be2f4362111d95479670eec4cae4d7d5f7 android.hardware.bluetooth.audio@2.0::types
+09ab9b24994429d9bb32a3fb420b6f6be3e47eb655139a2c08c4e80d3f33ff95 android.hardware.camera.device@3.5::ICameraDevice
+06237de53c42890029e3f8fe7d1480d078469c0d07608e51c37b4d485d342992 android.hardware.camera.device@3.5::ICameraDeviceCallback
+08c68b196e2fc4e5ba67ba0d0917bde828a87cbe2cffec19d04733972da9eb49 android.hardware.camera.device@3.5::ICameraDeviceSession
+d487ab209944df8987eeca70cf09307fc1429cedf64b0ea9e77c61d8caeb8c15 android.hardware.camera.device@3.5::types
+74ec7732fdacb22292c907b49f8f933510851ea1b3ed195c4dcdff35a20387f5 android.hardware.camera.metadata@3.4::types
+0fb39a7809ad1c52b3efbbed5ef4749b06c2a4f1f19cdc3efa2e3d9b28f1205c android.hardware.camera.provider@2.5::ICameraProvider
+f5777403d65135a5407723671bc7a864cdca83aea13ee3ce2894b95e6588ca3a android.hardware.camera.provider@2.5::types
+44c88954b3c201b26f64fcdb6f278024ab3aae864a9e1ec70e8a74274ae9d6aa android.hardware.cas@1.1::ICas
+25012d1778f7396f967bbc0231397d544bde421ba5b98706c9e48ac790612683 android.hardware.cas@1.1::ICasListener
+dffacdbe0bcf8443013de5bdc56a83479ad979d4919ed15a5585539f46091f07 android.hardware.cas@1.1::IMediaCasService
+bc742c6b17c834010f90c06ce2939c845198eecd2706be18da99e14bceb2acc0 android.hardware.configstore@1.2::ISurfaceFlingerConfigs
+aadac6b9fcf660384d73cbb97f3732ff9eeb8e8c67001e3fdbf4add108e5b1dc android.hardware.configstore@1.2::types
+5b1f4a4fb88c239e07d76026467a1f2ee0d08f4d52c1805bd93bd7c05e3fe69c android.hardware.drm@1.2::ICryptoFactory
+4895f98e9ef210e9acb01982f5d07b654538377e1404b8db5e19e7858835e9d8 android.hardware.drm@1.2::ICryptoPlugin
+976116b9033b2c222b940109fdf0ffcc29b77cbe631ef6b4fcc2ad5ce8e605f7 android.hardware.drm@1.2::IDrmFactory
+b2efccc6425085f84795a2ca15a09d9a81ffd02f9dc3d30ba21d1a59bdfa253f android.hardware.drm@1.2::IDrmPlugin
+39ca9e88404b6c090f7650455a7ed3fdee9cce4e3a356c9d547f8ff02f2e7fc8 android.hardware.drm@1.2::IDrmPluginListener
+f27baaa587bc3dd9b740cb6928ab812b9b7d105b5187663938aee578105f3c39 android.hardware.drm@1.2::types
+44480c912e4ab90b9ed17e56569cd5ca98413a8a2372efb028f4181204b6b73e android.hardware.fastboot@1.0::IFastboot
+7b2989744e3c555292d4b5b829acd09a7b40f96ead62ce54174cd959503b64bb android.hardware.fastboot@1.0::types
+7f460e795f5d1ed5e378935f98c6db4d39497de988aef1b4c2a4a07a6c400392 android.hardware.gnss@2.0::IAGnss
+2e5ad983734069e84a760004b32da0d09e4170c05380abe27e6eb80e4aa70d5a android.hardware.gnss@2.0::IAGnssCallback
+1f4ac068a88a72360280d94a7f6fd7c63813c1eea4891a0eb01394d3e7e775f2 android.hardware.gnss@2.0::IAGnssRil
+52e56490d35b4214d68c44f013e22bdf681fd6f8e5947c643dbb8453f9a03dcd android.hardware.gnss@2.0::IGnss
+0676e99eda39ff32f6891bcb56ea27df17007c439b9f900aa9a3919776920c23 android.hardware.gnss@2.0::IGnssCallback
+ecc966c68bddbd95c8dae782b84204cf01c75734675e8769963f3b5106ec128b android.hardware.gnss@2.0::IGnssConfiguration
+c67759f5d6387d273b66729180d03690e827f0b6b8d4e13ce2ff42d31b224065 android.hardware.gnss@2.0::IGnssMeasurement
+08615296d42451856f82c4953b45c4257d0a7b935fd98557c2ee2812c79fe0c3 android.hardware.gnss@2.0::IGnssMeasurementCallback
+141269652bcf30a7557edc4cd4311aa3e2ac67a252a7e8d3959b956d35793344 android.hardware.gnss@2.0::types
+50623a69a88b1c8a05738e4af7d5f78e905f415ccb0e84c99d0a71ea182e9393 android.hardware.gnss.measurement_corrections@1.0::IMeasurementCorrections
+6ef12cd95df73f8f80c25eb035d98ca4594f9cee571fdabea838a0b6016dd908 android.hardware.gnss.measurement_corrections@1.0::types
+0d278956d7fc6fdf9ca9c42962ff2d73967bbb1c9f0b3e0b58d71b7095c286bc android.hardware.gnss.visibility_control@1.0::IGnssVisibilityControl
+0d99e34500cfc2d40b684cb4dea7ebd89d4aff9f5315ed36b33442a7a88c138c android.hardware.gnss.visibility_control@1.0::IGnssVisibilityControlCallback
+6b2d8dfa3db505c34a3a19082d8737c86bd859ec00f0e6c5fd19cce3c1ef95d1 android.hardware.graphics.allocator@3.0::IAllocator
+2a81d3132df91614a30ca45dfe088d67ddbb30240ab8c25feb6b8110d7ec3800 android.hardware.graphics.bufferqueue@2.0::IGraphicBufferProducer
+b826892686850a9cf2b60ca5845db7185c2196ea4dd765cd80cd163169678a78 android.hardware.graphics.bufferqueue@2.0::IProducerListener
+01c6398c90fc6be0640810e2c5d8a4863b457280132bb3f97dd5682e19632b62 android.hardware.graphics.bufferqueue@2.0::types
+7a2d64095252f85781b2d521f4f11d04ce774544feececcec2088c568656e93c android.hardware.graphics.common@1.2::types
+3dff04a36b86660b5807414587e530bb0c294ed56fdff06f8915ba0a9b73f974 android.hardware.graphics.composer@2.3::IComposer
+ed0cf91532e88dff073cf7f45b9c65ee1c88553ebcb97892f7b7072abb9b822a android.hardware.graphics.composer@2.3::IComposerClient
+5c8bf8e1af9efe225a4661db8c08ff1b7e13fdc8ed49f35291bd0b6c9436b8f2 android.hardware.graphics.mapper@3.0::IMapper
+7183d9d9acfa41a61a64bdfed548e98299265a7bb1821a3ed204173b5c2cfd4a android.hardware.graphics.mapper@3.0::types
+c3f831a66d5815baf74f5b82fe79cf099542ddae4dfab3f388e1d41828e794fc android.hardware.health.storage@1.0::IGarbageCollectCallback
+dd1ec219f5d2e2b33c6c0bcb92e63bbedb36f7c716413462848f6b6ae74fc864 android.hardware.health.storage@1.0::IStorage
+2b4a14661e6a38617b7dd0c6ebb66a56a90e564674ac7697a14cb8a0cab92b2f android.hardware.health.storage@1.0::types
+30006fde4cb1f255f2530208728bff692100411b20af5b66fa31a9196d51f00b android.hardware.input.classifier@1.0::IInputClassifier
+97d8757bb05eb23d6a218bda374e095dfbb064c47714e2f859963c11f433e822 android.hardware.input.common@1.0::types
+24ae089981d58bc4cc74d75a6055bf357338ae6744ce1b467c5b4a9c470aba6d android.hardware.media.bufferpool@2.0::IAccessor
+897f45ee7db24ef227dea83ca3e4de72d53ff6bb7adc7983c90a650a1a6ff576 android.hardware.media.bufferpool@2.0::IClientManager
+aee53b2865b4f7939fb3df6fae758d9750c14f93dd454b479fc74aa7978fda4f android.hardware.media.bufferpool@2.0::IConnection
+0bf3758eeeb05767830ea87041214be80968c4679fb73577ac5b3091841ee71f android.hardware.media.bufferpool@2.0::IObserver
+82255e252ae215382473ad2e5ac7a2814a439a24f0092551aad7a2f89c6e9546 android.hardware.media.bufferpool@2.0::types
+fd4725732511b8ae124b868fd0b2090386663dffc5e67dfd0d0b4a0b49c335db android.hardware.media.c2@1.0::IComponent
+389d06e4a4ecf60f828a260045b0c327a5ae883ee0856a3c054556dd22b1f450 android.hardware.media.c2@1.0::IComponentInterface
+5ee0c02265c5505ade189796bef46697df4e0563e3544bb0c934855b34694b07 android.hardware.media.c2@1.0::IComponentListener
+43d70bcdc63b3d042bac3c3297f5d941dfabbd08f3ceb96b6016cc14f6e34ba3 android.hardware.media.c2@1.0::IComponentStore
+d36f747f9c9a8f2f21db2f8323c2d755dd08b34ce813932d7339979f7d490dab android.hardware.media.c2@1.0::IConfigurable
+cd2bd9f424515aeb0c2b91f3bb879797defb5b846b8660784b68d225285bcdff android.hardware.media.c2@1.0::IInputSink
+c3dfaa1fcd452c6cfc26d8dcbb67b71b08a1fe6dad5f87427e93d11a95372b05 android.hardware.media.c2@1.0::IInputSurface
+0a786a19e6753f9774a7ca7781c2a2edfe5c0b5fa112355dfa0e50ebedeb08b9 android.hardware.media.c2@1.0::IInputSurfaceConnection
+4cb139f729c29d8d6f4ecdab149c4feb571dad8a06e56cd57fcb52e70208bab4 android.hardware.media.c2@1.0::types
+4880af120fc1640225abdc2c60bda6d79617d73484d5124913c7278af3b11e2d android.hardware.neuralnetworks@1.2::IBurstCallback
+19877e466ad8c6ed42b38050b77bd010cf7800ff365fdc8574f45bbfda03a758 android.hardware.neuralnetworks@1.2::IBurstContext
+96249c852dabeefa3a9496ecdfc44681a071c665bfbf88527bf775c88bf1ab1b android.hardware.neuralnetworks@1.2::IDevice
+92714960d1a53fc2ec557302b41c7cc93d2636d8364a44bd0f85be0c92927ff8 android.hardware.neuralnetworks@1.2::IExecutionCallback
+83885d366f22ada42c00d8854f0b7e7ba4cf73ddf80bb0d8e168ce132cec57ea android.hardware.neuralnetworks@1.2::IPreparedModel
+e1c734d1545e1a4ae749ff1dd9704a8e594c59aea7c8363159dc258e93e0df3b android.hardware.neuralnetworks@1.2::IPreparedModelCallback
+313b341f1f6196a48cf304eaf067f67510c1ebc04df8c7cd536db5611df5c5c2 android.hardware.neuralnetworks@1.2::types
+cf7a4ba516a638f9b82a249c91fb603042c2d9ca43fd5aad9cf6c0401ed2a5d7 android.hardware.nfc@1.2::INfc
+abf98c2ae08bf765db54edc8068e36d52eb558cff6706b6fd7c18c65a1f3fc18 android.hardware.nfc@1.2::types
+4cb252dc6372a874aef666b92a6e9529915aa187521a700f0789065c3c702ead android.hardware.power.stats@1.0::IPowerStats
+69c394e7fe3236beb6231a709865e8a882aac7a612c8dddf64f5a66028fa2c68 android.hardware.power.stats@1.0::types
+11620ce020b6ef8f5b63eb2a39390de4a2fbbccc0a5e558b5b1a0e22e33f63cf android.hardware.radio@1.3::IRadio
+e9d0f11a52715f5a29d89e2d8e2e21db1e16a43174af6b9d51a62d705cda1455 android.hardware.radio@1.3::IRadioIndication
+d233f0da44f55fdef0a95db5229231412787bb67695cd1ea197ce89a3c2908b9 android.hardware.radio@1.3::IRadioResponse
+750a363c8cec70baa1aac19e275c15233c5898e93c6bb5155fa2ca7f365490dc android.hardware.radio@1.3::types
+21e6ce53f1759f6a213ca05bac3c0325ed911f74764d1c1f6fa5ed8068ade65b android.hardware.radio@1.4::IRadio
+33d9e6895cca98aa56296bb01720d18b8acd0e4de4960beb712e63ad147438a5 android.hardware.radio@1.4::IRadioIndication
+0cc0dd87c634aad36d7df22b2832839ef7ded71909dbcde11cfdd69dc0dc52b8 android.hardware.radio@1.4::IRadioResponse
+29d34232cc3974626b08759e039fe788bded7695cdeb098458e3e11e4c7d3603 android.hardware.radio@1.4::types
+51e696c0ceff30f74da8ff8d02fe4522ffd2f4a04cdfdbca0c68bfa64fcd306b android.hardware.radio.config@1.1::IRadioConfig
+7fcf167f593b10c67b59ab70321781c26a5575eab60803e7cbb1c14c71085a3b android.hardware.radio.config@1.1::IRadioConfigIndication
+b42eb3bbd5e7b519e28362340c2205aa75356de6b30f4fd09ec2ea784f250ab0 android.hardware.radio.config@1.1::IRadioConfigResponse
+989ffce9105bb21626fd7ef51330ad47a3292a77bef77ac59badd9da40316ca7 android.hardware.radio.config@1.1::types
+b0d452f9a2e45f80bdb672b1e4cb649fff50293bdf208099be41738f11cd2ead android.hardware.radio.config@1.2::IRadioConfigIndication
+d8e7717e8187dd7453d4142f8f331e7c325e7a6f9e8d44ac0d52b3be502bfe83 android.hardware.radio.config@1.2::IRadioConfigResponse
+93b8102078e25057ae347ac9704e87529eb26121c2a1b419b362dd36eccefc4d android.hardware.radio.config@1.2::types
+08d439c463e4044fa78874037d8e8379aa3cabecde32f08a775897eea5a538af android.hardware.secure_element@1.1::ISecureElement
+b53ac9d61c24efb16a2d63a861cef20680f6d57adb244a03b9778c675550628b android.hardware.secure_element@1.1::ISecureElementHalCallback
+3702b1c52c0bb3427244618e9e7975c05228bf4ceb8720da7a93603a71cb0368 android.hardware.sensors@2.0::ISensors
+ae5faa38538a9f50eb71eb7f9b998271124d2c64b761cb11c4d820c7732b4ddc android.hardware.sensors@2.0::ISensorsCallback
+3a98242a57d0820dacaca0f7db52bec433eae1f21c498763c6f1ece611c3967b android.hardware.sensors@2.0::types
+ce4b98211959449361146d4b1e5554dc841ceb4d4577154d7b2fb6d1eb504f76 android.hardware.soundtrigger@2.2::ISoundTriggerHw
+5cc81d517c5f3fef12e719b0f5683c7c99e3e8895fcb80e6f6653b454f463320 android.hardware.thermal@2.0::IThermal
+cc4d2ef36da776c475ad054f0f3416d8a8865def9d9e2129f10074b28e36d203 android.hardware.thermal@2.0::IThermalChangedCallback
+b47f90302595874dfddb19bd05a054727bf18b3a930bc810ea14957b859ae8bf android.hardware.thermal@2.0::types
+61bc302e7c974c59b25898c585c6e9685e8a81021b1bed3eedf5224198f2785a android.hardware.usb@1.2::IUsb
+46996cd2a1c66261a75a1f6ecada77eeb5861eb264fa39b996548fe0a7f22dd3 android.hardware.usb@1.2::IUsbCallback
+3bbaa8cbc5d6b1da21f5509b2b641e05fc7eeca1354751eb1bb3cf37f89aa32f android.hardware.usb@1.2::types
+92c1a726c80970d623b891f7c2f9a989a40a15ee1244092b49f4eb6adcdce4e9 android.hardware.vibrator@1.3::IVibrator
+f19832856a3f53ced5ef91d3cc630a57fb7f4d4ce15f364dbed09099b89f6830 android.hardware.wifi@1.3::IWifi
+7c6799c19bfdb3dec016b751556fe246cf7d37191ee7bb82a0091ab9fbf6f2fb android.hardware.wifi@1.3::IWifiChip
+3bef30e8b61ab050c0f6fd26572712be5ebb7707d624c9aa6c74bbb9d6a5b4a9 android.hardware.wifi@1.3::IWifiStaIface
+f3dbd8dd0d6333c005610288a4785d0ef79a72a7bbe6d0a46d46fa89fc886f1e android.hardware.wifi@1.3::types
+2fae61e962f68091335f7ff4581fcfe2e28ce7f6132d7a712fa13d7965543e4d android.hardware.wifi.hostapd@1.1::IHostapd
+913e66d8790c4e494950f1cbc259173b45d9e7bf9f1e8fc0c6a3623128290f4d android.hardware.wifi.hostapd@1.1::IHostapdCallback
+067b22efc50529a88d650fe7400603429d1164a47ee96a17476fdb0aadd6b4d3 android.hardware.wifi.supplicant@1.2::ISupplicant
+120211371fdd29fb134837071d432a302d7b60e9b95af611dd8dde86bd1f77ee android.hardware.wifi.supplicant@1.2::ISupplicantP2pIface
+7efe2b057e9f9387b3500e67af97942aa7c8008e6ee7d8dcaae4107fda84016b android.hardware.wifi.supplicant@1.2::ISupplicantStaIface
+eb569df2e80f8e276a91a510c75e83fbf957ff1988691726418d44c2be01c520 android.hardware.wifi.supplicant@1.2::ISupplicantStaIfaceCallback
+efbb061c969fa9553d243da6ee23b83fe5d4aa663a7b8896adc52e2b015bc2f3 android.hardware.wifi.supplicant@1.2::ISupplicantStaNetwork
+4851210036650ce6c86498c012db5ff618afce8508a2b06a0e9b902d1840f4bd android.hardware.wifi.supplicant@1.2::types
diff --git a/drm/1.2/Android.bp b/drm/1.2/Android.bp
index fa2962a..4e0e8ba 100644
--- a/drm/1.2/Android.bp
+++ b/drm/1.2/Android.bp
@@ -20,6 +20,7 @@
         "android.hidl.base@1.0",
     ],
     types: [
+        "HdcpLevel",
         "OfflineLicenseState",
         "Status",
     ],
diff --git a/graphics/common/1.2/Android.bp b/graphics/common/1.2/Android.bp
index a3ebdbf..b6cd865 100644
--- a/graphics/common/1.2/Android.bp
+++ b/graphics/common/1.2/Android.bp
@@ -15,9 +15,12 @@
         "android.hardware.graphics.common@1.1",
     ],
     types: [
+        "BufferUsage",
         "ColorMode",
         "Dataspace",
         "HardwareBuffer",
+        "Hdr",
+        "PixelFormat",
     ],
     gen_java: true,
     gen_java_constants: true,
diff --git a/input/common/1.0/Android.bp b/input/common/1.0/Android.bp
index 68a77f1..3de18b4 100644
--- a/input/common/1.0/Android.bp
+++ b/input/common/1.0/Android.bp
@@ -9,9 +9,6 @@
     srcs: [
         "types.hal",
     ],
-    interfaces: [
-        "android.hidl.base@1.0",
-    ],
     types: [
         "Action",
         "Axis",
diff --git a/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworks.cpp b/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworks.cpp
index 1ff3b66..9ebc0aa 100644
--- a/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworks.cpp
+++ b/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworks.cpp
@@ -60,6 +60,12 @@
 
 }  // namespace functional
 }  // namespace vts
+}  // namespace V1_0
+}  // namespace neuralnetworks
+}  // namespace hardware
+}  // namespace android
+
+namespace android::hardware::neuralnetworks::V1_0 {
 
 ::std::ostream& operator<<(::std::ostream& os, ErrorStatus errorStatus) {
     return os << toString(errorStatus);
@@ -69,10 +75,7 @@
     return os << toString(deviceStatus);
 }
 
-}  // namespace V1_0
-}  // namespace neuralnetworks
-}  // namespace hardware
-}  // namespace android
+}  // namespace android::hardware::neuralnetworks::V1_0
 
 using android::hardware::neuralnetworks::V1_0::vts::functional::NeuralnetworksHidlEnvironment;
 
diff --git a/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworks.h b/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworks.h
index e79129b..d4c114d 100644
--- a/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworks.h
+++ b/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworks.h
@@ -72,14 +72,17 @@
 
 }  // namespace functional
 }  // namespace vts
+}  // namespace V1_0
+}  // namespace neuralnetworks
+}  // namespace hardware
+}  // namespace android
+
+namespace android::hardware::neuralnetworks::V1_0 {
 
 // pretty-print values for error messages
 ::std::ostream& operator<<(::std::ostream& os, ErrorStatus errorStatus);
 ::std::ostream& operator<<(::std::ostream& os, DeviceStatus deviceStatus);
 
-}  // namespace V1_0
-}  // namespace neuralnetworks
-}  // namespace hardware
-}  // namespace android
+}  // namespace android::hardware::neuralnetworks::V1_0
 
 #endif  // VTS_HAL_NEURALNETWORKS_V1_0_TARGET_TESTS_H
diff --git a/neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworks.cpp b/neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworks.cpp
index 62381e6..4165953 100644
--- a/neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworks.cpp
+++ b/neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworks.cpp
@@ -60,6 +60,12 @@
 
 }  // namespace functional
 }  // namespace vts
+}  // namespace V1_1
+}  // namespace neuralnetworks
+}  // namespace hardware
+}  // namespace android
+
+namespace android::hardware::neuralnetworks::V1_0 {
 
 ::std::ostream& operator<<(::std::ostream& os, ErrorStatus errorStatus) {
     return os << toString(errorStatus);
@@ -69,10 +75,7 @@
     return os << toString(deviceStatus);
 }
 
-}  // namespace V1_1
-}  // namespace neuralnetworks
-}  // namespace hardware
-}  // namespace android
+}  // namespace android::hardware::neuralnetworks::V1_0
 
 using android::hardware::neuralnetworks::V1_1::vts::functional::NeuralnetworksHidlEnvironment;
 
diff --git a/neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworks.h b/neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworks.h
index 970e8b5..1c8c0e1 100644
--- a/neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworks.h
+++ b/neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworks.h
@@ -81,14 +81,17 @@
 
 }  // namespace functional
 }  // namespace vts
+}  // namespace V1_1
+}  // namespace neuralnetworks
+}  // namespace hardware
+}  // namespace android
+
+namespace android::hardware::neuralnetworks::V1_0 {
 
 // pretty-print values for error messages
 ::std::ostream& operator<<(::std::ostream& os, ErrorStatus errorStatus);
 ::std::ostream& operator<<(::std::ostream& os, DeviceStatus deviceStatus);
 
-}  // namespace V1_1
-}  // namespace neuralnetworks
-}  // namespace hardware
-}  // namespace android
+}  // namespace android::hardware::neuralnetworks::V1_0
 
 #endif  // VTS_HAL_NEURALNETWORKS_V1_1_H
diff --git a/neuralnetworks/1.2/Android.bp b/neuralnetworks/1.2/Android.bp
index 0642dce..daf0c18 100644
--- a/neuralnetworks/1.2/Android.bp
+++ b/neuralnetworks/1.2/Android.bp
@@ -24,6 +24,7 @@
     types: [
         "Constant",
         "DeviceType",
+        "Extension",
         "FmqRequestDatum",
         "FmqResultDatum",
         "MeasureTiming",
diff --git a/neuralnetworks/1.2/types.hal b/neuralnetworks/1.2/types.hal
index 3bddbe8..06bdc6a 100644
--- a/neuralnetworks/1.2/types.hal
+++ b/neuralnetworks/1.2/types.hal
@@ -1528,6 +1528,7 @@
      * Supported tensor {@link OperandType}:
      * * {@link OperandType::TENSOR_FLOAT16} (since API level 29)
      * * {@link OperandType::TENSOR_FLOAT32}
+     * * {@link OperandType::TENSOR_QUANT8_ASYMM} (since API level 29)
      *
      * Supported tensor rank: 4, with "NHWC" or "NCHW" data layout.
      * With the default data layout NHWC, the data is stored in the order of:
@@ -2212,6 +2213,7 @@
      * Supported tensor {@link OperandType}:
      * * {@link OperandType::TENSOR_FLOAT16}
      * * {@link OperandType::TENSOR_FLOAT32}
+     * * {@link OperandType::TENSOR_QUANT16_ASYMM}
      *
      * Inputs:
      * * 0: A 2-D Tensor of shape [num_rois, 4], specifying the locations of the
@@ -2228,7 +2230,8 @@
      *      {@link OperandType::TENSOR_QUANT16_ASYMM}, this tensor should be
      *      of {@link OperandType::TENSOR_QUANT8_ASYMM}.
      * * 2: An 1-D {@link OperandType::TENSOR_INT32} tensor, of shape
-     *      [batches], specifying the number of output boxes for each batch.
+     *      [num_rois], specifying the batch index of each box. Boxes with
+     *      the same batch index are grouped together.
      * * 3: A 2-D Tensor of shape [batches, 2], specifying the information of
      *      each image in the batch, each line with format
      *      [image_height, image_width].
@@ -2557,8 +2560,9 @@
      *      {@link OperandType::TENSOR_QUANT8_ASYMM}, this tensor should be of
      *      {@link OperandType::TENSOR_QUANT16_ASYMM}, with zeroPoint of 0 and
      *      scale of 0.125.
-     * * 2: A 1-D Tensor of shape [batches], specifying the number of boxes
-     *      for each image in the batch.
+     * * 2: A 1-D {@link OperandType::TENSOR_INT32} tensor, of shape
+     *      [num_rois], specifying the batch index of each box. Boxes with
+     *      the same batch index are grouped together.
      * * 3: An {@link OperandType::FLOAT32} scalar, score_threshold. Boxes
      *      with scores lower than the threshold are filtered before sending
      *      to the NMS algorithm.
@@ -2584,7 +2588,8 @@
      *      [num_output_rois], specifying the class of each output box. The
      *      sequential order of the boxes corresponds with output0.
      * * 3: A 1-D {@link OperandType::TENSOR_INT32} tensor, of shape
-     *      [batches], specifying the number of output boxes for each image.
+     *      [num_rois], specifying the batch index of each box. Boxes with
+     *      the same batch index are grouped together.
      *
      * Available since API level 29.
      */
@@ -2878,6 +2883,9 @@
      *      {@link OperandType::TENSOR_QUANT16_SYMM}, with scale of 0.125.
      * * 3: A 2-D Tensor of shape [batches, 2], specifying the size of
      *      each image in the batch, with format [image_height, image_width].
+     *      For input0 of type {@link OperandType::TENSOR_QUANT8_ASYMM}, this
+     *      tensor should be of {@link OperandType::TENSOR_QUANT16_SYMM}, with
+     *      scale of 0.125.
      * * 4: An {@link OperandType::FLOAT32} scalar, specifying the ratio
      *      from the height of original image to the height of feature map.
      * * 5: An {@link OperandType::FLOAT32} scalar, specifying the ratio
@@ -2904,14 +2912,15 @@
      *      each batch is not guaranteed. For type of
      *      {@link OperandType::TENSOR_QUANT8_ASYMM}, the scale and zero
      *      point must be the same as input0.
-     * * 1: A tensor of the same {@link OperandType} as input1, of shape
+     * * 1: A tensor of the same {@link OperandType} as input3, of shape
      *      [num_output_rois, 4], specifying the coordinates of each output
      *      bounding box for each class, with format [x1, y1, x2, y2].
      *      The sequential order of the boxes corresponds with output0.
      *      For type of {@link OperandType::TENSOR_QUANT16_ASYMM}, the
      *      scale must be 0.125 and the zero point must be 0.
      * * 2: A 1-D {@link OperandType::TENSOR_INT32} tensor, of shape
-     *      [batches], specifying the number of output boxes for each image.
+     *      [num_rois], specifying the batch index of each box. Boxes with
+     *      the same batch index are grouped together.
      *
      * Available since API level 29.
      */
@@ -3904,7 +3913,8 @@
      *      this tensor should be of {@link OperandType::TENSOR_QUANT16_ASYMM},
      *      with zeroPoint of 0 and scale of 0.125.
      * * 2: An 1-D {@link OperandType::TENSOR_INT32} tensor, of shape
-     *      [batches], specifying the number of output boxes for each batch.
+     *      [num_rois], specifying the batch index of each box. Boxes with
+     *      the same batch index are grouped together.
      * * 3: An {@link OperandType::INT32} scalar, specifying the output
      *      height of the output tensor.
      * * 4: An {@link OperandType::INT32} scalar, specifying the output
@@ -3960,7 +3970,8 @@
      *      this tensor should be of {@link OperandType::TENSOR_QUANT16_ASYMM},
      *      with zeroPoint of 0 and scale of 0.125.
      * * 2: An 1-D {@link OperandType::TENSOR_INT32} tensor, of shape
-     *      [batches], specifying the number of output boxes for each batch.
+     *      [num_rois], specifying the batch index of each box. Boxes with
+     *      the same batch index are grouped together.
      * * 3: An {@link OperandType::INT32} scalar, specifying the output
      *      height of the output tensor.
      * * 4: An {@link OperandType::INT32} scalar, specifying the output
@@ -4441,6 +4452,42 @@
      * Available since API level 29.
      */
     UNIDIRECTIONAL_SEQUENCE_RNN = 93,
+
+    /**
+     * Resizes images to given size using the nearest neighbor interpretation.
+     *
+     * Resized images must be distorted if their output aspect ratio is not the
+     * same as input aspect ratio. The corner pixels of output may not be the
+     * same as corner pixels of input.
+     *
+     * Supported tensor {@link OperandType}:
+     * * {@link OperandType::TENSOR_FLOAT16}
+     * * {@link OperandType::TENSOR_FLOAT32}
+     * * {@link OperandType::TENSOR_QUANT8_ASYMM}
+     *
+     * Supported tensor rank: 4, with "NHWC" or "NCHW" data layout.
+     * With the default data layout NHWC, the data is stored in the order of:
+     * [batch, height, width, channels]. Alternatively, the data layout could
+     * be NCHW, the data storage order of: [batch, channels, height, width].
+     *
+     * Inputs:
+     * * 0: A 4-D tensor, of shape [batches, height, width, depth], specifying
+     *      the input.
+     * * 1: An {@link OperandType::INT32} scalar, specifying the output
+     *      height of the output tensor.
+     * * 2: An {@link OperandType::INT32} scalar, specifying the output
+     *      width of the output tensor.
+     * * 3: An {@link OperandType::BOOL} scalar, default to false.
+     *      Set to true to specify NCHW data layout for input0 and output0.
+     *
+     * Outputs:
+     * * 0: The output 4-D tensor, of shape
+     *      [batches, new_height, new_width, depth].
+     *
+     * Available since API level 29.
+     */
+    RESIZE_NEAREST_NEIGHBOR = 94,
+
     /**
      * DEPRECATED. Since NNAPI 1.2, extensions are the preferred alternative to
      * OEM operation and data types.
@@ -4463,7 +4510,7 @@
 enum OperationTypeRange : uint32_t {
     BASE_MIN        = 0,
     FUNDAMENTAL_MIN = 0,
-    FUNDAMENTAL_MAX = 93,
+    FUNDAMENTAL_MAX = 94,
     OEM_MIN         = 10000,
     OEM_MAX         = 10000,
     BASE_MAX        = 0xFFFF,
diff --git a/neuralnetworks/1.2/vts/functional/CompilationCachingTests.cpp b/neuralnetworks/1.2/vts/functional/CompilationCachingTests.cpp
index 454aa1f..00989e5 100644
--- a/neuralnetworks/1.2/vts/functional/CompilationCachingTests.cpp
+++ b/neuralnetworks/1.2/vts/functional/CompilationCachingTests.cpp
@@ -86,14 +86,22 @@
   protected:
     void SetUp() override {
         NeuralnetworksHidlTest::SetUp();
+        ASSERT_NE(device.get(), nullptr);
 
-        // Create cache directory.
+        // Create cache directory. The cache directory and cache files are always created to test
+        // the behavior of prepareModelFromCache, even when caching is not supported.
         char cacheDirTemp[] = "/data/local/tmp/TestCompilationCachingXXXXXX";
         char* cacheDir = mkdtemp(cacheDirTemp);
         ASSERT_NE(cacheDir, nullptr);
-        mCache1 = cacheDir + mCache1;
-        mCache2 = cacheDir + mCache2;
-        mCache3 = cacheDir + mCache3;
+        mCacheDir = cacheDir;
+
+        // Create empty cache files.
+        mCache1 = mCacheDir + "/cache1";
+        mCache2 = mCacheDir + "/cache2";
+        mCache3 = mCacheDir + "/cache3";
+        // A dummy handle, use AccessMode::WRITE_ONLY for createCacheHandle to create files.
+        hidl_handle handle;
+        createCacheHandle({mCache1, mCache2, mCache3}, AccessMode::WRITE_ONLY, &handle);
 
         // Check if caching is supported.
         bool isCachingSupported;
@@ -113,10 +121,18 @@
                       << std::endl;
             mIsCachingSupported = false;
         }
+    }
 
-        // Create empty cache files.
-        hidl_handle handle;
-        createCacheHandle({mCache1, mCache2, mCache3}, AccessMode::WRITE_ONLY, &handle);
+    void TearDown() override {
+        // The tmp directory is only removed when the driver reports caching not supported,
+        // otherwise it is kept for debugging purpose.
+        if (!mIsCachingSupported) {
+            remove(mCache1.c_str());
+            remove(mCache2.c_str());
+            remove(mCache3.c_str());
+            rmdir(mCacheDir.c_str());
+        }
+        NeuralnetworksHidlTest::TearDown();
     }
 
     void saveModelToCache(sp<IPreparedModel> preparedModel, const hidl_handle& cache1,
@@ -163,9 +179,10 @@
                                  .withDefault(nullptr);
     }
 
-    std::string mCache1 = "/cache1";
-    std::string mCache2 = "/cache2";
-    std::string mCache3 = "/cache3";
+    std::string mCacheDir;
+    std::string mCache1;
+    std::string mCache2;
+    std::string mCache3;
     uint8_t mToken[static_cast<uint32_t>(Constant::BYTE_SIZE_OF_CACHE_TOKEN)] = {};
     bool mIsCachingSupported;
 };
diff --git a/neuralnetworks/1.2/vts/functional/VtsHalNeuralnetworks.cpp b/neuralnetworks/1.2/vts/functional/VtsHalNeuralnetworks.cpp
index 4eced82..34c73ef 100644
--- a/neuralnetworks/1.2/vts/functional/VtsHalNeuralnetworks.cpp
+++ b/neuralnetworks/1.2/vts/functional/VtsHalNeuralnetworks.cpp
@@ -66,6 +66,12 @@
 
 }  // namespace functional
 }  // namespace vts
+}  // namespace V1_2
+}  // namespace neuralnetworks
+}  // namespace hardware
+}  // namespace android
+
+namespace android::hardware::neuralnetworks::V1_0 {
 
 ::std::ostream& operator<<(::std::ostream& os, ErrorStatus errorStatus) {
     return os << toString(errorStatus);
@@ -75,10 +81,7 @@
     return os << toString(deviceStatus);
 }
 
-}  // namespace V1_2
-}  // namespace neuralnetworks
-}  // namespace hardware
-}  // namespace android
+}  // namespace android::hardware::neuralnetworks::V1_0
 
 using android::hardware::neuralnetworks::V1_2::vts::functional::NeuralnetworksHidlEnvironment;
 
diff --git a/neuralnetworks/1.2/vts/functional/VtsHalNeuralnetworks.h b/neuralnetworks/1.2/vts/functional/VtsHalNeuralnetworks.h
index c0c21bd..404eec0 100644
--- a/neuralnetworks/1.2/vts/functional/VtsHalNeuralnetworks.h
+++ b/neuralnetworks/1.2/vts/functional/VtsHalNeuralnetworks.h
@@ -88,14 +88,17 @@
 
 }  // namespace functional
 }  // namespace vts
+}  // namespace V1_2
+}  // namespace neuralnetworks
+}  // namespace hardware
+}  // namespace android
+
+namespace android::hardware::neuralnetworks::V1_0 {
 
 // pretty-print values for error messages
 ::std::ostream& operator<<(::std::ostream& os, ErrorStatus errorStatus);
 ::std::ostream& operator<<(::std::ostream& os, DeviceStatus deviceStatus);
 
-}  // namespace V1_2
-}  // namespace neuralnetworks
-}  // namespace hardware
-}  // namespace android
+}  // namespace android::hardware::neuralnetworks::V1_0
 
 #endif  // VTS_HAL_NEURALNETWORKS_V1_2_H
diff --git a/radio/1.4/IRadio.hal b/radio/1.4/IRadio.hal
index 8ef1f96..f7ae39f 100644
--- a/radio/1.4/IRadio.hal
+++ b/radio/1.4/IRadio.hal
@@ -128,9 +128,11 @@
      * does not support the emergency service category or emergency uniform resource names, the
      * field 'categories' or 'urns' may be ignored.
      *
-     * 'fromEmergencyDialer' indicates if this request originated from emergency dialer/shortcut,
-     * which means an explicit intent from the user to dial an emergency number. The modem must
-     * treat this as an actual emergency dial and not try to disambiguate.
+     * In the scenarios that the 'address' in the 'dialInfo' field has other functions besides the
+     * emergency number function, if the 'hasKnownUserIntentEmergency' field is true, the user's
+     * intent for this dial request is emergency call, and the modem must treat this as an actual
+     * emergency dial; if the 'hasKnownUserIntentEmergency' field is false, Android does not know
+     * user's intent for this call.
      *
      * If 'isTesting' is true, this request is for testing purpose, and must not be sent to a real
      * emergency service; otherwise it's for a real emergency call request.
@@ -146,14 +148,15 @@
      *     of the call.
      * @param urns the emergency Uniform Resource Names (URN)
      * @param routing @1.4::EmergencyCallRouting the emergency call routing information.
-     * @param fromEmergencyDialer Flag indicating if this request originated from emergency dialer.
+     * @param hasKnownUserIntentEmergency Flag indicating if user's intent for the emergency call
+     *     is known.
      * @param isTesting Flag indicating if this request is for testing purpose.
      *
      * Response function is IRadioResponse.emergencyDialResponse()
      */
     oneway emergencyDial(int32_t serial, Dial dialInfo,
             bitfield<EmergencyServiceCategory> categories, vec<string> urns,
-            EmergencyCallRouting routing, bool fromEmergencyDialer, bool isTesting);
+            EmergencyCallRouting routing, bool hasKnownUserIntentEmergency, bool isTesting);
 
     /**
      * Starts a network scan
diff --git a/radio/1.4/types.hal b/radio/1.4/types.hal
index 2747732..dc3bba0 100644
--- a/radio/1.4/types.hal
+++ b/radio/1.4/types.hal
@@ -1789,15 +1789,25 @@
 };
 
 struct CellIdentityNr {
-    /** 3-digit Mobile Country Code, in range[0, 999], INT_MAX means invalid/unreported. */
+    /** 3-digit Mobile Country Code, in range[0, 999]; This value must be valid for registered or
+     *  camped cells; INT_MAX means invalid/unreported.
+     */
     string mcc;
 
     /**
-     * 2 or 3-digit Mobile Network Code, in range [0, 999], INT_MAX means invalid/unreported.
+     * 2 or 3-digit Mobile Network Code, in range [0, 999], This value must be valid for
+     * registered or camped cells; INT_MAX means invalid/unreported.
      */
     string mnc;
 
     /**
+     * NR Cell Identity in range [0, 68719476735] (36 bits) described in 3GPP TS 38.331, which
+     * unambiguously identifies a cell within a PLMN. This value must be valid for registered or
+     * camped cells; LONG_MAX (2^63-1) means invalid/unreported.
+     */
+    uint64_t nci;
+
+    /**
      * Physical cell id in range [0, 1007] described in 3GPP TS 38.331. This value must be valid.
      */
     uint32_t pci;
diff --git a/radio/1.4/vts/functional/radio_hidl_hal_api.cpp b/radio/1.4/vts/functional/radio_hidl_hal_api.cpp
index 6b1f85e..9237799 100644
--- a/radio/1.4/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.4/vts/functional/radio_hidl_hal_api.cpp
@@ -16,4 +16,81 @@
 
 #include <radio_hidl_hal_utils_v1_4.h>
 
-#define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk())
\ No newline at end of file
+#define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk())
+
+/*
+ * Test IRadio.emergencyDial() for the response returned.
+ */
+TEST_F(RadioHidlTest_v1_4, emergencyDial) {
+    serial = GetRandomSerialNumber();
+
+    ::android::hardware::radio::V1_0::Dial dialInfo;
+    dialInfo.address = hidl_string("911");
+    int categories = static_cast<int>(
+            ::android::hardware::radio::V1_4::EmergencyServiceCategory::UNSPECIFIED);
+    std::vector<hidl_string> urns = {""};
+    ::android::hardware::radio::V1_4::EmergencyCallRouting routing =
+            ::android::hardware::radio::V1_4::EmergencyCallRouting::UNKNOWN;
+
+    Return<void> res =
+            radio_v1_4->emergencyDial(serial, dialInfo, categories, urns, routing, true, true);
+    ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_4->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_v1_4->rspInfo.serial);
+
+    ALOGI("emergencyDial, rspInfo.error = %s\n", toString(radioRsp_v1_4->rspInfo.error).c_str());
+    EXPECT_EQ(RadioError::NONE, radioRsp_v1_4->rspInfo.error);
+}
+
+/*
+ * Test IRadio.emergencyDial() with specified service and its response returned.
+ */
+TEST_F(RadioHidlTest_v1_4, emergencyDial_withServices) {
+    serial = GetRandomSerialNumber();
+
+    ::android::hardware::radio::V1_0::Dial dialInfo;
+    dialInfo.address = hidl_string("911");
+    int categories =
+            static_cast<int>(::android::hardware::radio::V1_4::EmergencyServiceCategory::AMBULANCE);
+    std::vector<hidl_string> urns = {"urn:service:sos.ambulance"};
+    ::android::hardware::radio::V1_4::EmergencyCallRouting routing =
+            ::android::hardware::radio::V1_4::EmergencyCallRouting::UNKNOWN;
+
+    Return<void> res =
+            radio_v1_4->emergencyDial(serial, dialInfo, categories, urns, routing, true, true);
+    ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_4->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_v1_4->rspInfo.serial);
+
+    ALOGI("emergencyDial_withServices, rspInfo.error = %s\n",
+          toString(radioRsp_v1_4->rspInfo.error).c_str());
+    EXPECT_EQ(RadioError::NONE, radioRsp_v1_4->rspInfo.error);
+}
+
+/*
+ * Test IRadio.emergencyDial() with known emergency call routing and its response returned.
+ */
+TEST_F(RadioHidlTest_v1_4, emergencyDial_withEmergencyRouting) {
+    serial = GetRandomSerialNumber();
+
+    ::android::hardware::radio::V1_0::Dial dialInfo;
+    dialInfo.address = hidl_string("911");
+    int categories = static_cast<int>(
+            ::android::hardware::radio::V1_4::EmergencyServiceCategory::UNSPECIFIED);
+    std::vector<hidl_string> urns = {""};
+    ::android::hardware::radio::V1_4::EmergencyCallRouting routing =
+            ::android::hardware::radio::V1_4::EmergencyCallRouting::EMERGENCY;
+
+    Return<void> res =
+            radio_v1_4->emergencyDial(serial, dialInfo, categories, urns, routing, true, true);
+    ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_4->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_v1_4->rspInfo.serial);
+
+    ALOGI("emergencyDial_withEmergencyRouting, rspInfo.error = %s\n",
+          toString(radioRsp_v1_4->rspInfo.error).c_str());
+    EXPECT_EQ(RadioError::NONE, radioRsp_v1_4->rspInfo.error);
+}
\ No newline at end of file
diff --git a/sensors/2.0/Android.bp b/sensors/2.0/Android.bp
index 3b948a9..57d45ff 100644
--- a/sensors/2.0/Android.bp
+++ b/sensors/2.0/Android.bp
@@ -18,6 +18,7 @@
     types: [
         "EventQueueFlagBits",
         "SensorTimeout",
+        "WakeLockQueueFlagBits",
     ],
     gen_java: false,
 }
diff --git a/sensors/2.0/default/Android.bp b/sensors/2.0/default/Android.bp
index d83a9c3..d05634b 100644
--- a/sensors/2.0/default/Android.bp
+++ b/sensors/2.0/default/Android.bp
@@ -14,7 +14,7 @@
 // limitations under the License.
 
 cc_binary {
-    name: "android.hardware.sensors@2.0-service",
+    name: "android.hardware.sensors@2.0-service.mock",
     defaults: ["hidl_defaults"],
     vendor: true,
     relative_install_path: "hw",
diff --git a/sensors/2.0/default/android.hardware.sensors@2.0-service.rc b/sensors/2.0/default/android.hardware.sensors@2.0-service.rc
index 321d760..1fee4f2 100644
--- a/sensors/2.0/default/android.hardware.sensors@2.0-service.rc
+++ b/sensors/2.0/default/android.hardware.sensors@2.0-service.rc
@@ -1,4 +1,4 @@
-service vendor.sensors-hal-2-0 /vendor/bin/hw/android.hardware.sensors@2.0-service
+service vendor.sensors-hal-2-0-mock /vendor/bin/hw/android.hardware.sensors@2.0-service.mock
     class hal
     user system
     group system
diff --git a/wifi/1.3/Android.bp b/wifi/1.3/Android.bp
index 45e2e88..8af1dc4 100644
--- a/wifi/1.3/Android.bp
+++ b/wifi/1.3/Android.bp
@@ -19,9 +19,9 @@
         "android.hidl.base@1.0",
     ],
     types: [
-      "StaLinkLayerRadioStats",
-      "StaLinkLayerStats",
-      "WifiChannelStats",
+        "StaLinkLayerRadioStats",
+        "StaLinkLayerStats",
+        "WifiChannelStats",
     ],
     gen_java: true,
 }
diff --git a/wifi/1.3/default/hidl_struct_util.cpp b/wifi/1.3/default/hidl_struct_util.cpp
index 49c1477..2e4db70 100644
--- a/wifi/1.3/default/hidl_struct_util.cpp
+++ b/wifi/1.3/default/hidl_struct_util.cpp
@@ -1259,10 +1259,6 @@
         hidl_request.debugConfigs
             .useSdfInBandVal[(size_t)NanBandIndex::NAN_BAND_5GHZ];
 
-    // disable NANv3 NDPe
-    legacy_request->config_ndpe_attr = 1;
-    legacy_request->use_ndpe_attr = 0;
-
     return true;
 }
 
@@ -1774,10 +1770,6 @@
         hidl_request.bandSpecificConfig[(size_t)NanBandIndex::NAN_BAND_5GHZ]
             .discoveryWindowIntervalVal;
 
-    // disable NANv3 NDPe
-    legacy_request->config_ndpe_attr = 1;
-    legacy_request->use_ndpe_attr = 0;
-
     return true;
 }
 
diff --git a/wifi/supplicant/1.2/Android.bp b/wifi/supplicant/1.2/Android.bp
index 18e1cca..addcc2a 100644
--- a/wifi/supplicant/1.2/Android.bp
+++ b/wifi/supplicant/1.2/Android.bp
@@ -7,12 +7,12 @@
         enabled: true,
     },
     srcs: [
+        "types.hal",
         "ISupplicant.hal",
         "ISupplicantP2pIface.hal",
         "ISupplicantStaIface.hal",
         "ISupplicantStaIfaceCallback.hal",
         "ISupplicantStaNetwork.hal",
-        "types.hal",
     ],
     interfaces: [
         "android.hardware.wifi.supplicant@1.0",
@@ -21,10 +21,10 @@
     ],
     types: [
         "DppAkm",
-        "DppNetRole",
-        "DppSuccessCode",
-        "DppProgressCode",
         "DppFailureCode",
+        "DppNetRole",
+        "DppProgressCode",
+        "DppSuccessCode",
     ],
     gen_java: true,
 }