Merge "[DPP] Add "Not supported" failure code for DPP."
diff --git a/.clang-format b/.clang-format
index 9b3f9d9..3494682 100644
--- a/.clang-format
+++ b/.clang-format
@@ -22,3 +22,4 @@
 TabWidth: 4
 UseTab: Never
 IndentWidth: 4
+ContinuationIndentWidth: 8
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
index a5c8eb8..7614cad 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
@@ -36,10 +36,12 @@
 constexpr int DOOR_1_RIGHT = (int)VehicleAreaDoor::ROW_1_RIGHT;
 constexpr int DOOR_2_LEFT = (int)VehicleAreaDoor::ROW_2_LEFT;
 constexpr int DOOR_2_RIGHT = (int)VehicleAreaDoor::ROW_2_RIGHT;
+constexpr int DOOR_REAR = (int)VehicleAreaDoor::REAR;
 constexpr int WINDOW_1_LEFT = (int)VehicleAreaWindow::ROW_1_LEFT;
 constexpr int WINDOW_1_RIGHT = (int)VehicleAreaWindow::ROW_1_RIGHT;
 constexpr int WINDOW_2_LEFT = (int)VehicleAreaWindow::ROW_2_LEFT;
 constexpr int WINDOW_2_RIGHT = (int)VehicleAreaWindow::ROW_2_RIGHT;
+constexpr int WINDOW_ROOF_TOP_1 = (int)VehicleAreaWindow::ROOF_TOP_1;
 constexpr int FAN_DIRECTION_FACE = (int)VehicleHvacFanDirection::FACE;
 constexpr int FAN_DIRECTION_FLOOR = (int)VehicleHvacFanDirection::FLOOR;
 constexpr int OBD2_LIVE_FRAME = (int)VehicleProperty::OBD2_LIVE_FRAME;
@@ -581,17 +583,18 @@
                            {DOOR_2_LEFT, {.int32Values = {1}}},
                            {DOOR_2_RIGHT, {.int32Values = {1}}}}},
 
