Merge "Camera: Enable session parameter reconfiguration queries"
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/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/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 3e3ef43..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);
@@ -473,6 +488,43 @@
    }
 }
 
+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:
@@ -487,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 32c387f..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>
@@ -69,6 +72,10 @@
     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
     static void deriveCameraCharacteristicsKeys(uint32_t deviceVersion, CameraMetadata &chars);
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/metadata/3.4/Android.bp b/camera/metadata/3.4/Android.bp
index 17a2675..d1cba14 100644
--- a/camera/metadata/3.4/Android.bp
+++ b/camera/metadata/3.4/Android.bp
@@ -14,10 +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/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/current.txt b/current.txt
index 478cbc5..0b58830 100644
--- a/current.txt
+++ b/current.txt
@@ -406,3 +406,40 @@
 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
+44480c912e4ab90b9ed17e56569cd5ca98413a8a2372efb028f4181204b6b73e android.hardware.fastboot@1.0::IFastboot
+7b2989744e3c555292d4b5b829acd09a7b40f96ead62ce54174cd959503b64bb android.hardware.fastboot@1.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
+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
+a42fb6a33e242e0035de32cdcd4b743d46ae93d65a1e316f3bffe7218ade82cb 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
+b2dfa12706a1633c387f2ae0a911021b98fe0ecacf5e14a3776053a27d606050 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
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.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/vts/functional/CompilationCachingTests.cpp b/neuralnetworks/1.2/vts/functional/CompilationCachingTests.cpp
index 454aa1f..d715d24 100644
--- a/neuralnetworks/1.2/vts/functional/CompilationCachingTests.cpp
+++ b/neuralnetworks/1.2/vts/functional/CompilationCachingTests.cpp
@@ -86,6 +86,7 @@
   protected:
     void SetUp() override {
         NeuralnetworksHidlTest::SetUp();
+        ASSERT_NE(device.get(), nullptr);
 
         // Create cache directory.
         char cacheDirTemp[] = "/data/local/tmp/TestCompilationCachingXXXXXX";
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/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,
 }