-    {.config = {.prop = toInt(VehicleProperty::DOOR_POS),
-                .access = VehiclePropertyAccess::READ_WRITE,
-                .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                .areaConfigs = {VehicleAreaConfig{.areaId = DOOR_1_LEFT},
-                                VehicleAreaConfig{.areaId = DOOR_1_RIGHT},
-                                VehicleAreaConfig{.areaId = DOOR_2_LEFT},
-                                VehicleAreaConfig{.areaId = DOOR_2_RIGHT}}},
-     .initialAreaValues = {{DOOR_1_LEFT, {.int32Values = {0}}},
-                           {DOOR_1_RIGHT, {.int32Values = {0}}},
-                           {DOOR_2_LEFT, {.int32Values = {0}}},
-                           {DOOR_2_RIGHT, {.int32Values = {0}}}}},
+    {.config =
+         {
+             .prop = toInt(VehicleProperty::DOOR_POS),
+             .access = VehiclePropertyAccess::READ_WRITE,
+             .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+             .areaConfigs =
+                 {VehicleAreaConfig{.areaId = DOOR_1_LEFT, .minInt32Value = 0, .maxInt32Value = 1},
+                  VehicleAreaConfig{.areaId = DOOR_1_RIGHT, .minInt32Value = 0, .maxInt32Value = 1},
+                  VehicleAreaConfig{.areaId = DOOR_2_LEFT, .minInt32Value = 0, .maxInt32Value = 1},
+                  VehicleAreaConfig{.areaId = DOOR_2_RIGHT, .minInt32Value = 0, .maxInt32Value = 1},
+                  VehicleAreaConfig{.areaId = DOOR_REAR, .minInt32Value = 0, .maxInt32Value = 1}}},
+     .initialValue = {.int32Values = {0}}},
 
     {.config = {.prop = toInt(VehicleProperty::WINDOW_LOCK),
                 .access = VehiclePropertyAccess::READ_WRITE,
@@ -601,17 +604,19 @@
      .initialAreaValues = {{WINDOW_1_RIGHT | WINDOW_2_LEFT | WINDOW_2_RIGHT,
                             {.int32Values = {0}}}}},
 
-    {.config = {.prop = toInt(VehicleProperty::WINDOW_POS),
-                .access = VehiclePropertyAccess::READ_WRITE,
-                .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                .areaConfigs = {VehicleAreaConfig{.areaId = WINDOW_1_LEFT},
-                                VehicleAreaConfig{.areaId = WINDOW_1_RIGHT},
-                                VehicleAreaConfig{.areaId = WINDOW_2_LEFT},
-                                VehicleAreaConfig{.areaId = WINDOW_2_RIGHT}}},
-     .initialAreaValues = {{WINDOW_1_LEFT, {.int32Values = {0}}},
-                           {WINDOW_1_RIGHT, {.int32Values = {0}}},
-                           {WINDOW_2_LEFT, {.int32Values = {0}}},
-                           {WINDOW_2_RIGHT, {.int32Values = {0}}}}},
+    {.config =
+         {.prop = toInt(VehicleProperty::WINDOW_POS),
+          .access =
+              VehiclePropertyAccess::READ_WRITE,
+          .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+          .areaConfigs =
+              {VehicleAreaConfig{.areaId = WINDOW_1_LEFT, .minInt32Value = 0, .maxInt32Value = 10},
+               VehicleAreaConfig{.areaId = WINDOW_1_RIGHT, .minInt32Value = 0, .maxInt32Value = 10},
+               VehicleAreaConfig{.areaId = WINDOW_2_LEFT, .minInt32Value = 0, .maxInt32Value = 10},
+               VehicleAreaConfig{.areaId = WINDOW_2_RIGHT, .minInt32Value = 0, .maxInt32Value = 10},
+               VehicleAreaConfig{
+                   .areaId = WINDOW_ROOF_TOP_1, .minInt32Value = -10, .maxInt32Value = 10}}},
+     .initialValue = {.int32Values = {0}}},
 
     {.config =
          {
diff --git a/camera/device/3.4/types.hal b/camera/device/3.4/types.hal
index bf2b3fc..8ee826b 100644
--- a/camera/device/3.4/types.hal
+++ b/camera/device/3.4/types.hal
@@ -164,6 +164,9 @@
      * If non-zero, read settings from request queue instead
      * (see ICameraDeviceSession.getCaptureRequestMetadataQueue).
      * If zero, read settings from .settings field.
+     *
+     * The v3_2 settings metadata is read first from the FMQ, followed by
+     * the physical cameras' settings metadata starting from index 0.
      */
     uint64_t fmqSettingsSize;
 
@@ -238,6 +241,9 @@
      * If non-zero, read metadata from result metadata queue instead
      * (see ICameraDeviceSession.getCaptureResultMetadataQueue).
      * If zero, read metadata from .metadata field.
+     *
+     * The v3_2 CaptureResult metadata is read first from the FMQ, followed by
+     * the physical cameras' metadata starting from index 0.
      */
     uint64_t fmqMetadataSize;
 
@@ -251,9 +257,6 @@
     /**
      * If fmqMetadataSize is zero, the metadata buffer contains the metadata
      * for the physical device with physicalCameraId.
-     *
-     * The v3_2 CaptureResult metadata is read first from the FMQ, followed by
-     * the physical cameras' metadata starting from index 0.
      */
     CameraMetadata metadata;
 };
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index e376551..60db5df 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -715,7 +715,8 @@
             StreamConfigurationMode configMode,
             ::android::hardware::camera::device::V3_2::StreamConfiguration *config3_2,
             ::android::hardware::camera::device::V3_4::StreamConfiguration *config3_4,
-            ::android::hardware::camera::device::V3_5::StreamConfiguration *config3_5);
+            ::android::hardware::camera::device::V3_5::StreamConfiguration *config3_5,
+            uint32_t jpegBufferSize = 0);
 
     void configurePreviewStreams3_4(const std::string &name, int32_t deviceVersion,
             sp<ICameraProvider> provider,
@@ -766,6 +767,8 @@
     static Status getAvailableOutputStreams(camera_metadata_t *staticMeta,
             std::vector<AvailableStream> &outputStreams,
             const AvailableStream *threshold = nullptr);
+    static Status getJpegBufferSize(camera_metadata_t *staticMeta,
+            uint32_t* outBufSize);
     static Status isConstrainedModeAvailable(camera_metadata_t *staticMeta);
     static Status isLogicalMultiCamera(const camera_metadata_t *staticMeta);
     static Status getPhysicalCameraIds(const camera_metadata_t *staticMeta,
@@ -2786,6 +2789,10 @@
         ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputStreams));
         ASSERT_NE(0u, outputStreams.size());
 
+        uint32_t jpegBufferSize = 0;
+        ASSERT_EQ(Status::OK, getJpegBufferSize(staticMeta, &jpegBufferSize));
+        ASSERT_NE(0u, jpegBufferSize);
+
         int32_t streamId = 0;
         uint32_t streamConfigCounter = 0;
         for (auto& it : outputStreams) {
@@ -2804,7 +2811,7 @@
             ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4;
             ::android::hardware::camera::device::V3_2::StreamConfiguration config3_2;
             createStreamConfiguration(streams3_2, StreamConfigurationMode::NORMAL_MODE,
-                                      &config3_2, &config3_4, &config3_5);
+                                      &config3_2, &config3_4, &config3_5, jpegBufferSize);
             if (session3_5 != nullptr) {
                 verifyStreamCombination(cameraDevice3_5, config3_4,
                         /*expectedStatus*/ true);
@@ -2879,6 +2886,10 @@
         ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputStreams));
         ASSERT_NE(0u, outputStreams.size());
 
+        uint32_t jpegBufferSize = 0;
+        ASSERT_EQ(Status::OK, getJpegBufferSize(staticMeta, &jpegBufferSize));
+        ASSERT_NE(0u, jpegBufferSize);
+
         int32_t streamId = 0;
         V3_2::Stream stream3_2 = {streamId++,
                          StreamType::OUTPUT,
@@ -2894,7 +2905,7 @@
         ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4;
         ::android::hardware::camera::device::V3_2::StreamConfiguration config3_2;
         createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE,
-                                  &config3_2, &config3_4, &config3_5);
+                                  &config3_2, &config3_4, &config3_5, jpegBufferSize);
         if (session3_5 != nullptr) {
             verifyStreamCombination(cameraDevice3_5, config3_4, /*expectedStatus*/ false);
             config3_5.streamConfigCounter = streamConfigCounter++;
@@ -2934,7 +2945,7 @@
                   StreamRotation::ROTATION_0};
         streams[0] = stream3_2;
         createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE,
-                &config3_2, &config3_4, &config3_5);
+                &config3_2, &config3_4, &config3_5, jpegBufferSize);
         if (session3_5 != nullptr) {
             config3_5.streamConfigCounter = streamConfigCounter++;
             ret = session3_5->configureStreams_3_5(config3_5, [](Status s,
@@ -2970,7 +2981,7 @@
                       StreamRotation::ROTATION_0};
             streams[0] = stream3_2;
             createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE,
-                    &config3_2, &config3_4, &config3_5);
+                    &config3_2, &config3_4, &config3_5, jpegBufferSize);
             if (session3_5 != nullptr) {
                 config3_5.streamConfigCounter = streamConfigCounter++;
                 ret = session3_5->configureStreams_3_5(config3_5,
@@ -3005,7 +3016,7 @@
                       static_cast<StreamRotation>(UINT32_MAX)};
             streams[0] = stream3_2;
             createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE,
-                    &config3_2, &config3_4, &config3_5);
+                    &config3_2, &config3_4, &config3_5, jpegBufferSize);
             if (session3_5 != nullptr) {
                 config3_5.streamConfigCounter = streamConfigCounter++;
                 ret = session3_5->configureStreams_3_5(config3_5,
@@ -3093,6 +3104,10 @@
             }
         }
 
+        uint32_t jpegBufferSize = 0;
+        ASSERT_EQ(Status::OK, getJpegBufferSize(staticMeta, &jpegBufferSize));
+        ASSERT_NE(0u, jpegBufferSize);
+
         int32_t streamId = 0;
         bool hasPrivToY8 = false, hasY8ToY8 = false, hasY8ToBlob = false;
         uint32_t streamConfigCounter = 0;
@@ -3150,7 +3165,7 @@
                 ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4;
                 ::android::hardware::camera::device::V3_2::StreamConfiguration config3_2;
                 createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE,
-                                          &config3_2, &config3_4, &config3_5);
+                                          &config3_2, &config3_4, &config3_5, jpegBufferSize);
                 if (session3_5 != nullptr) {
                     verifyStreamCombination(cameraDevice3_5, config3_4,
                             /*expectedStatus*/ true);
@@ -3199,7 +3214,7 @@
     }
 }
 
-// Check wehether session parameters are supported. If Hal support for them
+// Check whether session parameters are supported. If Hal support for them
 // exist, then try to configure a preview stream using them.
 TEST_F(CameraHidlTest, configureStreamsWithSessionParameters) {
     hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
@@ -3266,6 +3281,7 @@
                                 GRALLOC1_CONSUMER_USAGE_HWCOMPOSER,
                                 0,
                                 StreamRotation::ROTATION_0};
+        previewStream.bufferSize = 0;
         ::android::hardware::hidl_vec<V3_4::Stream> streams = {previewStream};
         ::android::hardware::camera::device::V3_4::StreamConfiguration config;
         ::android::hardware::camera::device::V3_5::StreamConfiguration config3_5;
@@ -3344,6 +3360,10 @@
                 &previewThreshold));
         ASSERT_NE(0u, outputPreviewStreams.size());
 
+        uint32_t jpegBufferSize = 0;
+        ASSERT_EQ(Status::OK, getJpegBufferSize(staticMeta, &jpegBufferSize));
+        ASSERT_NE(0u, jpegBufferSize);
+
         int32_t streamId = 0;
         uint32_t streamConfigCounter = 0;
         for (auto& blobIter : outputBlobStreams) {
@@ -3370,7 +3390,7 @@
                 ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4;
                 ::android::hardware::camera::device::V3_2::StreamConfiguration config3_2;
                 createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE,
-                                          &config3_2, &config3_4, &config3_5);
+                                          &config3_2, &config3_4, &config3_5, jpegBufferSize);
                 if (session3_5 != nullptr) {
                     verifyStreamCombination(cameraDevice3_5, config3_4,
                             /*expectedStatus*/ true);
@@ -3661,6 +3681,10 @@
                           &videoThreshold));
         ASSERT_NE(0u, outputVideoStreams.size());
 
+        uint32_t jpegBufferSize = 0;
+        ASSERT_EQ(Status::OK, getJpegBufferSize(staticMeta, &jpegBufferSize));
+        ASSERT_NE(0u, jpegBufferSize);
+
         int32_t streamId = 0;
         uint32_t streamConfigCounter = 0;
         for (auto& blobIter : outputBlobStreams) {
@@ -3686,7 +3710,7 @@
                 ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4;
                 ::android::hardware::camera::device::V3_2::StreamConfiguration config3_2;
                 createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE,
-                                          &config3_2, &config3_4, &config3_5);
+                                          &config3_2, &config3_4, &config3_5, jpegBufferSize);
                 if (session3_5 != nullptr) {
                     verifyStreamCombination(cameraDevice3_5, config3_4,
                             /*expectedStatus*/ true);
@@ -4660,6 +4684,23 @@
     return Status::OK;
 }
 
+// Get max jpeg buffer size in android.jpeg.maxSize
+Status CameraHidlTest::getJpegBufferSize(camera_metadata_t *staticMeta, uint32_t* outBufSize) {
+    if (nullptr == staticMeta || nullptr == outBufSize) {
+        return Status::ILLEGAL_ARGUMENT;
+    }
+
+    camera_metadata_ro_entry entry;
+    int rc = find_camera_metadata_ro_entry(staticMeta,
+            ANDROID_JPEG_MAX_SIZE, &entry);
+    if ((0 != rc) || (1 != entry.count)) {
+        return Status::ILLEGAL_ARGUMENT;
+    }
+
+    *outBufSize = static_cast<uint32_t>(entry.data.i32[0]);
+    return Status::OK;
+}
+
 // Check if the camera device has logical multi-camera capability.
 Status CameraHidlTest::isLogicalMultiCamera(const camera_metadata_t *staticMeta) {
     Status ret = Status::METHOD_NOT_SUPPORTED;
@@ -4946,7 +4987,8 @@
         StreamConfigurationMode configMode,
         ::android::hardware::camera::device::V3_2::StreamConfiguration *config3_2 /*out*/,
         ::android::hardware::camera::device::V3_4::StreamConfiguration *config3_4 /*out*/,
-        ::android::hardware::camera::device::V3_5::StreamConfiguration *config3_5 /*out*/) {
+        ::android::hardware::camera::device::V3_5::StreamConfiguration *config3_5 /*out*/,
+        uint32_t jpegBufferSize) {
     ASSERT_NE(nullptr, config3_2);
     ASSERT_NE(nullptr, config3_4);
     ASSERT_NE(nullptr, config3_5);
@@ -4956,6 +4998,11 @@
     for (auto& stream3_2 : streams3_2) {
         V3_4::Stream stream;
         stream.v3_2 = stream3_2;
+        stream.bufferSize = 0;
+        if (stream3_2.format == PixelFormat::BLOB &&
+                stream3_2.dataSpace == static_cast<V3_2::DataspaceFlags>(Dataspace::V0_JFIF)) {
+            stream.bufferSize = jpegBufferSize;
+        }
         streams3_4[idx++] = stream;
     }
     // Caller is responsible to fill in non-zero config3_5->streamConfigCounter after this returns
@@ -5191,6 +5238,11 @@
     outputPreviewStreams.clear();
     auto rc = getAvailableOutputStreams(staticMeta,
             outputPreviewStreams, previewThreshold);
+
+    uint32_t jpegBufferSize = 0;
+    ASSERT_EQ(Status::OK, getJpegBufferSize(staticMeta, &jpegBufferSize));
+    ASSERT_NE(0u, jpegBufferSize);
+
     free_camera_metadata(staticMeta);
     ASSERT_EQ(Status::OK, rc);
     ASSERT_FALSE(outputPreviewStreams.empty());
@@ -5205,7 +5257,7 @@
     ::android::hardware::camera::device::V3_4::StreamConfiguration config3_4;
     ::android::hardware::camera::device::V3_5::StreamConfiguration config3_5;
     createStreamConfiguration(streams3_2, StreamConfigurationMode::NORMAL_MODE,
-                              &config3_2, &config3_4, &config3_5);
+                              &config3_2, &config3_4, &config3_5, jpegBufferSize);
     if (session3_5 != nullptr) {
         RequestTemplate reqTemplate = RequestTemplate::PREVIEW;
         ret = session3_5->constructDefaultRequestSettings(reqTemplate,
diff --git a/cas/1.0/default/Android.bp b/cas/1.0/default/Android.bp
index debb3e5..aa080f4 100644
--- a/cas/1.0/default/Android.bp
+++ b/cas/1.0/default/Android.bp
@@ -23,10 +23,10 @@
       "libhidlmemory",
       "libhidltransport",
       "liblog",
+      "libstagefright_foundation",
       "libutils",
     ],
     header_libs: [
-      "libstagefright_foundation_headers",
       "media_plugin_headers",
     ],
 }
diff --git a/cas/1.0/default/DescramblerImpl.cpp b/cas/1.0/default/DescramblerImpl.cpp
index 6d5e2d5..9b09751 100644
--- a/cas/1.0/default/DescramblerImpl.cpp
+++ b/cas/1.0/default/DescramblerImpl.cpp
@@ -20,6 +20,7 @@
 #include <hidlmemory/mapping.h>
 #include <media/cas/DescramblerAPI.h>
 #include <media/hardware/CryptoAPI.h>
+#include <media/stagefright/foundation/AString.h>
 #include <media/stagefright/foundation/AUtils.h>
 #include <utils/Log.h>
 
@@ -177,6 +178,7 @@
     // Casting hidl SubSample to DescramblerPlugin::SubSample, but need
     // to ensure structs are actually idential
 
+    AString detailedError;
     int32_t result = holder->descramble(
             dstBuffer.type != BufferType::SHARED_MEMORY,
             (DescramblerPlugin::ScramblingControl)scramblingControl,
@@ -186,10 +188,10 @@
             srcOffset,
             dstPtr,
             dstOffset,
-            NULL);
+            &detailedError);
 
     holder.reset();
-    _hidl_cb(toStatus(result >= 0 ? OK : result), result, NULL);
+    _hidl_cb(toStatus(result >= 0 ? OK : result), result, detailedError.c_str());
     return Void();
 }
 
diff --git a/current.txt b/current.txt
index c063f3e..beafcf0 100644
--- a/current.txt
+++ b/current.txt
@@ -388,6 +388,7 @@
 2a55e224aa9bc62c0387cd85ad3c97e33f0c33a4e1489cbae86b2523e6f9df35 android.hardware.camera.device@3.2::ICameraDevice
 8caf9104dc6885852c0b117d853dd93f6d4b61a0a365138295eb8bcd41b36423 android.hardware.camera.device@3.2::ICameraDeviceSession
 684702a60deef03a1e8093961dc0a18c555c857ad5a77ba7340b0635ae01eb70 android.hardware.camera.device@3.4::ICameraDeviceSession
+e96190f635b8458b92525bd6e040fec4ccbac22fdd4bc7274a9794ab976362f7 android.hardware.camera.device@3.4::types
 291638a1b6d4e63283e9e722ab5049d9351717ffa2b66162124f84d1aa7c2835 android.hardware.camera.metadata@3.2::types
 8a075cf3a17fe99c6d23415a3e9a65612f1fee73ee052a3a8a0ca5b8877395a4 android.hardware.camera.metadata@3.3::types
 da33234403ff5d60f3473711917b9948e6484a4260b5247acdafb111193a9de2 android.hardware.configstore@1.0::ISurfaceFlingerConfigs
diff --git a/drm/1.2/Android.bp b/drm/1.2/Android.bp
index 66a1bd8..fa2962a 100644
--- a/drm/1.2/Android.bp
+++ b/drm/1.2/Android.bp
@@ -9,8 +9,10 @@
     srcs: [
         "types.hal",
         "ICryptoFactory.hal",
+        "ICryptoPlugin.hal",
         "IDrmFactory.hal",
         "IDrmPlugin.hal",
+        "IDrmPluginListener.hal",
     ],
     interfaces: [
         "android.hardware.drm@1.0",
@@ -18,8 +20,8 @@
         "android.hidl.base@1.0",
     ],
     types: [
-        "KeySetId",
         "OfflineLicenseState",
+        "Status",
     ],
     gen_java: false,
 }
diff --git a/drm/1.2/ICryptoPlugin.hal b/drm/1.2/ICryptoPlugin.hal
new file mode 100644
index 0000000..0700676
--- /dev/null
+++ b/drm/1.2/ICryptoPlugin.hal
@@ -0,0 +1,84 @@
+/**
+ * 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.drm@1.2;
+
+import @1.0::DestinationBuffer;
+import @1.0::ICryptoPlugin;
+import @1.0::Mode;
+import @1.0::Pattern;
+import @1.0::SessionId;
+import @1.0::SharedBuffer;
+import @1.0::SubSample;
+
+/**
+ * ICryptoPlugin is the HAL for vendor-provided crypto plugins.
+ * It allows crypto sessions to be opened and operated on, to
+ * load crypto keys for a codec to decrypt protected video content.
+ */
+interface ICryptoPlugin extends @1.0::ICryptoPlugin {
+
+    /**
+     * Decrypt an array of subsamples from the source memory buffer to the
+     * destination memory buffer.
+     *
+     * decrypt_1_2() only differs from decrypt() in that additional status
+     * codes must be returned.
+     *
+     * @param secure a flag to indicate if a secure decoder is being used. This
+     *     enables the plugin to configure buffer modes to work consistently with
+     *     a secure decoder.
+     * @param the keyId for the key that is used to do the the decryption. The
+     *     keyId refers to a key in the associated MediaDrm instance.
+     * @param iv the initialization vector to use
+     * @param mode the crypto mode to use
+     * @param pattern the crypto pattern to use
+     * @param subSamples a vector of subsamples indicating the number
+     *     of clear and encrypted bytes to process. This allows the decrypt
+     *     call to operate on a range of subsamples in a single call
+     * @param source the input buffer for the decryption
+     * @param offset the offset of the first byte of encrypted data from
+     *     the base of the source buffer
+     * @param destination the output buffer for the decryption
+     * @return status the status of the call. The status must be OK or one
+     *     of the following errors:
+     *     ERROR_DRM_NO_LICENSE if no license keys have been loaded
+     *     ERROR_DRM_LICENSE_EXPIRED if the license keys have expired
+     *     ERROR_DRM_RESOURCE_BUSY if the resources required to perform
+     *         the decryption are not available
+     *     ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION if required output
+     *         protections are not active
+     *     ERROR_DRM_INSUFFICIENT_SECURITY if the security level of the
+     *         device is not sufficient to meet the requirements in
+     *         the license policy
+     *     ERROR_DRM_FRAME_TOO_LARGE if the frame being decrypted into
+     *         the secure output buffer exceeds the size of the buffer
+     *     ERROR_DRM_SESSION_NOT_OPENED if the decrypt session is not
+     *         opened
+     *     ERROR_DRM_DECRYPT if the decrypt operation fails
+     *     ERROR_DRM_INVALID_STATE if the device is in a state where it
+     *         is not able to perform decryption
+     *     ERROR_DRM_CANNOT_HANDLE in other failure cases.
+     *
+     * @return bytesWritten the number of bytes output from the decryption
+     * @return detailedError if the error is a vendor-specific error, the
+     *     vendor's crypto HAL may provide a detailed error string to help
+     *     describe the error.
+     */
+    decrypt_1_2(bool secure, uint8_t[16] keyId, uint8_t[16] iv, Mode mode,
+        Pattern pattern, vec<SubSample> subSamples,
+            SharedBuffer source, uint64_t offset, DestinationBuffer destination)
+        generates(Status status, uint32_t bytesWritten, string detailedError);
+};
diff --git a/drm/1.2/IDrmPlugin.hal b/drm/1.2/IDrmPlugin.hal
index 88338d6..88ace0b 100644
--- a/drm/1.2/IDrmPlugin.hal
+++ b/drm/1.2/IDrmPlugin.hal
@@ -15,13 +15,19 @@
  */
 package android.hardware.drm@1.2;
 
-import @1.1::IDrmPlugin;
+import @1.0::KeyedVector;
+import @1.0::KeyType;
+import @1.0::SessionId;
 import @1.0::Status;
+import @1.1::IDrmPlugin;
+import @1.1::KeyRequestType;
+import @1.2::IDrmPluginListener;
 
 /**
- * IDrmPlugin is used to interact with a specific drm plugin that was created by
- * IDrm::createPlugin. A drm plugin provides methods for obtaining drm keys that
- * may be used by a codec to decrypt protected video content.
+ * IDrmPlugin is used to interact with a specific drm plugin that was
+ * created by IDrm::createPlugin. A drm plugin provides methods for
+ * obtaining drm keys to be used by a codec to decrypt protected video
+ * content.
  */
 interface IDrmPlugin extends @1.1::IDrmPlugin {
 
@@ -32,24 +38,25 @@
      * request/response exchange when the key request KeyType is
      * OFFLINE. Normally each app is responsible for keeping track of
      * the KeySetIds it has created. In some situations however, it
-     * may be necessary to request the list of stored offline license
+     * will be necessary to request the list of stored offline license
      * KeySetIds. If an app loses the KeySetId for any stored licenses
      * that it created, for example, it must be able to recover the
-     * stored KeySetIds so those licenses can be removed when they
+     * stored KeySetIds so those licenses will be removed when they
      * expire or when the app is uninstalled.
      * <p>
      * This method returns a list of the KeySetIds for all offline
-     * licenses. The offline license KeySetId may be used to query
+     * licenses. The offline license KeySetId allows an app to query
      * the status of an offline license or remove it.
      *
-     * @return status the status of the call. May be OK or
+     * @return status the status of the call. Must be OK or
      *     ERROR_DRM_INVALID_STATE if the HAL is in a state where the
      *     KeySetIds can't be returned.
      * @return a list of offline license keySetIds. If there are no offline
      *     licenses, the list must be empty and OK must be returned as the
      *     status.
      */
-    getOfflineLicenseKeySetIds() generates (Status status, vec<KeySetId> keySetIds);
+    getOfflineLicenseKeySetIds() generates (@1.0::Status status,
+            vec<KeySetId> keySetIds);
 
     /**
      * Normally offline licenses are released using a key
@@ -59,20 +66,20 @@
      * removed and then adjust the count of offline licenses allocated
      * to the device.
      * <p>
-     * In some exceptional situations it may be necessary to directly
-     * remove offline licenses without notifying the server, which may
-     * be performed using this method.
+     * In some exceptional situations it will be necessary to directly
+     * remove offline licenses without notifying the server, which is
+     * performed by this method.
      *
      * @param keySetId the id of the offline license to remove
-     * @return status the status of the call. May be one of OK on
+     * @return status the status of the call. Must be one of OK on
      *     success, BAD_VALUE if the license is not found or
      *     ERROR_DRM_INVALID_STATE if the HAL is in a state where the
      *     KeySetIds can't be returned.
      */
-    removeOfflineLicense(KeySetId keySetId) generates (Status status);
+    removeOfflineLicense(KeySetId keySetId) generates (@1.0::Status status);
 
     /**
-     * Request the state of an offline license. An offline license may
+     * Request the state of an offline license. An offline license must
      * be usable or inactive. The keys in a usable offline license are
      * available for decryption. When the offline license state is
      * inactive, the keys have been marked for release using
@@ -81,7 +88,7 @@
      * usable for decryption.
      *
      * @param keySetId the id of the offline license
-     * @return status the status of the call. May be one of OK on
+     * @return status the status of the call. Must be one of OK on
      *     success, BAD_VALUE if the license is not found or
      *     ERROR_DRM_INVALID_STATE if the HAL is in a state where the
      *     offline license state can't be queried.
@@ -89,6 +96,100 @@
      *     If the return status is not OK then state must be set to
      *     UNKNOWN.
      */
-    getOfflineLicenseState(KeySetId keySetId) generates (Status status,
-            OfflineLicenseState state);
+    getOfflineLicenseState(KeySetId keySetId) generates (
+            @1.0::Status status, OfflineLicenseState state);
+
+    /**
+     * A key request/response exchange occurs between the app and a License
+     * Server to obtain the keys required to decrypt the content.
+     * getKeyRequest_1_2() is used to obtain an opaque key request blob that is
+     * delivered to the license server.
+     *
+     * getKeyRequest_1_2() only differs from getKeyRequest_1_1() in that
+     *     additional status codes must be returned.
+     *
+     * @param scope either a sessionId or a keySetId, depending on the
+     *     specified keyType. When the keyType is OFFLINE or STREAMING, scope
+     *     must be set to the sessionId the keys will be provided to. When the
+     *     keyType is RELEASE, scope must be set to the keySetId of the keys
+     *     being released.
+     * @param initData container-specific data, its meaning is interpreted
+     *     based on the mime type provided in the mimeType parameter. It could
+     *     contain, for example, the content ID, key ID or other data obtained
+     *     from the content metadata that is required to generate the key
+     *     request. initData must be empty when keyType is RELEASE.
+     * @param mimeType identifies the mime type of the content
+     * @param keyType specifies if the keys are to be used for streaming,
+     *     offline or a release
+     * @param optionalParameters included in the key request message to
+     *     allow a client application to provide additional message parameters
+     *     to the server.
+     * @return status the status of the call. The status must be OK or one of
+     *     the following errors: ERROR_DRM_SESSION_NOT_OPENED if the session is
+     *     not opened, ERROR_DRM_NOT_PROVISIONED if the device requires
+     *     provisioning before it is able to generate a key request,
+     *     ERROR_DRM_RESOURCE_CONTENTION if client applications using the hal
+     *     are temporarily exceeding the available crypto resources such that a
+     *     retry of the operation is likely to succeed, ERROR_DRM_CANNOT_HANDLE
+     *     if getKeyRequest is not supported at the time of the call, BAD_VALUE
+     *     if any parameters are invalid or ERROR_DRM_INVALID_STATE if the HAL
+     *     is in a state where a key request cannot be generated.
+     * @return request if successful, the opaque key request blob is returned
+     * @return requestType indicates type information about the returned
+     *      request. The type must be one of INITIAL, RENEWAL, RELEASE, NONE or
+     *      UPDATE. An INITIAL request is the first key request for a
+     *      license. RENEWAL is a subsequent key request used to refresh the
+     *      keys in a license. RELEASE corresponds to a keyType of RELEASE,
+     *      which indicates keys are being released. NONE indicates that no
+     *      request is needed because the keys are already loaded. UPDATE
+     *      indicates that the keys need to be refetched after the initial
+     *      license request.
+     * @return defaultUrl the URL that the request may be sent to, if
+     *      provided by the drm HAL. The app can choose to override this URL.
+     */
+    getKeyRequest_1_2(vec<uint8_t> scope, vec<uint8_t> initData,
+            string mimeType, KeyType keyType, KeyedVector optionalParameters)
+        generates (Status status, vec<uint8_t> request,
+                KeyRequestType requestType, string defaultUrl);
+
+    /**
+     * A provision request/response exchange occurs between the app and a
+     * provisioning server to retrieve a device certificate. getProvisionRequest
+     * is used to obtain an opaque provisioning request blob that is delivered
+     * to the provisioning server.
+     *
+     * getProvisionRequest_1_2() only differs from getProvisionRequest_1_0() in
+     *     that additional status codes must be returned.
+     *
+     * @param certificateType the type of certificate requested, e.g. "X.509"
+     * @param certificateAuthority identifies the certificate authority. A
+     *     certificate authority (CA) is an entity which issues digital
+     *     certificates for use by other parties. It is an example of a trusted
+     *     third party.
+     * @return status the status of the call. The status must be OK or one of
+     *     the following errors: ERROR_DRM_RESOURCE_CONTENTION if client
+     *     applications using the hal are temporarily exceeding the available
+     *     crypto resources such that a retry of the operation is likely to
+     *     succeed, ERROR_DRM_CANNOT_HANDLE if the drm scheme does not require
+     *     provisioning or ERROR_DRM_INVALID_STATE if the HAL is in a state
+     *     where the provision request cannot be generated.
+     * @return request if successful the opaque certificate request blob
+     *     is returned
+     * @return defaultUrl URL that the provisioning request may be
+     *     sent to, if known by the HAL implementation. An app can choose to
+     *     override this URL. If the HAL implementation does not provide a
+     *     defaultUrl, the returned string must be empty.
+     */
+    getProvisionRequest_1_2(string certificateType, string certificateAuthority)
+        generates (Status status, vec<uint8_t> request, string defaultUrl);
+
+    /**
+     * Send a session lost state event to the listener. This event
+     * indicates that a session's state has become invalid because the
+     * device crypto hardware is incapable of retaining crypto session
+     * state across suspend and resume cycles.
+     *
+     * @param sessionId identifies the session the event originated from
+     */
+    sendSessionLostState(SessionId sessionId);
 };
diff --git a/drm/1.2/IDrmPluginListener.hal b/drm/1.2/IDrmPluginListener.hal
new file mode 100644
index 0000000..a6bd6c9
--- /dev/null
+++ b/drm/1.2/IDrmPluginListener.hal
@@ -0,0 +1,39 @@
+/*
+ * 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.drm@1.2;
+
+import @1.0::IDrmPluginListener;
+import @1.0::SessionId;
+
+/**
+ * IDrmPluginListener is a listener interface for Drm events sent from an
+ * IDrmPlugin instance.
+ */
+interface IDrmPluginListener extends @1.0::IDrmPluginListener {
+    /**
+     * Some device crypto hardware is incapable of retaining crypto
+     * session state across suspend and resume cycles. A
+     * SessionLostState event must be signaled when a session has
+     * become invalid for this reason. This event must not be used to
+     * indicate a failure in the crypto system. Closing the session
+     * and opening a new one must allow the application to resume
+     * normal use of the drm hal module.
+     *
+     * @param sessionId identifies the session that has been invalidated
+     */
+     oneway sendSessionLostState(SessionId sessionId);
+};
diff --git a/drm/1.2/types.hal b/drm/1.2/types.hal
index 8770c79..6e1acde 100644
--- a/drm/1.2/types.hal
+++ b/drm/1.2/types.hal
@@ -16,6 +16,8 @@
 
 package android.hardware.drm@1.2;
 
+import @1.0::Status;
+
 enum OfflineLicenseState : uint32_t {
     /**
      * Offline license state is unknown
@@ -23,7 +25,7 @@
     UNKNOWN,
 
     /**
-     * Offline license state is usable, the keys may be used for decryption.
+     * Offline license state is usable, the keys are usable for decryption.
      */
     USABLE,
 
@@ -35,6 +37,40 @@
     INACTIVE
 };
 
+enum Status : @1.0::Status {
+    /**
+     * The drm HAL module must return ERROR_DRM_INSUFFICIENT_SECURITY
+     * from the crypto plugin decrypt method when the security level
+     * of the device is not sufficient to meet the requirements in the
+     * license policy.
+     */
+    ERROR_DRM_INSUFFICIENT_SECURITY,
+
+    /**
+     * The drm HAL module must return ERROR_FRAME_TOO_LARGE from the
+     * decrypt method when the frame being decrypted into the secure
+     * output buffer exceeds the size of the buffer.
+     */
+    ERROR_DRM_FRAME_TOO_LARGE,
+
+    /**
+     * This error must be returned from any session method when an
+     * attempt is made to use the session after the crypto hardware
+     * state has been invalidated. Some devices are not able to
+     * retain crypto session state across device suspend/resume which
+     * results in invalid session state.
+     */
+    ERROR_DRM_SESSION_LOST_STATE,
+
+     /**
+      * The drm HAL module must return this error if client
+      * applications using the hal are temporarily exceeding the
+      * capacity of available crypto resources such that a retry of
+      * the operation is likely to succeed.
+      */
+    ERROR_DRM_RESOURCE_CONTENTION,
+};
+
 /**
  * KeySetId is an identifier that references a set of keys in an
  * offline license. The keySetId is created by the HAL implementation
diff --git a/thermal/2.0/default/Android.bp b/thermal/2.0/default/Android.bp
index f620e6e..dab0d33 100644
--- a/thermal/2.0/default/Android.bp
+++ b/thermal/2.0/default/Android.bp
@@ -14,7 +14,7 @@
 // limitations under the License.
 
 cc_binary {
-    name: "android.hardware.thermal@2.0-service",
+    name: "android.hardware.thermal@2.0-service.mock",
     defaults: ["hidl_defaults"],
     relative_install_path: "hw",
     vendor: true,
diff --git a/thermal/2.0/default/android.hardware.thermal@2.0-service.rc b/thermal/2.0/default/android.hardware.thermal@2.0-service.rc
index de49d20..046c771 100644
--- a/thermal/2.0/default/android.hardware.thermal@2.0-service.rc
+++ b/thermal/2.0/default/android.hardware.thermal@2.0-service.rc
@@ -1,4 +1,4 @@
-service vendor.thermal-hal-2-0-mock /vendor/bin/hw/android.hardware.thermal@2.0-service
+service vendor.thermal-hal-2-0-mock /vendor/bin/hw/android.hardware.thermal@2.0-service.mock
     interface android.hardware.thermal@2.0::IThermal default
     class hal
     user system