Merge "Camera: Add a new tag for multi-resolution stream support" into sc-dev
diff --git a/atrace/1.0/default/AtraceDevice.cpp b/atrace/1.0/default/AtraceDevice.cpp
index 4e82b0a..9f0c4c4 100644
--- a/atrace/1.0/default/AtraceDevice.cpp
+++ b/atrace/1.0/default/AtraceDevice.cpp
@@ -16,6 +16,7 @@
 
 #include <android-base/file.h>
 #include <android-base/logging.h>
+#include <android-base/stringprintf.h>
 
 #include "AtraceDevice.h"
 
@@ -39,15 +40,11 @@
         // gfx
         {
                 "gfx",
-                {"Graphics",
-                 {{"/sys/kernel/debug/tracing/events/mdss/enable", false},
-                  {"/sys/kernel/debug/tracing/events/sde/enable", false},
-                  {"/sys/kernel/debug/tracing/events/mali_systrace/enable", false}}},
+                {"Graphics", {{"mdss", false}, {"sde", false}, {"mali_systrace", false}}},
         },
         {
                 "ion",
-                {"ION allocation",
-                 {{"/sys/kernel/debug/tracing/events/kmem/ion_alloc_buffer_start/enable", false}}},
+                {"ION allocation", {{"kmem/ion_alloc_buffer_start", false}}},
         },
 };
 
@@ -65,16 +62,31 @@
     return Void();
 }
 
+AtraceDevice::AtraceDevice() {
+    struct stat st;
+
+    tracefs_event_root_ = "/sys/kernel/tracing/events/";
+    if (stat(tracefs_event_root_.c_str(), &st) != 0) {
+        tracefs_event_root_ = "/sys/kernel/debug/tracing/events/";
+        CHECK(stat(tracefs_event_root_.c_str(), &st) == 0) << "tracefs must be mounted at either"
+                                                              "/sys/kernel/tracing or "
+                                                              "/sys/kernel/debug/tracing";
+    }
+}
+
 Return<::android::hardware::atrace::V1_0::Status> AtraceDevice::enableCategories(
-    const hidl_vec<hidl_string>& categories) {
+        const hidl_vec<hidl_string>& categories) {
     if (!categories.size()) {
         return Status::ERROR_INVALID_ARGUMENT;
     }
+
     for (auto& c : categories) {
         if (kTracingMap.count(c)) {
             for (auto& p : kTracingMap.at(c).paths) {
-                if (!android::base::WriteStringToFile("1", p.first)) {
-                    LOG(ERROR) << "Failed to enable tracing on: " << p.first;
+                std::string tracefs_event_enable_path = android::base::StringPrintf(
+                        "%s%s/enable", tracefs_event_root_.c_str(), p.first.c_str());
+                if (!android::base::WriteStringToFile("1", tracefs_event_enable_path)) {
+                    LOG(ERROR) << "Failed to enable tracing on: " << tracefs_event_enable_path;
                     if (p.second) {
                         // disable before return
                         disableAllCategories();
@@ -91,10 +103,13 @@
 
 Return<::android::hardware::atrace::V1_0::Status> AtraceDevice::disableAllCategories() {
     auto ret = Status::SUCCESS;
+
     for (auto& c : kTracingMap) {
         for (auto& p : c.second.paths) {
-            if (!android::base::WriteStringToFile("0", p.first)) {
-                LOG(ERROR) << "Failed to disable tracing on: " << p.first;
+            std::string tracefs_event_enable_path = android::base::StringPrintf(
+                    "%s%s/enable", tracefs_event_root_.c_str(), p.first.c_str());
+            if (!android::base::WriteStringToFile("0", tracefs_event_enable_path)) {
+                LOG(ERROR) << "Failed to disable tracing on: " << tracefs_event_enable_path;
                 if (p.second) {
                     ret = Status::ERROR_TRACING_POINT;
                 }
diff --git a/atrace/1.0/default/AtraceDevice.h b/atrace/1.0/default/AtraceDevice.h
index e700f89..ab87c65 100644
--- a/atrace/1.0/default/AtraceDevice.h
+++ b/atrace/1.0/default/AtraceDevice.h
@@ -36,12 +36,16 @@
 using ::android::hardware::Void;
 
 struct AtraceDevice : public IAtraceDevice {
+    AtraceDevice();
     // Methods from ::android::hardware::atrace::V1_0::IAtraceDevice follow.
     Return<void> listCategories(listCategories_cb _hidl_cb) override;
     Return<::android::hardware::atrace::V1_0::Status> enableCategories(
         const hidl_vec<hidl_string>& categories) override;
     Return<::android::hardware::atrace::V1_0::Status> disableAllCategories() override;
 
+  private:
+    std::string tracefs_event_root_;
+
     // Methods from ::android::hidl::base::V1_0::IBase follow.
 };
 
diff --git a/atrace/1.0/default/android.hardware.atrace@1.0-service.rc b/atrace/1.0/default/android.hardware.atrace@1.0-service.rc
index eb54c39..7110b45 100644
--- a/atrace/1.0/default/android.hardware.atrace@1.0-service.rc
+++ b/atrace/1.0/default/android.hardware.atrace@1.0-service.rc
@@ -1,10 +1,14 @@
 on late-init
     # vendor graphics trace points
     chmod 0666 /sys/kernel/debug/tracing/events/sde/enable
+    chmod 0666 /sys/kernel/tracing/events/sde/enable
     chmod 0666 /sys/kernel/debug/tracing/events/mdss/enable
+    chmod 0666 /sys/kernel/tracing/events/mdss/enable
     chmod 0666 /sys/kernel/debug/tracing/events/mali_systrace/enable
+    chmod 0666 /sys/kernel/tracing/events/mali_systrace/enable
     # ion allocation trace point
     chmod 0666 /sys/kernel/debug/tracing/events/kmem/ion_alloc_buffer_start/enable
+    chmod 0666 /sys/kernel/tracing/events/kmem/ion_alloc_buffer_start/enable
 
 service vendor.atrace-hal-1-0 /vendor/bin/hw/android.hardware.atrace@1.0-service
     interface android.hardware.atrace@1.0::IAtraceDevice default
diff --git a/audio/7.0/config/api/current.txt b/audio/7.0/config/api/current.txt
index e61ddcb..3716cf0 100644
--- a/audio/7.0/config/api/current.txt
+++ b/audio/7.0/config/api/current.txt
@@ -45,6 +45,8 @@
     enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_IN_VOICE_DNLINK_MONO;
     enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_IN_VOICE_UPLINK_MONO;
     enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_NONE;
+    enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_13POINT_360RA;
+    enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_22POINT2;
     enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_2POINT0POINT2;
     enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_2POINT1;
     enum_constant public static final android.audio.policy.configuration.V7_0.AudioChannelMask AUDIO_CHANNEL_OUT_2POINT1POINT2;
@@ -208,6 +210,7 @@
     enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_CELT;
     enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DEFAULT;
     enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DOLBY_TRUEHD;
+    enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DRA;
     enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DSD;
     enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DTS;
     enum_constant public static final android.audio.policy.configuration.V7_0.AudioFormat AUDIO_FORMAT_DTS_HD;
diff --git a/audio/7.0/config/audio_policy_configuration.xsd b/audio/7.0/config/audio_policy_configuration.xsd
index 77cff91..7f7fb61 100644
--- a/audio/7.0/config/audio_policy_configuration.xsd
+++ b/audio/7.0/config/audio_policy_configuration.xsd
@@ -415,6 +415,7 @@
             <xs:enumeration value="AUDIO_FORMAT_MPEGH_LC_L4"/>
             <xs:enumeration value="AUDIO_FORMAT_IEC60958"/>
             <xs:enumeration value="AUDIO_FORMAT_DTS_UHD"/>
+            <xs:enumeration value="AUDIO_FORMAT_DRA"/>
         </xs:restriction>
     </xs:simpleType>
     <xs:simpleType name="extendableAudioFormat">
@@ -508,6 +509,8 @@
             <xs:enumeration value="AUDIO_CHANNEL_OUT_7POINT1"/>
             <xs:enumeration value="AUDIO_CHANNEL_OUT_7POINT1POINT2"/>
             <xs:enumeration value="AUDIO_CHANNEL_OUT_7POINT1POINT4"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_13POINT_360RA"/>
+            <xs:enumeration value="AUDIO_CHANNEL_OUT_22POINT2"/>
             <xs:enumeration value="AUDIO_CHANNEL_OUT_MONO_HAPTIC_A"/>
             <xs:enumeration value="AUDIO_CHANNEL_OUT_STEREO_HAPTIC_A"/>
             <xs:enumeration value="AUDIO_CHANNEL_OUT_HAPTIC_AB"/>
diff --git a/audio/common/7.0/enums/include/android_audio_policy_configuration_V7_0-enums.h b/audio/common/7.0/enums/include/android_audio_policy_configuration_V7_0-enums.h
index 723d7f8..a92a277 100644
--- a/audio/common/7.0/enums/include/android_audio_policy_configuration_V7_0-enums.h
+++ b/audio/common/7.0/enums/include/android_audio_policy_configuration_V7_0-enums.h
@@ -94,6 +94,7 @@
         case AudioChannelMask::AUDIO_CHANNEL_OUT_7POINT1POINT4:
         case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_12:
             return 12;
+        case AudioChannelMask::AUDIO_CHANNEL_OUT_13POINT_360RA:
         case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_13:
             return 13;
         case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_14:
@@ -116,6 +117,7 @@
             return 22;
         case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_23:
             return 23;
+        case AudioChannelMask::AUDIO_CHANNEL_OUT_22POINT2:
         case AudioChannelMask::AUDIO_CHANNEL_INDEX_MASK_24:
             return 24;
         case AudioChannelMask::UNKNOWN:
diff --git a/automotive/evs/OWNERS b/automotive/evs/OWNERS
index fec2a3a..6fc5024 100644
--- a/automotive/evs/OWNERS
+++ b/automotive/evs/OWNERS
@@ -1,3 +1,3 @@
 changyeon@google.com
+garysungang@google.com
 haoxiangl@google.com
-swan@google.com
diff --git a/automotive/vehicle/2.0/default/Android.bp b/automotive/vehicle/2.0/default/Android.bp
index d6f3120..21c1a6e 100644
--- a/automotive/vehicle/2.0/default/Android.bp
+++ b/automotive/vehicle/2.0/default/Android.bp
@@ -78,6 +78,7 @@
     name: "android.hardware.automotive.vehicle@2.0-default-impl-lib",
     vendor: true,
     defaults: ["vhal_v2_0_target_defaults"],
+    cflags: ["-DENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING"],
     srcs: [
         "impl/vhal_v2_0/CommConn.cpp",
         "impl/vhal_v2_0/EmulatedVehicleConnector.cpp",
@@ -91,13 +92,13 @@
         "impl/vhal_v2_0/LinearFakeValueGenerator.cpp",
         "impl/vhal_v2_0/JsonFakeValueGenerator.cpp",
         "impl/vhal_v2_0/GeneratorHub.cpp",
+        "impl/vhal_v2_0/qemu_pipe.cpp",
     ],
     local_include_dirs: ["common/include/vhal_v2_0"],
     export_include_dirs: ["impl"],
     whole_static_libs: [
         "android.hardware.automotive.vehicle@2.0-emulated-user-hal-lib",
         "android.hardware.automotive.vehicle@2.0-manager-lib",
-        "libqemu_pipe",
     ],
     shared_libs: [
         "libbase",
@@ -210,7 +211,6 @@
     vendor: true,
     relative_install_path: "hw",
     srcs: ["VehicleService.cpp"],
-    cflags: ["-DENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING"],
     shared_libs: [
         "libbase",
         "libjsoncpp",
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 2cc956d..abf33a3 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
@@ -461,22 +461,22 @@
                          .changeMode = VehiclePropertyChangeMode::CONTINUOUS,
                          .areaConfigs = {VehicleAreaConfig{
                                                  .areaId = WHEEL_FRONT_LEFT,
-                                                 .minFloatValue = 100.0f,
+                                                 .minFloatValue = 193.0f,
                                                  .maxFloatValue = 300.0f,
                                          },
                                          VehicleAreaConfig{
                                                  .areaId = WHEEL_FRONT_RIGHT,
-                                                 .minFloatValue = 100.0f,
+                                                 .minFloatValue = 193.0f,
                                                  .maxFloatValue = 300.0f,
                                          },
                                          VehicleAreaConfig{
                                                  .areaId = WHEEL_REAR_LEFT,
-                                                 .minFloatValue = 100.0f,
+                                                 .minFloatValue = 193.0f,
                                                  .maxFloatValue = 300.0f,
                                          },
                                          VehicleAreaConfig{
                                                  .areaId = WHEEL_REAR_RIGHT,
-                                                 .minFloatValue = 100.0f,
+                                                 .minFloatValue = 193.0f,
                                                  .maxFloatValue = 300.0f,
                                          }},
                          .minSampleRate = 1.0f,
@@ -486,6 +486,17 @@
 
         {.config =
                  {
+                         .prop = toInt(VehicleProperty::CRITICALLY_LOW_TIRE_PRESSURE),
+                         .access = VehiclePropertyAccess::READ,
+                         .changeMode = VehiclePropertyChangeMode::STATIC,
+                 },
+         .initialAreaValues = {{WHEEL_FRONT_LEFT, {.floatValues = {137.0f}}},
+                               {WHEEL_FRONT_RIGHT, {.floatValues = {137.0f}}},
+                               {WHEEL_REAR_RIGHT, {.floatValues = {137.0f}}},
+                               {WHEEL_REAR_LEFT, {.floatValues = {137.0f}}}}},
+
+        {.config =
+                 {
                          .prop = toInt(VehicleProperty::TIRE_PRESSURE_DISPLAY_UNITS),
                          .access = VehiclePropertyAccess::READ_WRITE,
                          .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
@@ -690,6 +701,7 @@
         {.config = {.prop = toInt(VehicleProperty::HVAC_TEMPERATURE_SET),
                     .access = VehiclePropertyAccess::READ_WRITE,
                     .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                    .configArray = {160, 280, 5, 605, 825, 10},
                     .areaConfigs = {VehicleAreaConfig{
                                             .areaId = HVAC_LEFT,
                                             .minFloatValue = 16,
@@ -705,6 +717,14 @@
 
         {.config =
                  {
+                         .prop = toInt(VehicleProperty::HVAC_TEMPERATURE_VALUE_SUGGESTION),
+                         .access = VehiclePropertyAccess::READ_WRITE,
+                         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                 },
+         .initialValue = {.floatValues = {66.2f, (float)VehicleUnit::FAHRENHEIT, 19.0f, 66.5f}}},
+
+        {.config =
+                 {
                          .prop = toInt(VehicleProperty::ENV_OUTSIDE_TEMPERATURE),
                          .access = VehiclePropertyAccess::READ,
                          // TODO(bryaneyler): Support ON_CHANGE as well.
@@ -1240,7 +1260,7 @@
                                 .prop = toInt(VehicleProperty::CLUSTER_REPORT_STATE),
                                 .access = VehiclePropertyAccess::WRITE,
                                 .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                                .configArray = {0, 0, 0, 9, 0, 0, 0, 0, 16},
+                                .configArray = {0, 0, 0, 11, 0, 0, 0, 0, 16},
                         },
         },
         {
@@ -1283,7 +1303,7 @@
                                 .prop = VENDOR_CLUSTER_REPORT_STATE,
                                 .access = VehiclePropertyAccess::READ,
                                 .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                                .configArray = {0, 0, 0, 9, 0, 0, 0, 0, 16},
+                                .configArray = {0, 0, 0, 11, 0, 0, 0, 0, 16},
                         },
         },
         {
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/PipeComm.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/PipeComm.cpp
index f024287..81e7c78 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/PipeComm.cpp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/PipeComm.cpp
@@ -18,9 +18,9 @@
 
 #include <android/hardware/automotive/vehicle/2.0/IVehicle.h>
 #include <log/log.h>
-#include <qemu_pipe.h>
 
 #include "PipeComm.h"
+#include "qemu_pipe.h"
 
 #define CAR_SERVICE_NAME "pipe:qemud:car"
 
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/qemu_pipe.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/qemu_pipe.cpp
new file mode 100644
index 0000000..cf1a002
--- /dev/null
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/qemu_pipe.cpp
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "qemu_pipe.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <android-base/file.h>
+
+using android::base::ReadFully;
+using android::base::WriteFully;
+
+// Define QEMU_PIPE_DEBUG if you want to print error messages when an error
+// occurs during pipe operations. The macro should simply take a printf-style
+// formatting string followed by optional arguments.
+#ifndef QEMU_PIPE_DEBUG
+#define QEMU_PIPE_DEBUG(...) (void)0
+#endif
+
+int qemu_pipe_open(const char* pipeName) {
+    if (!pipeName) {
+        errno = EINVAL;
+        return -1;
+    }
+
+    int fd = TEMP_FAILURE_RETRY(open("/dev/qemu_pipe", O_RDWR));
+    if (fd < 0) {
+        QEMU_PIPE_DEBUG("%s: Could not open /dev/qemu_pipe: %s", __FUNCTION__, strerror(errno));
+        return -1;
+    }
+
+    // Write the pipe name, *including* the trailing zero which is necessary.
+    size_t pipeNameLen = strlen(pipeName);
+    if (WriteFully(fd, pipeName, pipeNameLen + 1U)) {
+        return fd;
+    }
+
+    // now, add 'pipe:' prefix and try again
+    // Note: host side will wait for the trailing '\0' to start
+    // service lookup.
+    const char pipe_prefix[] = "pipe:";
+    if (WriteFully(fd, pipe_prefix, strlen(pipe_prefix)) &&
+        WriteFully(fd, pipeName, pipeNameLen + 1U)) {
+        return fd;
+    }
+    QEMU_PIPE_DEBUG("%s: Could not write to %s pipe service: %s", __FUNCTION__, pipeName,
+                    strerror(errno));
+    close(fd);
+    return -1;
+}
+
+int qemu_pipe_frame_send(int fd, const void* buff, size_t len) {
+    char header[5];
+    snprintf(header, sizeof(header), "%04zx", len);
+    if (!WriteFully(fd, header, 4)) {
+        QEMU_PIPE_DEBUG("Can't write qemud frame header: %s", strerror(errno));
+        return -1;
+    }
+    if (!WriteFully(fd, buff, len)) {
+        QEMU_PIPE_DEBUG("Can't write qemud frame payload: %s", strerror(errno));
+        return -1;
+    }
+    return 0;
+}
+
+int qemu_pipe_frame_recv(int fd, void* buff, size_t len) {
+    char header[5];
+    if (!ReadFully(fd, header, 4)) {
+        QEMU_PIPE_DEBUG("Can't read qemud frame header: %s", strerror(errno));
+        return -1;
+    }
+    header[4] = '\0';
+    size_t size;
+    if (sscanf(header, "%04zx", &size) != 1) {
+        QEMU_PIPE_DEBUG("Malformed qemud frame header: [%.*s]", 4, header);
+        return -1;
+    }
+    if (size > len) {
+        QEMU_PIPE_DEBUG("Oversized qemud frame (% bytes, expected <= %)", size, len);
+        return -1;
+    }
+    if (!ReadFully(fd, buff, size)) {
+        QEMU_PIPE_DEBUG("Could not read qemud frame payload: %s", strerror(errno));
+        return -1;
+    }
+    return size;
+}
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/qemu_pipe.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/qemu_pipe.h
new file mode 100644
index 0000000..0987498
--- /dev/null
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/qemu_pipe.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef ANDROID_CORE_INCLUDE_QEMU_PIPE_H
+#define ANDROID_CORE_INCLUDE_QEMU_PIPE_H
+
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+// Try to open a new Qemu fast-pipe. This function returns a file descriptor
+// that can be used to communicate with a named service managed by the
+// emulator.
+//
+// This file descriptor can be used as a standard pipe/socket descriptor.
+//
+// 'pipeName' is the name of the emulator service you want to connect to,
+// and should begin with 'pipe:' (e.g. 'pipe:camera' or 'pipe:opengles').
+// For backward compatibility, the 'pipe:' prefix can be omitted, and in
+// that case, qemu_pipe_open will add it for you.
+
+// On success, return a valid file descriptor, or -1/errno on failure. E.g.:
+//
+// EINVAL  -> unknown/unsupported pipeName
+// ENOSYS  -> fast pipes not available in this system.
+//
+// ENOSYS should never happen, except if you're trying to run within a
+// misconfigured emulator.
+//
+// You should be able to open several pipes to the same pipe service,
+// except for a few special cases (e.g. GSM modem), where EBUSY will be
+// returned if more than one client tries to connect to it.
+int qemu_pipe_open(const char* pipeName);
+
+// Send a framed message |buff| of |len| bytes through the |fd| descriptor.
+// This really adds a 4-hexchar prefix describing the payload size.
+// Returns 0 on success, and -1 on error.
+int qemu_pipe_frame_send(int fd, const void* buff, size_t len);
+
+// Read a frame message from |fd|, and store it into |buff| of |len| bytes.
+// If the framed message is larger than |len|, then this returns -1 and the
+// content is lost. Otherwise, this returns the size of the message. NOTE:
+// empty messages are possible in a framed wire protocol and do not mean
+// end-of-stream.
+int qemu_pipe_frame_recv(int fd, void* buff, size_t len);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ANDROID_CORE_INCLUDE_QEMU_PIPE_H */
diff --git a/automotive/vehicle/2.0/types.hal b/automotive/vehicle/2.0/types.hal
index 1fb7dc7..e22f9fa 100644
--- a/automotive/vehicle/2.0/types.hal
+++ b/automotive/vehicle/2.0/types.hal
@@ -641,6 +641,25 @@
         | VehicleArea:WHEEL),
 
     /**
+     * Critically low tire pressure
+     *
+     * This property indicates the critically low pressure threshold for each tire.
+     * It indicates when it is time for tires to be replaced or fixed. The value
+     * must be less than or equal to minFloatValue in TIRE_PRESSURE.
+     * Minimum and maximum property values (that is, minFloatValue, maxFloatValue)
+     * are not applicable to this property.
+     *
+     * @change_mode VehiclePropertyChangeMode:STATIC
+     * @access VehiclePropertyAccess:READ
+     * @unit VehicleUnit:KILOPASCAL
+     */
+    CRITICALLY_LOW_TIRE_PRESSURE = (
+        0x030A
+        | VehiclePropertyGroup:SYSTEM
+        | VehiclePropertyType:FLOAT
+        | VehicleArea:WHEEL),
+
+    /**
      * Currently selected gear
      *
      * This is the gear selected by the user.
@@ -881,6 +900,24 @@
     /**
      * HVAC, target temperature set.
      *
+     * The configArray is used to indicate the valid values for HVAC in Fahrenheit and Celsius.
+     * Android might use it in the HVAC app UI.
+     * The configArray is set as follows:
+     *      configArray[0] = [the lower bound of the supported temperature in Celsius] * 10.
+     *      configArray[1] = [the upper bound of the supported temperature in Celsius] * 10.
+     *      configArray[2] = [the increment in Celsius] * 10.
+     *      configArray[3] = [the lower bound of the supported temperature in Fahrenheit] * 10.
+     *      configArray[4] = [the upper bound of the supported temperature in Fahrenheit] * 10.
+     *      configArray[5] = [the increment in Fahrenheit] * 10.
+     * For example, if the vehicle supports temperature values as:
+     *      [16.0, 16.5, 17.0 ,..., 28.0] in Celsius
+     *      [60.5, 61.5, 62.5 ,..., 85.5] in Fahrenheit.
+     * The configArray should be configArray = {160, 280, 5, 605, 825, 10}.
+     *
+     * If the vehicle supports HVAC_TEMPERATURE_VALUE_SUGGESTION, the application can use
+     * that property to get the suggested value before setting HVAC_TEMPERATURE_SET. Otherwise,
+     * the application may choose the value in HVAC_TEMPERATURE_SET configArray by itself.
+     *
      * @change_mode VehiclePropertyChangeMode:ON_CHANGE
      * @access VehiclePropertyAccess:READ_WRITE
      * @unit VehicleUnit:CELSIUS
@@ -1229,6 +1266,50 @@
         | VehiclePropertyType:BOOLEAN
         | VehicleArea:WINDOW),
 
+    /**
+     * Suggested values for setting HVAC temperature.
+     *
+     * Implement the property to help applications understand the closest supported temperature
+     * value in Celsius or Fahrenheit.
+     *
+     *      floatValues[0] = the requested value that an application wants to set a temperature to.
+     *      floatValues[1] = the unit for floatValues[0]. It should be one of
+     *                       {VehicleUnit:CELSIUS, VehicleUnit:FAHRENHEIT}.
+     *      floatValues[2] = the value OEMs suggested in CELSIUS. This value is not included
+     *                       in the request.
+     *      floatValues[3] = the value OEMs suggested in FAHRENHEIT. This value is not included
+     *                       in the request.
+     *
+     * An application calls set(VehiclePropValue propValue) with the requested value and unit for
+     * the value. OEMs need to return the suggested values in floatValues[2] and floatValues[3] by
+     * onPropertyEvent() callbacks.
+     *
+     * For example, when a user uses the voice assistant to set HVAC temperature to 66.2 in
+     * Fahrenheit.
+     * First, an application will set this property with the value
+     * [66.2, (float)VehicleUnit:FAHRENHEIT,0,0].
+     * If OEMs suggest to set 19.0 in Celsius or 66.5 in Fahrenheit for user's request, then VHAL
+     * must generate a callback with property value
+     * [66.2, (float)VehicleUnit:FAHRENHEIT, 19.0, 66.5]. After the voice assistant gets the
+     * callback, it will inform the user and set HVAC temperature to the suggested value.
+     *
+     * Another example, an application receives 21 Celsius as the current temperature value by
+     * querying HVC_TEMPERATURE_SET. But the application wants to know what value is displayed on
+     * the car's UI in Fahrenheit.
+     * For this, the application sets the property to [21, (float)VehicleUnit:CELSIUS, 0, 0]. If
+     * the suggested value by the OEM for 21 Celsius is 70 Fahrenheit, then VHAL must generate a
+     * callback with property value [21, (float)VehicleUnit:CELSIUS, 21.0, 70.0].
+     * In this case, the application can know that the value is 70.0 Fahrenheit in the car’s UI.
+     *
+     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+     * @access VehiclePropertyAccess:READ_WRITE
+     */
+    HVAC_TEMPERATURE_VALUE_SUGGESTION = (
+        0x0515
+        | VehiclePropertyGroup:SYSTEM
+        | VehiclePropertyType:FLOAT_VEC
+        | VehicleArea:GLOBAL),
+
    /**
      * Distance units for display
      *
@@ -3119,15 +3200,21 @@
     /**
      * Changes the state of the cluster display.
      *
+     * Bounds: the area to render the cluster Activity.
+     * Inset: the area which Activity should avoid from placing any important
+     *     information.
+     *
      * int32[0]: on/off: 0 - off, 1 - on, -1 - don't care
-     * int32[1]: width: positive number - actual width in pixels
-                        -1 - don't care (should set "don't care" both width and height)
-     * int32[2]: height: same format with 'width'
-     * int32[3]: Inset - left: positive number - actual left inset value in pixels
+     * int32[1]: Bounds - left: positive number - left position in pixels
+                                -1 - don't care (should set all Bounds fields)
+     * int32[2]: Bounds - top:    same format with 'left'
+     * int32[3]: Bounds - right:  same format with 'left'
+     * int32[4]: Bounds - bottom: same format with 'left'
+     * int32[5]: Inset - left: positive number - actual left inset value in pixels
                                -1 - don't care (should set "don't care" all Inset fields)
-     * int32[4]: Inset - top:    same format with 'left'
-     * int32[5]: Inset - right:  same format with 'left'
-     * int32[6]: Inset - bottom: same format with 'left'
+     * int32[6]: Inset - top:    same format with 'left'
+     * int32[7]: Inset - right:  same format with 'left'
+     * int32[8]: Inset - bottom: same format with 'left'
      *
      * @change_mode VehiclePropertyChangeMode:ON_CHANGE
      * @access VehiclePropertyAccess:READ
@@ -3149,16 +3236,18 @@
      * match the state.
      *
      * int32[0]: on/off: 0 - off, 1 - on
-     * int32[1]: width
-     * int32[2]: height
-     * int32[3]: Inset - left
-     * int32[4]: Inset - top
-     * int32[5]: Inset - right
-     * int32[6]: Inset - bottom
-     * int32[7]: the type of ClusterUI in the fullscreen or main screen.
+     * int32[1]: Bounds - left
+     * int32[2]: Bounds - top
+     * int32[3]: Bounds - right
+     * int32[4]: Bounds - bottom
+     * int32[5]: Inset - left
+     * int32[6]: Inset - top
+     * int32[7]: Inset - right
+     * int32[8]: Inset - bottom
+     * int32[9]: the type of ClusterUI in the fullscreen or main screen.
      *    0 indicates ClusterHome.
      *    the other values are followed by OEM's definition.
-     * int32[8]: the type of ClusterUI in sub screen if the currently two UIs are shown.
+     * int32[10]: the type of ClusterUI in sub screen if the currently two UIs are shown.
      *    -1 indicates the area isn't used any more.
      * bytes: the array to represent the availability of ClusterUI.
      *     0 indicates non-available and 1 indicates available.
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl
index c19534c..eaa43f3 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl
@@ -34,30 +34,31 @@
 package android.hardware.biometrics.face;
 @Backing(type="byte") @VintfStability
 enum AcquiredInfo {
-  GOOD = 0,
-  INSUFFICIENT = 1,
-  TOO_BRIGHT = 2,
-  TOO_DARK = 3,
-  TOO_CLOSE = 4,
-  TOO_FAR = 5,
-  FACE_TOO_HIGH = 6,
-  FACE_TOO_LOW = 7,
-  FACE_TOO_RIGHT = 8,
-  FACE_TOO_LEFT = 9,
-  POOR_GAZE = 10,
-  NOT_DETECTED = 11,
-  TOO_MUCH_MOTION = 12,
-  RECALIBRATE = 13,
-  TOO_DIFFERENT = 14,
-  TOO_SIMILAR = 15,
-  PAN_TOO_EXTREME = 16,
-  TILT_TOO_EXTREME = 17,
-  ROLL_TOO_EXTREME = 18,
-  FACE_OBSCURED = 19,
-  START = 20,
-  SENSOR_DIRTY = 21,
-  VENDOR = 22,
-  FIRST_FRAME_RECEIVED = 23,
-  DARK_GLASSES_DETECTED = 24,
-  MOUTH_COVERING_DETECTED = 25,
+  UNKNOWN = 0,
+  GOOD = 1,
+  INSUFFICIENT = 2,
+  TOO_BRIGHT = 3,
+  TOO_DARK = 4,
+  TOO_CLOSE = 5,
+  TOO_FAR = 6,
+  FACE_TOO_HIGH = 7,
+  FACE_TOO_LOW = 8,
+  FACE_TOO_RIGHT = 9,
+  FACE_TOO_LEFT = 10,
+  POOR_GAZE = 11,
+  NOT_DETECTED = 12,
+  TOO_MUCH_MOTION = 13,
+  RECALIBRATE = 14,
+  TOO_DIFFERENT = 15,
+  TOO_SIMILAR = 16,
+  PAN_TOO_EXTREME = 17,
+  TILT_TOO_EXTREME = 18,
+  ROLL_TOO_EXTREME = 19,
+  FACE_OBSCURED = 20,
+  START = 21,
+  SENSOR_DIRTY = 22,
+  VENDOR = 23,
+  FIRST_FRAME_RECEIVED = 24,
+  DARK_GLASSES_DETECTED = 25,
+  MOUTH_COVERING_DETECTED = 26,
 }
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/BaseFrame.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/BaseFrame.aidl
index aa51343..67b5cf4 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/BaseFrame.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/BaseFrame.aidl
@@ -34,7 +34,7 @@
 package android.hardware.biometrics.face;
 @VintfStability
 parcelable BaseFrame {
-  android.hardware.biometrics.face.AcquiredInfo acquiredInfo = android.hardware.biometrics.face.AcquiredInfo.INSUFFICIENT;
+  android.hardware.biometrics.face.AcquiredInfo acquiredInfo = android.hardware.biometrics.face.AcquiredInfo.UNKNOWN;
   int vendorCode;
   float pan;
   float tilt;
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentFrame.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentFrame.aidl
index 982e759..0ea10d6 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentFrame.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentFrame.aidl
@@ -35,6 +35,6 @@
 @VintfStability
 parcelable EnrollmentFrame {
   @nullable android.hardware.biometrics.face.Cell cell;
-  android.hardware.biometrics.face.EnrollmentStage stage = android.hardware.biometrics.face.EnrollmentStage.FIRST_FRAME_RECEIVED;
+  android.hardware.biometrics.face.EnrollmentStage stage = android.hardware.biometrics.face.EnrollmentStage.UNKNOWN;
   android.hardware.biometrics.face.BaseFrame data;
 }
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStage.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStage.aidl
index 6be6e0b..ce5679a 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStage.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStage.aidl
@@ -34,10 +34,11 @@
 package android.hardware.biometrics.face;
 @Backing(type="byte") @VintfStability
 enum EnrollmentStage {
-  FIRST_FRAME_RECEIVED = 0,
-  WAITING_FOR_CENTERING = 1,
-  HOLD_STILL_IN_CENTER = 2,
-  ENROLLING_MOVEMENT_1 = 3,
-  ENROLLING_MOVEMENT_2 = 4,
-  ENROLLMENT_FINISHED = 5,
+  UNKNOWN = 0,
+  FIRST_FRAME_RECEIVED = 1,
+  WAITING_FOR_CENTERING = 2,
+  HOLD_STILL_IN_CENTER = 3,
+  ENROLLING_MOVEMENT_1 = 4,
+  ENROLLING_MOVEMENT_2 = 5,
+  ENROLLMENT_FINISHED = 6,
 }
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStageConfig.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStageConfig.aidl
index 232bd52..48db2cf 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStageConfig.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStageConfig.aidl
@@ -34,6 +34,6 @@
 package android.hardware.biometrics.face;
 @VintfStability
 parcelable EnrollmentStageConfig {
-  android.hardware.biometrics.face.EnrollmentStage stage = android.hardware.biometrics.face.EnrollmentStage.FIRST_FRAME_RECEIVED;
+  android.hardware.biometrics.face.EnrollmentStage stage = android.hardware.biometrics.face.EnrollmentStage.UNKNOWN;
   List<android.hardware.biometrics.face.Cell> cells;
 }
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Error.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Error.aidl
index 0437f07..1a21661 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Error.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Error.aidl
@@ -34,12 +34,13 @@
 package android.hardware.biometrics.face;
 @Backing(type="byte") @VintfStability
 enum Error {
+  UNKNOWN = 0,
   HW_UNAVAILABLE = 1,
   UNABLE_TO_PROCESS = 2,
   TIMEOUT = 3,
   NO_SPACE = 4,
   CANCELED = 5,
   UNABLE_TO_REMOVE = 6,
-  VENDOR = 8,
-  REENROLL_REQUIRED = 16,
+  VENDOR = 7,
+  REENROLL_REQUIRED = 8,
 }
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Feature.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Feature.aidl
index a8faf06..1875b97 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Feature.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Feature.aidl
@@ -34,7 +34,7 @@
 package android.hardware.biometrics.face;
 @Backing(type="byte") @VintfStability
 enum Feature {
-  WAVE_ATTENTION_REQUIREMENT = 0,
-  WAVE_DIVERSE_POSES_REQUIREMENT = 1,
+  REQUIRE_ATTENTION = 0,
+  REQUIRE_DIVERSE_POSES = 1,
   DEBUG = 2,
 }
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISession.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISession.aidl
index 9033989..d1c2c1d 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISession.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISession.aidl
@@ -36,13 +36,14 @@
 interface ISession {
   void generateChallenge();
   void revokeChallenge(in long challenge);
+  android.hardware.biometrics.face.EnrollmentStageConfig[] getEnrollmentConfig(in android.hardware.biometrics.face.EnrollmentType enrollmentType);
   android.hardware.biometrics.common.ICancellationSignal enroll(in android.hardware.keymaster.HardwareAuthToken hat, in android.hardware.biometrics.face.EnrollmentType type, in android.hardware.biometrics.face.Feature[] features, in android.hardware.common.NativeHandle previewSurface);
   android.hardware.biometrics.common.ICancellationSignal authenticate(in long operationId);
   android.hardware.biometrics.common.ICancellationSignal detectInteraction();
   void enumerateEnrollments();
   void removeEnrollments(in int[] enrollmentIds);
-  void getFeatures(in int enrollmentId);
-  void setFeature(in android.hardware.keymaster.HardwareAuthToken hat, in int enrollmentId, in android.hardware.biometrics.face.Feature feature, boolean enabled);
+  void getFeatures();
+  void setFeature(in android.hardware.keymaster.HardwareAuthToken hat, in android.hardware.biometrics.face.Feature feature, boolean enabled);
   void getAuthenticatorId();
   void invalidateAuthenticatorId();
   void resetLockout(in android.hardware.keymaster.HardwareAuthToken hat);
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl
index 2bb053a..bbace29 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl
@@ -47,8 +47,8 @@
   void onLockoutCleared();
   void onInteractionDetected();
   void onEnrollmentsEnumerated(in int[] enrollmentIds);
-  void onFeaturesRetrieved(in android.hardware.biometrics.face.Feature[] features, in int enrollmentId);
-  void onFeatureSet(in int enrollmentId, android.hardware.biometrics.face.Feature feature);
+  void onFeaturesRetrieved(in android.hardware.biometrics.face.Feature[] features);
+  void onFeatureSet(android.hardware.biometrics.face.Feature feature);
   void onEnrollmentsRemoved(in int[] enrollmentIds);
   void onAuthenticatorIdRetrieved(in long authenticatorId);
   void onAuthenticatorIdInvalidated(in long newAuthenticatorId);
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl
index c55a600..8b3c51b 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl
@@ -35,8 +35,9 @@
 @VintfStability
 parcelable SensorProps {
   android.hardware.biometrics.common.CommonProps commonProps;
-  android.hardware.biometrics.face.FaceSensorType sensorType = android.hardware.biometrics.face.FaceSensorType.RGB;
+  android.hardware.biometrics.face.FaceSensorType sensorType = android.hardware.biometrics.face.FaceSensorType.UNKNOWN;
   boolean halControlsPreview;
+  int previewDisplayId;
   int enrollPreviewWidth;
   int enrollPreviewHeight;
   float enrollTranslationX;
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl
index a3b229e..cf68421 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl
@@ -19,18 +19,24 @@
 @VintfStability
 @Backing(type="byte")
 enum AcquiredInfo {
+    /**
+     * Placeholder value used for default initialization of AcquiredInfo. This
+     * value means AcquiredInfo wasn't explicitly initialized and must be
+     * discarded by the recipient.
+     */
+    UNKNOWN,
 
     /**
      * The acquired face data was good, no further user interaction is necessary.
      */
-    GOOD = 0,
+    GOOD,
 
     /**
      * The acquired face data was too noisy or did not have sufficient detail.
      * This is a catch-all for all acquisition errors not captured by the other
      * constants.
      */
-    INSUFFICIENT = 1,
+    INSUFFICIENT,
 
     /**
      * Because there was too much ambient light, the captured face data was too
@@ -40,7 +46,7 @@
      * The user is expected to take action to retry the operation in better
      * lighting conditions when this is returned.
      */
-    TOO_BRIGHT = 2,
+    TOO_BRIGHT,
 
     /**
      * Because there was not enough illumination, the captured face data was too
@@ -50,7 +56,7 @@
      * The user is expected to take action to retry the operation in better
      * lighting conditions when this is returned.
      */
-    TOO_DARK = 3,
+    TOO_DARK,
 
     /**
      * The detected face is too close to the sensor, and the image cannot be
@@ -59,7 +65,7 @@
      * The user is expected to be informed to move further from the sensor when
      * this is returned.
      */
-    TOO_CLOSE = 4,
+    TOO_CLOSE,
 
     /**
      * The detected face is too small, as the user might be too far away from
@@ -68,7 +74,7 @@
      * The user is expected to be informed to move closer to the sensor when
      * this is returned.
      */
-    TOO_FAR = 5,
+    TOO_FAR,
 
     /**
      * Only the upper part of the face was detected. The sensor's field of view
@@ -77,7 +83,7 @@
      * The user should be informed to move up with respect to the sensor when
      * this is returned.
      */
-    FACE_TOO_HIGH = 6,
+    FACE_TOO_HIGH,
 
     /**
      * Only the lower part of the face was detected. The sensor's field of view
@@ -86,7 +92,7 @@
      * The user should be informed to move down with respect to the sensor when
      * this is returned.
      */
-    FACE_TOO_LOW = 7,
+    FACE_TOO_LOW,
 
     /**
      * Only the right part of the face was detected. The sensor's field of view
@@ -95,7 +101,7 @@
      * The user should be informed to move to the right with respect to the
      * sensor when this is returned.
      */
-    FACE_TOO_RIGHT = 8,
+    FACE_TOO_RIGHT,
 
     /**
      * Only the left part of the face was detected. The sensor's field of view
@@ -104,7 +110,7 @@
      * The user should be informed to move to the left with respect to the
      * sensor when this is returned.
      */
-    FACE_TOO_LEFT = 9,
+    FACE_TOO_LEFT,
 
     /**
      * The user's eyes have strayed away from the sensor. If this message is
@@ -112,7 +118,7 @@
      * can't be found in the frame, one of the other acquisition messages
      * must be sent, e.g. NOT_DETECTED.
      */
-    POOR_GAZE = 10,
+    POOR_GAZE,
 
     /**
      * No face was detected within the sensor's field of view.
@@ -120,7 +126,7 @@
      * The user should be informed to point the sensor to a face when this is
      * returned.
      */
-    NOT_DETECTED = 11,
+    NOT_DETECTED,
 
     /**
      * Too much motion was detected.
@@ -128,7 +134,7 @@
      * The user should be informed to keep their face steady relative to the
      * sensor.
      */
-    TOO_MUCH_MOTION = 12,
+    TOO_MUCH_MOTION,
 
     /**
      * The sensor needs to be re-calibrated. This is an unexpected condition,
@@ -137,20 +143,20 @@
      * re-enrolling. The expected response to this message is to direct the
      * user to re-enroll.
      */
-    RECALIBRATE = 13,
+    RECALIBRATE,
 
     /**
      * The face is too different from a previous acquisition. This condition
      * only applies to enrollment. This can happen if the user passes the
      * device to someone else in the middle of enrollment.
      */
-    TOO_DIFFERENT = 14,
+    TOO_DIFFERENT,
 
     /**
      * The face is too similar to a previous acquisition. This condition only
      * applies to enrollment. The user should change their pose.
      */
-    TOO_SIMILAR = 15,
+    TOO_SIMILAR,
 
     /**
      * The magnitude of the pan angle of the user’s face with respect to the sensor’s
@@ -162,7 +168,7 @@
      *
      * The user should be informed to look more directly at the camera.
      */
-    PAN_TOO_EXTREME = 16,
+    PAN_TOO_EXTREME,
 
     /**
      * The magnitude of the tilt angle of the user’s face with respect to the sensor’s
@@ -173,7 +179,7 @@
      *
      * The user should be informed to look more directly at the camera.
      */
-    TILT_TOO_EXTREME = 17,
+    TILT_TOO_EXTREME,
 
     /**
      * The magnitude of the roll angle of the user’s face with respect to the sensor’s
@@ -185,7 +191,7 @@
      *
      * The user should be informed to look more directly at the camera.
      */
-    ROLL_TOO_EXTREME = 18,
+    ROLL_TOO_EXTREME,
 
     /**
      * The user’s face has been obscured by some object.
@@ -193,7 +199,7 @@
      * The user should be informed to remove any objects from the line of sight from
      * the sensor to the user’s face.
      */
-    FACE_OBSCURED = 19,
+    FACE_OBSCURED,
 
     /**
      * This message represents the earliest message sent at the beginning of the authentication
@@ -202,33 +208,33 @@
      * will measure latency based on the time between the last START message and the onAuthenticated
      * callback.
      */
-    START = 20,
+    START,
 
     /**
      * The sensor is dirty. The user should be informed to clean the sensor.
      */
-    SENSOR_DIRTY = 21,
+    SENSOR_DIRTY,
 
     /**
      * Vendor-specific acquisition message. See ISessionCallback#onAcquired vendorCode
      * documentation.
      */
-    VENDOR = 22,
+    VENDOR,
 
     /**
      * The first frame from the camera has been received.
      */
-    FIRST_FRAME_RECEIVED = 23,
+    FIRST_FRAME_RECEIVED,
 
     /**
      * Dark glasses detected. This can be useful for providing relevant feedback to the user and
      * enabling an alternative authentication logic if the implementation supports it.
      */
-    DARK_GLASSES_DETECTED = 24,
+    DARK_GLASSES_DETECTED,
 
     /**
      * A face mask or face covering detected. This can be useful for providing relevant feedback to
      * the user and enabling an alternative authentication logic if the implementation supports it.
      */
-    MOUTH_COVERING_DETECTED = 25,
+    MOUTH_COVERING_DETECTED,
 }
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/AuthenticationFrame.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/AuthenticationFrame.aidl
index 47cad3c..be61a20 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/AuthenticationFrame.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/AuthenticationFrame.aidl
@@ -23,7 +23,6 @@
  */
 @VintfStability
 parcelable AuthenticationFrame {
-
     /**
      * The frame metadata. Can be used by the framework to provide user feedback.
      */
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/BaseFrame.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/BaseFrame.aidl
index 85535f9..58ad01a 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/BaseFrame.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/BaseFrame.aidl
@@ -29,7 +29,7 @@
      * Information about the frame that can be used by the framework to provide feedback to the
      * user, for example ask the user to move their face in a certain way.
      */
-    AcquiredInfo acquiredInfo = AcquiredInfo.INSUFFICIENT;
+    AcquiredInfo acquiredInfo = AcquiredInfo.UNKNOWN;
 
     /**
      * If acquiredInfo is set to AcquiredInfo::VENDOR. This is the index into the configuration
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentFrame.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentFrame.aidl
index ea0a502..ecb0e79 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentFrame.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentFrame.aidl
@@ -33,7 +33,7 @@
     /**
      * The enrollment stage for which this frame was captured.
      */
-    EnrollmentStage stage = EnrollmentStage.FIRST_FRAME_RECEIVED;
+    EnrollmentStage stage = EnrollmentStage.UNKNOWN;
 
     /**
      * The frame metadata. Can be used by the framework to provide user feedback.
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentStage.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentStage.aidl
index bbc874f..5974838 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentStage.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentStage.aidl
@@ -22,34 +22,40 @@
 @VintfStability
 @Backing(type="byte")
 enum EnrollmentStage {
+    /**
+     * Placeholder value used for default initialization of EnrollmentStage. This
+     * value means EnrollmentStage wasn't explicitly initialized and must be
+     * discarded by the recipient.
+     */
+    UNKNOWN,
 
-  /**
-   * HAL has obtained the first camera frame.
-   */
-   FIRST_FRAME_RECEIVED,
+    /**
+     * HAL has obtained the first camera frame.
+     */
+    FIRST_FRAME_RECEIVED,
 
-  /**
-   * HAL is waiting for the user's face to be centered.
-   */
-   WAITING_FOR_CENTERING,
+    /**
+     * HAL is waiting for the user's face to be centered.
+     */
+    WAITING_FOR_CENTERING,
 
-  /**
-   * HAL is expecting the user's face to stay centered.
-   */
-   HOLD_STILL_IN_CENTER,
+    /**
+     * HAL is expecting the user's face to stay centered.
+     */
+    HOLD_STILL_IN_CENTER,
 
-  /**
-   * Vendor defined movement 1.
-   */
-   ENROLLING_MOVEMENT_1,
+    /**
+     * Vendor defined movement 1.
+     */
+    ENROLLING_MOVEMENT_1,
 
-  /**
-   * Vendor defined movement 2.
-   */
-   ENROLLING_MOVEMENT_2,
+    /**
+     * Vendor defined movement 2.
+     */
+    ENROLLING_MOVEMENT_2,
 
-  /**
-   * HAL has finished the enrollment.
-   */
-   ENROLLMENT_FINISHED,
+    /**
+     * HAL has finished the enrollment.
+     */
+    ENROLLMENT_FINISHED,
 }
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentStageConfig.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentStageConfig.aidl
index 3c31fcc..a8fa9ab 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentStageConfig.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentStageConfig.aidl
@@ -24,7 +24,7 @@
     /**
      * The stage that's being configured.
      */
-    EnrollmentStage stage = EnrollmentStage.FIRST_FRAME_RECEIVED;
+    EnrollmentStage stage = EnrollmentStage.UNKNOWN;
 
     /**
      * Optional list of cells that must be completed to finish this stage.
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/Error.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/Error.aidl
index 6f3264b..e99415a 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/Error.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/Error.aidl
@@ -20,22 +20,22 @@
 @Backing(type="byte")
 enum Error {
     /**
-     * Reserved for testing and to keep subsequent numbering consistent with
-     * older interfaces.
-     *
-     * NO_ERROR = 0,
+     * Placeholder value used for default initialization of Error. This value
+     * means Error wasn't explicitly initialized and must be discarded by the
+     * recipient.
      */
+    UNKNOWN,
 
     /**
      * A hardware error has occurred that cannot be resolved. Try again later.
      */
-    HW_UNAVAILABLE = 1,
+    HW_UNAVAILABLE,
 
     /**
      * The current operation could not be completed, e.g. the sensor was unable
      * to process the current image or the HAT was invalid.
      */
-    UNABLE_TO_PROCESS = 2,
+    UNABLE_TO_PROCESS,
 
     /**
      * The current operation took too long to complete. This is intended to
@@ -48,48 +48,34 @@
      * indicate that the implementation is no longer looking and the framework
      * should restart the operation on the next user interaction.
      */
-    TIMEOUT = 3,
+    TIMEOUT,
 
     /**
      * The current operation could not be completed because there is not enough
      * storage space remaining to do so.
      */
-    NO_SPACE = 4,
+    NO_SPACE,
 
     /**
      * The current operation has been cancelled. This may happen if a new
      * request (authenticate, remove, enumerate, enroll) is initiated while
      * an on-going operation is in progress, or if cancel() was called.
      */
-    CANCELED = 5,
+    CANCELED,
 
     /**
      * The current remove operation could not be completed; the face template
      * provided could not be removed.
      */
-    UNABLE_TO_REMOVE = 6,
-
-    /**
-     * Reserved to maintain backwards compatibility. See
-     * ISessionCallback#onLockoutTimed instead.
-     *
-     * LOCKOUT = 7,
-     */
+    UNABLE_TO_REMOVE,
 
     /**
      * Used to enable a vendor-specific error message.
      */
-    VENDOR = 8,
-
-    /**
-     * Reserved to maintain backwards compatibility. See
-     * ISessionCallback#onLockoutPermanent instead.
-     *
-     * LOCKOUT_PERMANENT = 9
-     */
+    VENDOR,
 
     /**
      * Authentication cannot be performed because re-enrollment is required.
      */
-    REENROLL_REQUIRED = 16,
+    REENROLL_REQUIRED,
 }
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/Feature.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/Feature.aidl
index b88050a..bff1a02 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/Feature.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/Feature.aidl
@@ -20,20 +20,19 @@
 @Backing(type="byte")
 enum Feature {
     /**
-     * Do not require the user to look at the device during enrollment and authentication. Note
-     * this is to accommodate people who have limited vision.
+     * Require the user to look at the device during enrollment and authentication. This feature
+     * can be disabled to accommodate people who have limited vision.
      */
-    WAVE_ATTENTION_REQUIREMENT,
+    REQUIRE_ATTENTION,
 
     /**
-     * Do not require a diverse set of poses during enrollment. This is to accommodate people with
-     * limited mobility.
+     * Require a diverse set of poses during enrollment. This feature can be disabled to accommodate
+     * people with limited mobility.
      */
-    WAVE_DIVERSE_POSES_REQUIREMENT,
+    REQUIRE_DIVERSE_POSES,
 
     /**
      * Enable debugging functionality.
      */
     DEBUG,
 }
-
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl
index 9734873..a9a8c16 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl
@@ -17,6 +17,7 @@
 package android.hardware.biometrics.face;
 
 import android.hardware.biometrics.common.ICancellationSignal;
+import android.hardware.biometrics.face.EnrollmentStageConfig;
 import android.hardware.biometrics.face.EnrollmentType;
 import android.hardware.biometrics.face.Feature;
 import android.hardware.common.NativeHandle;
@@ -104,9 +105,9 @@
      * each of the stages.
      *
      * @param enrollmentType See the EnrollmentType enum.
-     * @return A list of EnrollmentStageConfig that describes each enrollment stage.
-     *
-    List<EnrollmentStageConfig> getEnrollmentConfig(in EnrollmentType enrollmentType);
+     * @return An EnrollmentStageConfig array that describes each enrollment stage.
+     */
+    EnrollmentStageConfig[] getEnrollmentConfig(in EnrollmentType enrollmentType);
 
     /**
      * enroll:
@@ -249,38 +250,34 @@
     /**
      * getFeatures:
      *
-     * Returns a list of currently enabled features for the provided enrollmentId.
+     * Returns a list of currently enabled features for this (sensorId, userId) pair.
      *
-     * If the enrollmentId is invalid, the HAL must invoke ISessionCallback#onError with
+     * If the user is not enrolled, the HAL must invoke ISessionCallback#onError with
      * Error::UNABLE_TO_PROCESS.
      *
      * The HAL must notify the framework about the result by calling
      * ISessionCallback#onFeaturesRetrieved.
-     *
-     * @param enrollmentId the ID of the enrollment for which the features are requested.
      */
-    void getFeatures(in int enrollmentId);
+    void getFeatures();
 
     /**
      * setFeature:
      *
-     * Enables or disables a feature for the given enrollmentId. Because certain features may
+     * Enables or disables a feature for this (sensorId, userId) pair. Because certain features may
      * decrease security, the user must enter their password before this method is invoked
      * (see @param hat). The HAL must verify the hat before changing any feature state.
      *
-     * If either the hat or enrollmentId is invalid, the HAL must invoke ISessionCallback#onError
-     * with Error::UNABLE_TO_PROCESS.
+     * If the hat is invalid or if the user is not enrolled, the HAL must invoke
+     * ISessionCallback#onError with Error::UNABLE_TO_PROCESS.
      *
      * After the feature is successfully set, the HAL must notify the framework by calling
      * ISessionCallback#onFeatureSet.
      *
      * @param hat HardwareAuthToken See above documentation.
-     * @param enrollmentId the ID of the enrollment for which the feature update is requested.
      * @param feature The feature to be enabled or disabled.
      * @param enabled Whether the provided features should be enabled or disabled.
      */
-    void setFeature(
-            in HardwareAuthToken hat, in int enrollmentId, in Feature feature, boolean enabled);
+    void setFeature(in HardwareAuthToken hat, in Feature feature, boolean enabled);
 
     /**
      * getAuthenticatorId:
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl
index a2601e7..23570bd 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl
@@ -172,22 +172,21 @@
     /**
      * This method must only be used to notify the framework during ISession#getFeatures.
      *
-     * Provides a list of features that are currently enabled for the given enrollmentId.
+     * Provides a list of features that are currently enabled for the session's (userId, sensorId)
+     * pair.
      *
      * @param features A list of currently enabled features. See the Feature enum.
-     * @param enrollmentId The enrollment for which the features were requested.
      */
-    void onFeaturesRetrieved(in Feature[] features, in int enrollmentId);
+    void onFeaturesRetrieved(in Feature[] features);
 
     /**
      * This method must only be used to notify the framework during ISession#setFeature.
      *
      * Notifies the framework that ISession#setFeature has completed.
      *
-     * @param enrollmentId The enrollment for which a feature was set.
      * @param feature The feature that was set.
      */
-    void onFeatureSet(in int enrollmentId, Feature feature);
+    void onFeatureSet(Feature feature);
 
     /**
      * This method must only be used to notify the framework during
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl
index b11b436..5f881ca 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl
@@ -29,7 +29,7 @@
     /**
      * A statically configured sensor type representing this face sensor.
      */
-    FaceSensorType sensorType = FaceSensorType.RGB;
+    FaceSensorType sensorType = FaceSensorType.UNKNOWN;
 
     /**
      * Whether or not the HAL is responsible for showing the face enrollment preview to the user.
@@ -41,6 +41,13 @@
     boolean halControlsPreview;
 
     /**
+     * The ID of the display that's used for enrollment preview. This must correspond to the
+     * android.hardware.DisplayManager#getDisplay Android API. This is useful for devices with
+     * multiple displays to ensure the correct display is used for this face sensor.
+     */
+    int previewDisplayId;
+
+    /**
      * For implementations where the HAL manages the preview, this is the width, in pixels, of each
      * frame that the camera is set up to output.
      */
diff --git a/biometrics/face/aidl/default/Session.cpp b/biometrics/face/aidl/default/Session.cpp
index b5eb717..d980c5f 100644
--- a/biometrics/face/aidl/default/Session.cpp
+++ b/biometrics/face/aidl/default/Session.cpp
@@ -52,6 +52,12 @@
     return ndk::ScopedAStatus::ok();
 }
 
+ndk::ScopedAStatus Session::getEnrollmentConfig(EnrollmentType /*enrollmentType*/,
+                                                std::vector<EnrollmentStageConfig>* return_val) {
+    *return_val = {};
+    return ndk::ScopedAStatus::ok();
+}
+
 ndk::ScopedAStatus Session::enroll(
         const keymaster::HardwareAuthToken& /*hat*/, EnrollmentType /*enrollmentType*/,
         const std::vector<Feature>& /*features*/, const NativeHandle& /*previewSurface*/,
@@ -92,14 +98,13 @@
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus Session::getFeatures(int32_t /*enrollmentId*/) {
+ndk::ScopedAStatus Session::getFeatures() {
     LOG(INFO) << "getFeatures";
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus Session::setFeature(const keymaster::HardwareAuthToken& /*hat*/,
-                                       int32_t /*enrollmentId*/, Feature /*feature*/,
-                                       bool /*enabled*/) {
+                                       Feature /*feature*/, bool /*enabled*/) {
     LOG(INFO) << "setFeature";
     return ndk::ScopedAStatus::ok();
 }
diff --git a/biometrics/face/aidl/default/Session.h b/biometrics/face/aidl/default/Session.h
index 73cdf08..caf81f8 100644
--- a/biometrics/face/aidl/default/Session.h
+++ b/biometrics/face/aidl/default/Session.h
@@ -34,6 +34,9 @@
 
     ndk::ScopedAStatus revokeChallenge(int64_t challenge) override;
 
+    ndk::ScopedAStatus getEnrollmentConfig(EnrollmentType enrollmentType,
+                                           std::vector<EnrollmentStageConfig>* return_val) override;
+
     ndk::ScopedAStatus enroll(const keymaster::HardwareAuthToken& hat,
                               EnrollmentType enrollmentType, const std::vector<Feature>& features,
                               const NativeHandle& previewSurface,
@@ -50,10 +53,10 @@
 
     ndk::ScopedAStatus removeEnrollments(const std::vector<int32_t>& enrollmentIds) override;
 
-    ndk::ScopedAStatus getFeatures(int32_t enrollmentId) override;
+    ndk::ScopedAStatus getFeatures() override;
 
-    ndk::ScopedAStatus setFeature(const keymaster::HardwareAuthToken& hat, int32_t enrollmentId,
-                                  Feature feature, bool enabled) override;
+    ndk::ScopedAStatus setFeature(const keymaster::HardwareAuthToken& hat, Feature feature,
+                                  bool enabled) override;
 
     ndk::ScopedAStatus getAuthenticatorId() override;
 
diff --git a/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp b/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp
index 60e0a2a..ada6f73 100644
--- a/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp
+++ b/biometrics/face/aidl/vts/VtsHalBiometricsFaceTargetTest.cpp
@@ -104,12 +104,11 @@
         return ndk::ScopedAStatus::ok();
     }
 
-    ndk::ScopedAStatus onFeaturesRetrieved(const std::vector<Feature>& /*features*/,
-                                           int32_t /*enrollmentId*/) override {
+    ndk::ScopedAStatus onFeaturesRetrieved(const std::vector<Feature>& /*features*/) override {
         return ndk::ScopedAStatus::ok();
     }
 
-    ndk::ScopedAStatus onFeatureSet(int32_t /*enrollmentId*/, Feature /*feature*/) override {
+    ndk::ScopedAStatus onFeatureSet(Feature /*feature*/) override {
         return ndk::ScopedAStatus::ok();
     }
 
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
index 2c2011a..c51aa03 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
@@ -34,16 +34,17 @@
 package android.hardware.biometrics.fingerprint;
 @Backing(type="byte") @VintfStability
 enum AcquiredInfo {
-  GOOD = 0,
-  PARTIAL = 1,
-  INSUFFICIENT = 2,
-  SENSOR_DIRTY = 3,
-  TOO_SLOW = 4,
-  TOO_FAST = 5,
-  VENDOR = 6,
-  START = 7,
-  TOO_DARK = 8,
-  TOO_BRIGHT = 9,
-  IMMOBILE = 10,
-  RETRYING_CAPTURE = 11,
+  UNKNOWN = 0,
+  GOOD = 1,
+  PARTIAL = 2,
+  INSUFFICIENT = 3,
+  SENSOR_DIRTY = 4,
+  TOO_SLOW = 5,
+  TOO_FAST = 6,
+  VENDOR = 7,
+  START = 8,
+  TOO_DARK = 9,
+  TOO_BRIGHT = 10,
+  IMMOBILE = 11,
+  RETRYING_CAPTURE = 12,
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl
index f79c576..060379d 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl
@@ -34,11 +34,12 @@
 package android.hardware.biometrics.fingerprint;
 @Backing(type="byte") @VintfStability
 enum Error {
+  UNKNOWN = 0,
   HW_UNAVAILABLE = 1,
   UNABLE_TO_PROCESS = 2,
   TIMEOUT = 3,
   NO_SPACE = 4,
   CANCELED = 5,
   UNABLE_TO_REMOVE = 6,
-  VENDOR = 8,
+  VENDOR = 7,
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl
index c7a4002..782d289 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl
@@ -39,4 +39,6 @@
   android.hardware.biometrics.fingerprint.SensorLocation[] sensorLocations;
   boolean supportsNavigationGestures;
   boolean supportsDetectInteraction;
+  boolean halHandlesDisplayTouches;
+  boolean halControlsIllumination;
 }
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
index b406947..8ec8574 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
@@ -20,6 +20,13 @@
 @Backing(type="byte")
 enum AcquiredInfo {
     /**
+     * Placeholder value used for default initialization of AcquiredInfo. This
+     * value means AcquiredInfo wasn't explicitly initialized and must be
+     * discarded by the recipient.
+     */
+    UNKNOWN,
+
+    /**
      * A high quality fingerprint image was detected, no further user interaction is necessary.
      */
     GOOD,
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/Error.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/Error.aidl
index 4fe7f5f..fc89da2 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/Error.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/Error.aidl
@@ -20,57 +20,47 @@
 @Backing(type="byte")
 enum Error {
     /**
-     * Used for testing, and to keep subsequent numbering consistent with older HIDLs.
+     * Placeholder value used for default initialization of Error. This value
+     * means Error wasn't explicitly initialized and must be discarded by the
+     * recipient.
      */
-    // NO_ERROR = 0,
+    UNKNOWN,
 
     /**
      * A hardware error has occurred that cannot be resolved. For example, I2C failure or a broken
      * sensor.
      */
-    HW_UNAVAILABLE = 1,
+    HW_UNAVAILABLE,
 
     /**
      * The implementation is unable to process the request. For example, invalid arguments were
      * supplied.
      */
-    UNABLE_TO_PROCESS = 2,
+    UNABLE_TO_PROCESS,
 
     /**
      * The current operation took too long to complete.
      */
-    TIMEOUT = 3,
+    TIMEOUT,
 
     /**
      * No space available to store additional enrollments.
      */
-    NO_SPACE = 4,
+    NO_SPACE,
 
     /**
      * The operation was canceled. See common::ICancellationSignal.
      */
-    CANCELED = 5,
+    CANCELED,
 
     /**
      * The implementation was unable to remove an enrollment.
      * See ISession#removeEnrollments.
      */
-    UNABLE_TO_REMOVE = 6,
-
-    /**
-     * Reserved to maintain backwards compatibility. See ISessionCallback#onLockoutTimed instead.
-     */
-    // LOCKOUT = 7,
+    UNABLE_TO_REMOVE,
 
     /**
      * Used to enable vendor-specific error messages.
      */
-    VENDOR = 8,
-
-    /**
-     * Reserved to maintain backwards compatibility. See ISessionCallback#onLockoutPermanent
-     * instead.
-     */
-    // LOCKOUT_PERMANENT = 9,
+    VENDOR,
 }
-
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl
index 765a2ed..dbe7137 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl
@@ -26,4 +26,3 @@
     POWER_BUTTON,
     HOME_BUTTON
 }
-
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl
index 940548b..02ef138 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl
@@ -42,8 +42,8 @@
  * have callbacks.
  *
  * ISession only supports execution of one non-interrupting operation at a time, regardless of
- * whether it's cancellable. The framework must wait for a corresponding callback indicating the end of
- * the current non-interrupting operation before a new non-interrupting operation can be started.
+ * whether it's cancellable. The framework must wait for a corresponding callback indicating the end
+ * of the current non-interrupting operation before a new non-interrupting operation can be started.
  */
 @VintfStability
 interface ISession {
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorLocation.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorLocation.aidl
index 62a2e8c..b1618b2 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorLocation.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorLocation.aidl
@@ -51,4 +51,4 @@
      * in pixels.
      */
     int sensorRadius;
-}
\ No newline at end of file
+}
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl
index fd2cf47..fb516da 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/SensorProps.aidl
@@ -48,4 +48,26 @@
      * Specifies whether or not the implementation supports ISession#detectInteraction.
      */
     boolean supportsDetectInteraction;
+
+    /**
+     * Whether the HAL is responsible for detecting and processing of display touches. This is only
+     * applicable to under-display fingerprint sensors (UDFPS). If the value is false, the framework
+     * will be responsible for handling the display touch events and passing them down to the HAL by
+     * using ISession#onPointerDown and ISession#onPointerUp. If the value is true, the framework
+     * will not notify the HAL about touch events.
+     *
+     * This value must be ignored for non-UDFPS sensors.
+     */
+    boolean halHandlesDisplayTouches;
+
+    /**
+     * Whether the HAL is responsible for fingerprint illumination, for example through enabling the
+     * display's high-brightness mode. This is only applicable to optical under-display fingerprint
+     * sensors (optical UDFPS). If the value is false, the framework will be responsible for
+     * illuminating the finger and reporting ISession#onUiReady. If the value is true, the framework
+     * will not illuminate the finger and will not report ISession#onUiReady.
+     *
+     * This value must be ignored for sensors that aren't optical UDFPS.
+     */
+    boolean halControlsIllumination;
 }
diff --git a/biometrics/fingerprint/aidl/vts/Android.bp b/biometrics/fingerprint/aidl/vts/Android.bp
index 0d83e74..5539548 100644
--- a/biometrics/fingerprint/aidl/vts/Android.bp
+++ b/biometrics/fingerprint/aidl/vts/Android.bp
@@ -14,9 +14,13 @@
         "use_libaidlvintf_gtest_helper_static",
     ],
     srcs: ["VtsHalBiometricsFingerprintTargetTest.cpp"],
+    static_libs: [
+        "android.hardware.biometrics.common-V1-ndk_platform",
+        "android.hardware.biometrics.fingerprint-V1-ndk_platform",
+        "android.hardware.keymaster-V3-ndk_platform",
+    ],
     shared_libs: [
         "libbinder_ndk",
-        "android.hardware.biometrics.fingerprint-V1-ndk_platform",
     ],
     test_suites: [
         "general-tests",
diff --git a/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp b/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp
index 25c990b..0df2b8d 100644
--- a/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp
+++ b/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp
@@ -73,10 +73,15 @@
 
     IComposerClient::Rect getFrameRect() const { return {0, 0, mDisplayWidth, mDisplayHeight}; }
 
+    void setDimensions(int32_t displayWidth, int32_t displayHeight) const {
+        mDisplayWidth = displayWidth;
+        mDisplayHeight = displayHeight;
+    }
+
   private:
     const Display mDisplay;
-    const int32_t mDisplayWidth;
-    const int32_t mDisplayHeight;
+    mutable int32_t mDisplayWidth;
+    mutable int32_t mDisplayHeight;
 };
 
 class GraphicsComposerHidlTest : public ::testing::TestWithParam<std::string> {
@@ -194,6 +199,31 @@
                                        const std::vector<ContentType>& capabilities,
                                        const ContentType& contentType, const char* contentTypeStr);
 
+    Error setActiveConfigWithConstraints(
+            const VtsDisplay& display, Config config,
+            const IComposerClient::VsyncPeriodChangeConstraints& constraints,
+            VsyncPeriodChangeTimeline* timeline) {
+        const auto error = mComposerClient->setActiveConfigWithConstraints(display.get(), config,
+                                                                           constraints, timeline);
+        if (error == Error::NONE) {
+            const int32_t displayWidth = mComposerClient->getDisplayAttribute_2_4(
+                    display.get(), config, IComposerClient::Attribute::WIDTH);
+            const int32_t displayHeight = mComposerClient->getDisplayAttribute_2_4(
+                    display.get(), config, IComposerClient::Attribute::HEIGHT);
+            display.setDimensions(displayWidth, displayHeight);
+        }
+        return error;
+    }
+
+    void setActiveConfig(const VtsDisplay& display, Config config) {
+        mComposerClient->setActiveConfig(display.get(), config);
+        const int32_t displayWidth = mComposerClient->getDisplayAttribute_2_4(
+                display.get(), config, IComposerClient::Attribute::WIDTH);
+        const int32_t displayHeight = mComposerClient->getDisplayAttribute_2_4(
+                display.get(), config, IComposerClient::Attribute::HEIGHT);
+        display.setDimensions(displayWidth, displayHeight);
+    }
+
   private:
     // use the slot count usually set by SF
     static constexpr uint32_t kBufferSlotCount = 64;
@@ -358,8 +388,8 @@
 
             constraints.desiredTimeNanos = systemTime();
             constraints.seamlessRequired = false;
-            EXPECT_EQ(Error::NONE, mComposerClient->setActiveConfigWithConstraints(
-                                           display.get(), config, constraints, &timeline));
+            EXPECT_EQ(Error::NONE,
+                      setActiveConfigWithConstraints(display, config, constraints, &timeline));
 
             if (timeline.refreshRequired) {
                 sendRefreshFrame(display, &timeline);
@@ -414,8 +444,7 @@
     for (const auto& display : mDisplays) {
         Config invalidConfigId = GetInvalidConfigId(display.get());
         EXPECT_EQ(Error::BAD_CONFIG,
-                  mComposerClient->setActiveConfigWithConstraints(display.get(), invalidConfigId,
-                                                                  constraints, &timeline));
+                  setActiveConfigWithConstraints(display, invalidConfigId, constraints, &timeline));
     }
 }
 
@@ -435,11 +464,10 @@
                     display.get(), config2,
                     IComposerClient::IComposerClient::Attribute::CONFIG_GROUP);
             if (configGroup1 != configGroup2) {
-                mComposerClient->setActiveConfig(display.get(), config1);
+                setActiveConfig(display, config1);
                 sendRefreshFrame(display, nullptr);
                 EXPECT_EQ(Error::SEAMLESS_NOT_ALLOWED,
-                          mComposerClient->setActiveConfigWithConstraints(display.get(), config2,
-                                                                          constraints, &timeline));
+                          setActiveConfigWithConstraints(display, config2, constraints, &timeline));
             }
         });
     }
@@ -505,6 +533,8 @@
 
     mWriter->presentDisplay();
     execute();
+
+    ASSERT_NO_FATAL_FAILURE(mComposerClient->destroyLayer(display.get(), layer));
 }
 
 void GraphicsComposerHidlTest::waitForVsyncPeriodChange(Display display,
@@ -528,7 +558,7 @@
 void GraphicsComposerHidlTest::Test_setActiveConfigWithConstraints(const TestParameters& params) {
     for (const auto& display : mDisplays) {
         forEachTwoConfigs(display.get(), [&](Config config1, Config config2) {
-            mComposerClient->setActiveConfig(display.get(), config1);
+            setActiveConfig(display, config1);
             sendRefreshFrame(display, nullptr);
 
             int32_t vsyncPeriod1 = mComposerClient->getDisplayAttribute_2_4(
@@ -546,8 +576,8 @@
             IComposerClient::VsyncPeriodChangeConstraints constraints = {
                     .desiredTimeNanos = systemTime() + params.delayForChange,
                     .seamlessRequired = false};
-            EXPECT_EQ(Error::NONE, mComposerClient->setActiveConfigWithConstraints(
-                                           display.get(), config2, constraints, &timeline));
+            EXPECT_EQ(Error::NONE,
+                      setActiveConfigWithConstraints(display, config2, constraints, &timeline));
 
             EXPECT_TRUE(timeline.newVsyncAppliedTimeNanos >= constraints.desiredTimeNanos);
             // Refresh rate should change within a reasonable time
diff --git a/identity/aidl/default/Android.bp b/identity/aidl/default/Android.bp
index a124b1e..7c68aee 100644
--- a/identity/aidl/default/Android.bp
+++ b/identity/aidl/default/Android.bp
@@ -32,6 +32,7 @@
     static_libs: [
         "libbase",
         "libcppbor_external",
+        "libcppcose_rkp",
         "libutils",
         "libsoft_attestation_cert",
         "libkeymaster_portable",
@@ -92,6 +93,7 @@
     static_libs: [
         "libbase",
         "libcppbor_external",
+        "libcppcose_rkp",
         "libutils",
         "libsoft_attestation_cert",
         "libkeymaster_portable",
diff --git a/identity/aidl/vts/Android.bp b/identity/aidl/vts/Android.bp
index 3592d3e..61d15d2 100644
--- a/identity/aidl/vts/Android.bp
+++ b/identity/aidl/vts/Android.bp
@@ -35,6 +35,7 @@
     ],
     static_libs: [
         "libcppbor_external",
+        "libcppcose_rkp",
         "libkeymaster_portable",
         "libpuresoftkeymasterdevice",
         "android.hardware.keymaster@4.0",
diff --git a/identity/support/Android.bp b/identity/support/Android.bp
index 774bc40..db1a945 100644
--- a/identity/support/Android.bp
+++ b/identity/support/Android.bp
@@ -35,6 +35,7 @@
         "android.hardware.keymaster@4.0",
         "libcrypto",
         "libbase",
+        "libcppcose_rkp",
         "libhidlbase",
         "libhardware",
         "libkeymaster_portable",
diff --git a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Device.h b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Device.h
index 4681b9e..db3b2ad 100644
--- a/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Device.h
+++ b/neuralnetworks/1.0/utils/include/nnapi/hal/1.0/Device.h
@@ -52,7 +52,6 @@
     const std::string& getVersionString() const override;
     nn::Version getFeatureLevel() const override;
     nn::DeviceType getType() const override;
-    bool isUpdatable() const override;
     const std::vector<nn::Extension>& getSupportedExtensions() const override;
     const nn::Capabilities& getCapabilities() const override;
     std::pair<uint32_t, uint32_t> getNumberOfCacheFilesNeeded() const override;
diff --git a/neuralnetworks/1.0/utils/src/Device.cpp b/neuralnetworks/1.0/utils/src/Device.cpp
index bb31a26..93bd81a 100644
--- a/neuralnetworks/1.0/utils/src/Device.cpp
+++ b/neuralnetworks/1.0/utils/src/Device.cpp
@@ -106,10 +106,6 @@
     return nn::DeviceType::OTHER;
 }
 
-bool Device::isUpdatable() const {
-    return false;
-}
-
 const std::vector<nn::Extension>& Device::getSupportedExtensions() const {
     return kExtensions;
 }
diff --git a/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Device.h b/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Device.h
index 3aec8ee..5e224b5 100644
--- a/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Device.h
+++ b/neuralnetworks/1.1/utils/include/nnapi/hal/1.1/Device.h
@@ -52,7 +52,6 @@
     const std::string& getVersionString() const override;
     nn::Version getFeatureLevel() const override;
     nn::DeviceType getType() const override;
-    bool isUpdatable() const override;
     const std::vector<nn::Extension>& getSupportedExtensions() const override;
     const nn::Capabilities& getCapabilities() const override;
     std::pair<uint32_t, uint32_t> getNumberOfCacheFilesNeeded() const override;
diff --git a/neuralnetworks/1.1/utils/src/Device.cpp b/neuralnetworks/1.1/utils/src/Device.cpp
index d2ef57f..3197ef4 100644
--- a/neuralnetworks/1.1/utils/src/Device.cpp
+++ b/neuralnetworks/1.1/utils/src/Device.cpp
@@ -106,10 +106,6 @@
     return nn::DeviceType::UNKNOWN;
 }
 
-bool Device::isUpdatable() const {
-    return false;
-}
-
 const std::vector<nn::Extension>& Device::getSupportedExtensions() const {
     return kExtensions;
 }
diff --git a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Device.h b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Device.h
index 489f857..b4bef5e 100644
--- a/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Device.h
+++ b/neuralnetworks/1.2/utils/include/nnapi/hal/1.2/Device.h
@@ -71,7 +71,6 @@
     const std::string& getVersionString() const override;
     nn::Version getFeatureLevel() const override;
     nn::DeviceType getType() const override;
-    bool isUpdatable() const override;
     const std::vector<nn::Extension>& getSupportedExtensions() const override;
     const nn::Capabilities& getCapabilities() const override;
     std::pair<uint32_t, uint32_t> getNumberOfCacheFilesNeeded() const override;
diff --git a/neuralnetworks/1.2/utils/src/Device.cpp b/neuralnetworks/1.2/utils/src/Device.cpp
index 1954dfa..9fe0de2 100644
--- a/neuralnetworks/1.2/utils/src/Device.cpp
+++ b/neuralnetworks/1.2/utils/src/Device.cpp
@@ -199,10 +199,6 @@
     return kDeviceType;
 }
 
-bool Device::isUpdatable() const {
-    return false;
-}
-
 const std::vector<nn::Extension>& Device::getSupportedExtensions() const {
     return kExtensions;
 }
diff --git a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Device.h b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Device.h
index f36b6c0..84f606a 100644
--- a/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Device.h
+++ b/neuralnetworks/1.3/utils/include/nnapi/hal/1.3/Device.h
@@ -54,7 +54,6 @@
     const std::string& getVersionString() const override;
     nn::Version getFeatureLevel() const override;
     nn::DeviceType getType() const override;
-    bool isUpdatable() const override;
     const std::vector<nn::Extension>& getSupportedExtensions() const override;
     const nn::Capabilities& getCapabilities() const override;
     std::pair<uint32_t, uint32_t> getNumberOfCacheFilesNeeded() const override;
diff --git a/neuralnetworks/1.3/utils/src/Device.cpp b/neuralnetworks/1.3/utils/src/Device.cpp
index 87c9f32..d710b85 100644
--- a/neuralnetworks/1.3/utils/src/Device.cpp
+++ b/neuralnetworks/1.3/utils/src/Device.cpp
@@ -150,10 +150,6 @@
     return kDeviceType;
 }
 
-bool Device::isUpdatable() const {
-    return false;
-}
-
 const std::vector<nn::Extension>& Device::getSupportedExtensions() const {
     return kExtensions;
 }
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IBurst.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IBurst.aidl
index 634f39e..eb3d0b0 100644
--- a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IBurst.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IBurst.aidl
@@ -34,6 +34,6 @@
 package android.hardware.neuralnetworks;
 @VintfStability
 interface IBurst {
-  android.hardware.neuralnetworks.ExecutionResult executeSynchronously(in android.hardware.neuralnetworks.Request request, in long[] memoryIdentifierTokens, in boolean measureTiming, in long deadline, in long loopTimeoutDuration);
+  android.hardware.neuralnetworks.ExecutionResult executeSynchronously(in android.hardware.neuralnetworks.Request request, in long[] memoryIdentifierTokens, in boolean measureTiming, in long deadlineNs, in long loopTimeoutDurationNs);
   void releaseMemoryResource(in long memoryIdentifierToken);
 }
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IDevice.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IDevice.aidl
index b328b29..c9c67f2 100644
--- a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IDevice.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IDevice.aidl
@@ -41,8 +41,8 @@
   boolean[] getSupportedOperations(in android.hardware.neuralnetworks.Model model);
   android.hardware.neuralnetworks.DeviceType getType();
   String getVersionString();
-  void prepareModel(in android.hardware.neuralnetworks.Model model, in android.hardware.neuralnetworks.ExecutionPreference preference, in android.hardware.neuralnetworks.Priority priority, in long deadline, in ParcelFileDescriptor[] modelCache, in ParcelFileDescriptor[] dataCache, in byte[] token, in android.hardware.neuralnetworks.IPreparedModelCallback callback);
-  void prepareModelFromCache(in long deadline, in ParcelFileDescriptor[] modelCache, in ParcelFileDescriptor[] dataCache, in byte[] token, in android.hardware.neuralnetworks.IPreparedModelCallback callback);
+  void prepareModel(in android.hardware.neuralnetworks.Model model, in android.hardware.neuralnetworks.ExecutionPreference preference, in android.hardware.neuralnetworks.Priority priority, in long deadlineNs, in ParcelFileDescriptor[] modelCache, in ParcelFileDescriptor[] dataCache, in byte[] token, in android.hardware.neuralnetworks.IPreparedModelCallback callback);
+  void prepareModelFromCache(in long deadlineNs, in ParcelFileDescriptor[] modelCache, in ParcelFileDescriptor[] dataCache, in byte[] token, in android.hardware.neuralnetworks.IPreparedModelCallback callback);
   const int BYTE_SIZE_OF_CACHE_TOKEN = 32;
   const int MAX_NUMBER_OF_CACHE_FILES = 32;
   const int EXTENSION_TYPE_HIGH_BITS_PREFIX = 15;
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IPreparedModel.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IPreparedModel.aidl
index 52882cd..fccb5dc 100644
--- a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IPreparedModel.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IPreparedModel.aidl
@@ -34,8 +34,8 @@
 package android.hardware.neuralnetworks;
 @VintfStability
 interface IPreparedModel {
-  android.hardware.neuralnetworks.ExecutionResult executeSynchronously(in android.hardware.neuralnetworks.Request request, in boolean measureTiming, in long deadline, in long loopTimeoutDuration);
-  android.hardware.neuralnetworks.FencedExecutionResult executeFenced(in android.hardware.neuralnetworks.Request request, in ParcelFileDescriptor[] waitFor, in boolean measureTiming, in long deadline, in long loopTimeoutDuration, in long duration);
+  android.hardware.neuralnetworks.ExecutionResult executeSynchronously(in android.hardware.neuralnetworks.Request request, in boolean measureTiming, in long deadlineNs, in long loopTimeoutDurationNs);
+  android.hardware.neuralnetworks.FencedExecutionResult executeFenced(in android.hardware.neuralnetworks.Request request, in ParcelFileDescriptor[] waitFor, in boolean measureTiming, in long deadlineNs, in long loopTimeoutDurationNs, in long durationNs);
   android.hardware.neuralnetworks.IBurst configureExecutionBurst();
   const long DEFAULT_LOOP_TIMEOUT_DURATION_NS = 2000000000;
   const long MAXIMUM_LOOP_TIMEOUT_DURATION_NS = 15000000000;
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/Timing.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/Timing.aidl
index 9690e01..bcc83cf 100644
--- a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/Timing.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/Timing.aidl
@@ -34,6 +34,6 @@
 package android.hardware.neuralnetworks;
 @VintfStability
 parcelable Timing {
-  long timeOnDevice;
-  long timeInDriver;
+  long timeOnDeviceNs;
+  long timeInDriverNs;
 }
diff --git a/neuralnetworks/aidl/android/hardware/neuralnetworks/IBurst.aidl b/neuralnetworks/aidl/android/hardware/neuralnetworks/IBurst.aidl
index 85d2a03..decdc48 100644
--- a/neuralnetworks/aidl/android/hardware/neuralnetworks/IBurst.aidl
+++ b/neuralnetworks/aidl/android/hardware/neuralnetworks/IBurst.aidl
@@ -77,18 +77,18 @@
      * @param measure Specifies whether or not to measure duration of the execution. The duration
      *                runs from the time the driver sees the call to the executeSynchronously
      *                function to the time the driver returns from the function.
-     * @param deadline The time by which the execution is expected to complete. The time is measured
-     *                 in nanoseconds since epoch of the steady clock (as from
-     *                 std::chrono::steady_clock). If the execution cannot be finished by the
-     *                 deadline, the execution may be aborted. Passing -1 means the deadline is
-     *                 omitted. Other negative values are invalid.
-     * @param loopTimeoutDuration The maximum amount of time in nanoseconds that should be spent
-     *                            executing a {@link OperationType::WHILE} operation. If a loop
-     *                            condition model does not output false within this duration, the
-     *                            execution must be aborted. If -1 is provided, the maximum amount
-     *                            of time is {@link DEFAULT_LOOP_TIMEOUT_DURATION_NS}. Other
-     *                            negative values are invalid. When provided, the duration must not
-     *                            exceed {@link MAXIMUM_LOOP_TIMEOUT_DURATION_NS}.
+     * @param deadlineNs The time by which the execution is expected to complete. The time is
+     *                   measured in nanoseconds since epoch of the steady clock (as from
+     *                   std::chrono::steady_clock). If the execution cannot be finished by the
+     *                   deadline, the execution may be aborted. Passing -1 means the deadline is
+     *                   omitted. Other negative values are invalid.
+     * @param loopTimeoutDurationNs The maximum amount of time in nanoseconds that should be spent
+     *                              executing a {@link OperationType::WHILE} operation. If a loop
+     *                              condition model does not output false within this duration, the
+     *                              execution must be aborted. If -1 is provided, the maximum amount
+     *                              of time is {@link DEFAULT_LOOP_TIMEOUT_DURATION_NS}. Other
+     *                              negative values are invalid. When provided, the duration must
+     *                              not exceed {@link MAXIMUM_LOOP_TIMEOUT_DURATION_NS}.
      * @return ExecutionResult parcelable, containing the status of the execution, output shapes and
      *     timing information.
      * @throws ServiceSpecificException with one of the following ErrorStatus values:
@@ -100,7 +100,7 @@
      *     - RESOURCE_EXHAUSTED_* if the task was aborted by the driver
      */
     ExecutionResult executeSynchronously(in Request request, in long[] memoryIdentifierTokens,
-            in boolean measureTiming, in long deadline, in long loopTimeoutDuration);
+            in boolean measureTiming, in long deadlineNs, in long loopTimeoutDurationNs);
 
     /**
      * releaseMemoryResource is used by the client to signal to the service that a memory buffer
diff --git a/neuralnetworks/aidl/android/hardware/neuralnetworks/IDevice.aidl b/neuralnetworks/aidl/android/hardware/neuralnetworks/IDevice.aidl
index c5b4ab1..72e2623 100644
--- a/neuralnetworks/aidl/android/hardware/neuralnetworks/IDevice.aidl
+++ b/neuralnetworks/aidl/android/hardware/neuralnetworks/IDevice.aidl
@@ -306,11 +306,11 @@
      * @param preference Indicates the intended execution behavior of a prepared model.
      * @param priority The priority of the prepared model relative to other prepared models owned by
      *                 the client.
-     * @param deadline The time by which the model is expected to be prepared. The time is measured
-     *                 in nanoseconds since boot (as from clock_gettime(CLOCK_BOOTTIME, &ts)
-     *                 or ::android::base::boot_clock). If the model cannot be prepared by the
-     *                 deadline, the preparation may be aborted. Passing -1 means the deadline is
-     *                 omitted. Other negative values are invalid.
+     * @param deadlineNs The time by which the model is expected to be prepared. The time is
+     *                   measured in nanoseconds since boot (as from clock_gettime(CLOCK_BOOTTIME,
+     *                   &ts) or ::android::base::boot_clock). If the model cannot be prepared by
+     *                   the deadline, the preparation may be aborted. Passing -1 means the deadline
+     *                   is omitted. Other negative values are invalid.
      * @param modelCache A vector of file descriptors for the security-sensitive cache. The length
      *                   of the vector must either be 0 indicating that caching information is not
      *                   provided, or match the numModelCache returned from
@@ -344,7 +344,7 @@
      *     - RESOURCE_EXHAUSTED_* if the task was aborted by the driver
      */
     void prepareModel(in Model model, in ExecutionPreference preference, in Priority priority,
-            in long deadline, in ParcelFileDescriptor[] modelCache,
+            in long deadlineNs, in ParcelFileDescriptor[] modelCache,
             in ParcelFileDescriptor[] dataCache, in byte[] token,
             in IPreparedModelCallback callback);
 
@@ -395,11 +395,11 @@
      * with a set of inputs to the model. Note that the same prepared model object may be used with
      * different shapes of inputs on different (possibly concurrent) executions.
      *
-     * @param deadline The time by which the model is expected to be prepared. The time is measured
-     *                 in nanoseconds since boot (as from clock_gettime(CLOCK_BOOTTIME, &ts) or
-     *                 ::android::base::boot_clock). If the model cannot be prepared by the
-     *                 deadline, the preparation may be aborted. Passing -1 means the deadline is
-     *                 omitted. Other negative values are invalid.
+     * @param deadlineNs The time by which the model is expected to be prepared. The time is
+     *                   measured in nanoseconds since boot (as from clock_gettime(CLOCK_BOOTTIME,
+     *                   &ts) or ::android::base::boot_clock). If the model cannot be prepared by
+     *                   the deadline, the preparation may be aborted. Passing -1 means the deadline
+     *                   is omitted. Other negative values are invalid.
      * @param modelCache A vector of file descriptors for the security-sensitive cache. The length
      *                   of the vector must match the numModelCache returned from
      *                   getNumberOfCacheFilesNeeded. The cache file descriptors will be provided in
@@ -426,7 +426,7 @@
      *       the deadline
      *     - RESOURCE_EXHAUSTED_* if the task was aborted by the driver
      */
-    void prepareModelFromCache(in long deadline, in ParcelFileDescriptor[] modelCache,
+    void prepareModelFromCache(in long deadlineNs, in ParcelFileDescriptor[] modelCache,
             in ParcelFileDescriptor[] dataCache, in byte[] token,
             in IPreparedModelCallback callback);
 }
diff --git a/neuralnetworks/aidl/android/hardware/neuralnetworks/IPreparedModel.aidl b/neuralnetworks/aidl/android/hardware/neuralnetworks/IPreparedModel.aidl
index bfab906..956b626 100644
--- a/neuralnetworks/aidl/android/hardware/neuralnetworks/IPreparedModel.aidl
+++ b/neuralnetworks/aidl/android/hardware/neuralnetworks/IPreparedModel.aidl
@@ -72,18 +72,18 @@
      * @param measure Specifies whether or not to measure duration of the execution. The duration
      *                runs from the time the driver sees the call to the executeSynchronously
      *                function to the time the driver returns from the function.
-     * @param deadline The time by which the execution is expected to complete. The time is measured
-     *                 in nanoseconds since boot (as from clock_gettime(CLOCK_BOOTTIME, &ts) or
-     *                 ::android::base::boot_clock). If the execution cannot be finished by the
-     *                 deadline, the execution may be aborted. Passing -1 means the deadline is
-     *                 omitted. Other negative values are invalid.
-     * @param loopTimeoutDuration The maximum amount of time in nanoseconds that should be spent
-     *                            executing a {@link OperationType::WHILE} operation. If a loop
-     *                            condition model does not output false within this duration, the
-     *                            execution must be aborted. If -1 is provided, the maximum amount
-     *                            of time is {@link DEFAULT_LOOP_TIMEOUT_DURATION_NS}. Other
-     *                            negative values are invalid. When provided, the duration must not
-     *                            exceed {@link MAXIMUM_LOOP_TIMEOUT_DURATION_NS}.
+     * @param deadlineNs The time by which the execution is expected to complete. The time is
+     *                   measured in nanoseconds since boot (as from clock_gettime(CLOCK_BOOTTIME,
+     *                   &ts) or ::android::base::boot_clock). If the execution cannot be finished
+     *                   by the deadline, the execution may be aborted. Passing -1 means the
+     *                   deadline is omitted. Other negative values are invalid.
+     * @param loopTimeoutDurationNs The maximum amount of time in nanoseconds that should be spent
+     *                              executing a {@link OperationType::WHILE} operation. If a loop
+     *                              condition model does not output false within this duration, the
+     *                              execution must be aborted. If -1 is provided, the maximum amount
+     *                              of time is {@link DEFAULT_LOOP_TIMEOUT_DURATION_NS}. Other
+     *                              negative values are invalid. When provided, the duration must
+     *                              not exceed {@link MAXIMUM_LOOP_TIMEOUT_DURATION_NS}.
      * @return ExecutionResult parcelable, containing the status of the execution, output shapes and
      *     timing information.
      * @throws ServiceSpecificException with one of the following ErrorStatus values:
@@ -95,7 +95,7 @@
      *     - RESOURCE_EXHAUSTED_* if the task was aborted by the driver
      */
     ExecutionResult executeSynchronously(in Request request, in boolean measureTiming,
-            in long deadline, in long loopTimeoutDuration);
+            in long deadlineNs, in long loopTimeoutDurationNs);
 
     /**
      * Launch a fenced asynchronous execution on a prepared model.
@@ -137,22 +137,23 @@
      * @param waitFor A vector of sync fence file descriptors. Execution must not start until all
      *                sync fences have been signaled.
      * @param measure Specifies whether or not to measure duration of the execution.
-     * @param deadline The time by which the execution is expected to complete. The time is measured
-     *                 in nanoseconds since boot (as from clock_gettime(CLOCK_BOOTTIME, &ts) or
-     *                 ::android::base::boot_clock). If the execution cannot be finished by the
-     *                 deadline, the execution may be aborted. Passing -1 means the deadline is
-     *                 omitted. Other negative values are invalid.
-     * @param loopTimeoutDuration The maximum amount of time in nanoseconds that should be spent
-     *                            executing a {@link OperationType::WHILE} operation. If a loop
-     *                            condition model does not output false within this duration, the
-     *                            execution must be aborted. If -1 is provided, the maximum amount
-     *                            of time is {@link DEFAULT_LOOP_TIMEOUT_DURATION_NS}. Other
-     *                            negative values are invalid. When provided, the duration must not
-     *                            exceed {@link MAXIMUM_LOOP_TIMEOUT_DURATION_NS}.
-     * @param duration The length of time in nanoseconds within which the execution is expected to
-     *                 complete after all sync fences in waitFor are signaled. If the execution
-     *                 cannot be finished within the duration, the execution may be aborted. Passing
-     *                 -1 means the duration is omitted. Other negative values are invalid.
+     * @param deadlineNs The time by which the execution is expected to complete. The time is
+     *                   measured in nanoseconds since boot (as from clock_gettime(CLOCK_BOOTTIME,
+     *                   &ts) or ::android::base::boot_clock). If the execution cannot be finished
+     *                   by the deadline, the execution may be aborted. Passing -1 means the
+     *                   deadline is omitted. Other negative values are invalid.
+     * @param loopTimeoutDurationNs The maximum amount of time in nanoseconds that should be spent
+     *                              executing a {@link OperationType::WHILE} operation. If a loop
+     *                              condition model does not output false within this duration, the
+     *                              execution must be aborted. If -1 is provided, the maximum amount
+     *                              of time is {@link DEFAULT_LOOP_TIMEOUT_DURATION_NS}. Other
+     *                              negative values are invalid. When provided, the duration must
+     *                              not exceed {@link MAXIMUM_LOOP_TIMEOUT_DURATION_NS}.
+     * @param durationNs The length of time in nanoseconds within which the execution is expected to
+     *                   complete after all sync fences in waitFor are signaled. If the execution
+     *                   cannot be finished within the duration, the execution may be aborted.
+     *                   Passing -1 means the duration is omitted. Other negative values are
+     *                   invalid.
      * @return The FencedExecutionResult parcelable, containing IFencedExecutionCallback and the
      *         sync fence.
      * @throws ServiceSpecificException with one of the following ErrorStatus values:
@@ -165,8 +166,8 @@
      *     - RESOURCE_EXHAUSTED_* if the task was aborted by the driver
      */
     FencedExecutionResult executeFenced(in Request request, in ParcelFileDescriptor[] waitFor,
-            in boolean measureTiming, in long deadline, in long loopTimeoutDuration,
-            in long duration);
+            in boolean measureTiming, in long deadlineNs, in long loopTimeoutDurationNs,
+            in long durationNs);
 
     /**
      * Configure a Burst object used to execute multiple inferences on a prepared model in rapid
diff --git a/neuralnetworks/aidl/android/hardware/neuralnetworks/Timing.aidl b/neuralnetworks/aidl/android/hardware/neuralnetworks/Timing.aidl
index 8130e08..5225096 100644
--- a/neuralnetworks/aidl/android/hardware/neuralnetworks/Timing.aidl
+++ b/neuralnetworks/aidl/android/hardware/neuralnetworks/Timing.aidl
@@ -28,9 +28,9 @@
     /**
      * Execution time on device (not driver, which runs on host processor).
      */
-    long timeOnDevice;
+    long timeOnDeviceNs;
     /**
      * Execution time in driver (including time on device).
      */
-    long timeInDriver;
+    long timeInDriverNs;
 }
diff --git a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Device.h b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Device.h
index eb194e3..1457646 100644
--- a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Device.h
+++ b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Device.h
@@ -54,7 +54,6 @@
     const std::string& getVersionString() const override;
     nn::Version getFeatureLevel() const override;
     nn::DeviceType getType() const override;
-    bool isUpdatable() const override;
     const std::vector<nn::Extension>& getSupportedExtensions() const override;
     const nn::Capabilities& getCapabilities() const override;
     std::pair<uint32_t, uint32_t> getNumberOfCacheFilesNeeded() const override;
diff --git a/neuralnetworks/aidl/utils/src/Conversions.cpp b/neuralnetworks/aidl/utils/src/Conversions.cpp
index 93ac51c..4b263ee 100644
--- a/neuralnetworks/aidl/utils/src/Conversions.cpp
+++ b/neuralnetworks/aidl/utils/src/Conversions.cpp
@@ -410,11 +410,11 @@
 }
 
 GeneralResult<Timing> unvalidatedConvert(const aidl_hal::Timing& timing) {
-    if (timing.timeInDriver < -1) {
-        return NN_ERROR() << "Timing: timeInDriver must not be less than -1";
+    if (timing.timeInDriverNs < -1) {
+        return NN_ERROR() << "Timing: timeInDriverNs must not be less than -1";
     }
-    if (timing.timeOnDevice < -1) {
-        return NN_ERROR() << "Timing: timeOnDevice must not be less than -1";
+    if (timing.timeOnDeviceNs < -1) {
+        return NN_ERROR() << "Timing: timeOnDeviceNs must not be less than -1";
     }
     constexpr auto convertTiming = [](int64_t halTiming) -> OptionalDuration {
         if (halTiming == kNoTiming) {
@@ -422,8 +422,8 @@
         }
         return nn::Duration(static_cast<uint64_t>(halTiming));
     };
-    return Timing{.timeOnDevice = convertTiming(timing.timeOnDevice),
-                  .timeInDriver = convertTiming(timing.timeInDriver)};
+    return Timing{.timeOnDevice = convertTiming(timing.timeOnDeviceNs),
+                  .timeInDriver = convertTiming(timing.timeInDriverNs)};
 }
 
 GeneralResult<Model::OperandValues> unvalidatedConvert(const std::vector<uint8_t>& operandValues) {
@@ -964,8 +964,8 @@
 
 nn::GeneralResult<Timing> unvalidatedConvert(const nn::Timing& timing) {
     return Timing{
-            .timeOnDevice = NN_TRY(unvalidatedConvert(timing.timeOnDevice)),
-            .timeInDriver = NN_TRY(unvalidatedConvert(timing.timeInDriver)),
+            .timeOnDeviceNs = NN_TRY(unvalidatedConvert(timing.timeOnDevice)),
+            .timeInDriverNs = NN_TRY(unvalidatedConvert(timing.timeInDriver)),
     };
 }
 
diff --git a/neuralnetworks/aidl/utils/src/Device.cpp b/neuralnetworks/aidl/utils/src/Device.cpp
index 02ca861..0fd453b 100644
--- a/neuralnetworks/aidl/utils/src/Device.cpp
+++ b/neuralnetworks/aidl/utils/src/Device.cpp
@@ -178,10 +178,6 @@
     return kDeviceType;
 }
 
-bool Device::isUpdatable() const {
-    return false;
-}
-
 const std::vector<nn::Extension>& Device::getSupportedExtensions() const {
     return kExtensions;
 }
diff --git a/neuralnetworks/aidl/utils/test/PreparedModelTest.cpp b/neuralnetworks/aidl/utils/test/PreparedModelTest.cpp
index 630a460..ff98a7d 100644
--- a/neuralnetworks/aidl/utils/test/PreparedModelTest.cpp
+++ b/neuralnetworks/aidl/utils/test/PreparedModelTest.cpp
@@ -39,7 +39,7 @@
 using ::testing::SetArgPointee;
 
 const std::shared_ptr<IPreparedModel> kInvalidPreparedModel;
-constexpr auto kNoTiming = Timing{.timeOnDevice = -1, .timeInDriver = -1};
+constexpr auto kNoTiming = Timing{.timeOnDeviceNs = -1, .timeInDriverNs = -1};
 
 constexpr auto makeStatusOk = [] { return ndk::ScopedAStatus::ok(); };
 
diff --git a/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp b/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp
index 1440429..d3b041d 100644
--- a/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp
+++ b/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp
@@ -547,7 +547,7 @@
         makeOutputInsufficientSize(kInsufficientOutputIndex, &request);
     }
 
-    int64_t loopTimeoutDuration = kOmittedTimeoutDuration;
+    int64_t loopTimeoutDurationNs = kOmittedTimeoutDuration;
     // OutputType::MISSED_DEADLINE is only used by
     // TestKind::INTINITE_LOOP_TIMEOUT tests to verify that an infinite loop is
     // aborted after a timeout.
@@ -555,7 +555,7 @@
         // Override the default loop timeout duration with a small value to
         // speed up test execution.
         constexpr int64_t kMillisecond = 1'000'000;
-        loopTimeoutDuration = 1 * kMillisecond;
+        loopTimeoutDurationNs = 1 * kMillisecond;
     }
 
     ErrorStatus executionStatus;
@@ -568,7 +568,7 @@
             ExecutionResult executionResult;
             // execute
             const auto ret = preparedModel->executeSynchronously(request, testConfig.measureTiming,
-                                                                 kNoDeadline, loopTimeoutDuration,
+                                                                 kNoDeadline, loopTimeoutDurationNs,
                                                                  &executionResult);
             ASSERT_TRUE(ret.isOk() || ret.getExceptionCode() == EX_SERVICE_SPECIFIC)
                     << ret.getDescription();
@@ -608,7 +608,7 @@
             ExecutionResult executionResult;
             // execute
             ret = burst->executeSynchronously(request, slots, testConfig.measureTiming, kNoDeadline,
-                                              loopTimeoutDuration, &executionResult);
+                                              loopTimeoutDurationNs, &executionResult);
             ASSERT_TRUE(ret.isOk() || ret.getExceptionCode() == EX_SERVICE_SPECIFIC)
                     << ret.getDescription();
             if (ret.isOk()) {
@@ -635,7 +635,7 @@
             ErrorStatus result = ErrorStatus::NONE;
             FencedExecutionResult executionResult;
             auto ret = preparedModel->executeFenced(request, {}, testConfig.measureTiming,
-                                                    kNoDeadline, loopTimeoutDuration, kNoDuration,
+                                                    kNoDeadline, loopTimeoutDurationNs, kNoDuration,
                                                     &executionResult);
             ASSERT_TRUE(ret.isOk() || ret.getExceptionCode() == EX_SERVICE_SPECIFIC)
                     << ret.getDescription();
@@ -649,7 +649,7 @@
                 waitFor.emplace_back(dupFd);
                 // If a sync fence is returned, try start another run waiting for the sync fence.
                 ret = preparedModel->executeFenced(request, waitFor, testConfig.measureTiming,
-                                                   kNoDeadline, loopTimeoutDuration, kNoDuration,
+                                                   kNoDeadline, loopTimeoutDurationNs, kNoDuration,
                                                    &executionResult);
                 ASSERT_TRUE(ret.isOk());
                 waitForSyncFence(executionResult.syncFence.get());
@@ -686,8 +686,8 @@
     if (!testConfig.measureTiming) {
         EXPECT_EQ(timing, kNoTiming);
     } else {
-        if (timing.timeOnDevice != -1 && timing.timeInDriver != -1) {
-            EXPECT_LE(timing.timeOnDevice, timing.timeInDriver);
+        if (timing.timeOnDeviceNs != -1 && timing.timeInDriverNs != -1) {
+            EXPECT_LE(timing.timeOnDeviceNs, timing.timeInDriverNs);
         }
     }
 
diff --git a/neuralnetworks/aidl/vts/functional/QualityOfServiceTests.cpp b/neuralnetworks/aidl/vts/functional/QualityOfServiceTests.cpp
index e803e38..bbba887 100644
--- a/neuralnetworks/aidl/vts/functional/QualityOfServiceTests.cpp
+++ b/neuralnetworks/aidl/vts/functional/QualityOfServiceTests.cpp
@@ -53,7 +53,7 @@
 
 using ExecutionFunction =
         std::function<MaybeResults(const std::shared_ptr<IPreparedModel>& preparedModel,
-                                   const Request& request, int64_t deadline)>;
+                                   const Request& request, int64_t deadlineNs)>;
 
 static int64_t makeDeadline(DeadlineBoundType deadlineBoundType) {
     const auto getNanosecondsSinceEpoch = [](const auto& time) -> int64_t {
@@ -79,9 +79,9 @@
 
 void runPrepareModelTest(const std::shared_ptr<IDevice>& device, const Model& model,
                          Priority priority, std::optional<DeadlineBoundType> deadlineBound) {
-    int64_t deadline = kNoDeadline;
+    int64_t deadlineNs = kNoDeadline;
     if (deadlineBound.has_value()) {
-        deadline = makeDeadline(deadlineBound.value());
+        deadlineNs = makeDeadline(deadlineBound.value());
     }
 
     // see if service can handle model
@@ -96,8 +96,8 @@
     const std::shared_ptr<PreparedModelCallback> preparedModelCallback =
             ndk::SharedRefBase::make<PreparedModelCallback>();
     const auto prepareLaunchStatus =
-            device->prepareModel(model, ExecutionPreference::FAST_SINGLE_ANSWER, priority, deadline,
-                                 {}, {}, kEmptyCacheToken, preparedModelCallback);
+            device->prepareModel(model, ExecutionPreference::FAST_SINGLE_ANSWER, priority,
+                                 deadlineNs, {}, {}, kEmptyCacheToken, preparedModelCallback);
     ASSERT_TRUE(prepareLaunchStatus.isOk())
             << "prepareLaunchStatus: " << prepareLaunchStatus.getDescription();
 
@@ -156,13 +156,13 @@
 }
 
 static MaybeResults executeSynchronously(const std::shared_ptr<IPreparedModel>& preparedModel,
-                                         const Request& request, int64_t deadline) {
+                                         const Request& request, int64_t deadlineNs) {
     SCOPED_TRACE("synchronous");
     const bool measure = false;
 
     // run execution
     ExecutionResult executionResult;
-    const auto ret = preparedModel->executeSynchronously(request, measure, deadline,
+    const auto ret = preparedModel->executeSynchronously(request, measure, deadlineNs,
                                                          kOmittedTimeoutDuration, &executionResult);
     EXPECT_TRUE(ret.isOk() || ret.getExceptionCode() == EX_SERVICE_SPECIFIC)
             << ret.getDescription();
@@ -182,7 +182,7 @@
 }
 
 static MaybeResults executeBurst(const std::shared_ptr<IPreparedModel>& preparedModel,
-                                 const Request& request, int64_t deadline) {
+                                 const Request& request, int64_t deadlineNs) {
     SCOPED_TRACE("burst");
     const bool measure = false;
 
@@ -200,7 +200,7 @@
 
     // run execution
     ExecutionResult executionResult;
-    ret = burst->executeSynchronously(request, slots, measure, deadline, kOmittedTimeoutDuration,
+    ret = burst->executeSynchronously(request, slots, measure, deadlineNs, kOmittedTimeoutDuration,
                                       &executionResult);
     EXPECT_TRUE(ret.isOk() || ret.getExceptionCode() == EX_SERVICE_SPECIFIC)
             << ret.getDescription();
@@ -224,10 +224,10 @@
                       const ExecutionContext& context, bool synchronous,
                       DeadlineBoundType deadlineBound) {
     const ExecutionFunction execute = synchronous ? executeSynchronously : executeBurst;
-    const auto deadline = makeDeadline(deadlineBound);
+    const auto deadlineNs = makeDeadline(deadlineBound);
 
     // Perform execution and unpack results.
-    const auto results = execute(preparedModel, request, deadline);
+    const auto results = execute(preparedModel, request, deadlineNs);
     if (!results.has_value()) return;
     const auto& [status, outputShapes, timing] = results.value();
 
diff --git a/neuralnetworks/aidl/vts/functional/Utils.h b/neuralnetworks/aidl/vts/functional/Utils.h
index 266301c..77085a7 100644
--- a/neuralnetworks/aidl/vts/functional/Utils.h
+++ b/neuralnetworks/aidl/vts/functional/Utils.h
@@ -43,7 +43,7 @@
 
 inline constexpr Priority kDefaultPriority = Priority::MEDIUM;
 
-inline constexpr Timing kNoTiming = {.timeOnDevice = -1, .timeInDriver = -1};
+inline constexpr Timing kNoTiming = {.timeOnDeviceNs = -1, .timeInDriverNs = -1};
 inline constexpr int64_t kNoDeadline = -1;
 inline constexpr int64_t kOmittedTimeoutDuration = -1;
 inline constexpr int64_t kNoDuration = -1;
diff --git a/neuralnetworks/utils/common/include/nnapi/hal/InvalidDevice.h b/neuralnetworks/utils/common/include/nnapi/hal/InvalidDevice.h
index d843526..5e62b9a 100644
--- a/neuralnetworks/utils/common/include/nnapi/hal/InvalidDevice.h
+++ b/neuralnetworks/utils/common/include/nnapi/hal/InvalidDevice.h
@@ -32,7 +32,7 @@
 class InvalidDevice final : public nn::IDevice {
   public:
     InvalidDevice(std::string name, std::string versionString, nn::Version featureLevel,
-                  nn::DeviceType type, bool isUpdatable, std::vector<nn::Extension> extensions,
+                  nn::DeviceType type, std::vector<nn::Extension> extensions,
                   nn::Capabilities capabilities,
                   std::pair<uint32_t, uint32_t> numberOfCacheFilesNeeded);
 
@@ -40,7 +40,6 @@
     const std::string& getVersionString() const override;
     nn::Version getFeatureLevel() const override;
     nn::DeviceType getType() const override;
-    bool isUpdatable() const override;
     const std::vector<nn::Extension>& getSupportedExtensions() const override;
     const nn::Capabilities& getCapabilities() const override;
     std::pair<uint32_t, uint32_t> getNumberOfCacheFilesNeeded() const override;
@@ -71,7 +70,6 @@
     const std::string kVersionString;
     const nn::Version kFeatureLevel;
     const nn::DeviceType kType;
-    const bool kIsUpdatable;
     const std::vector<nn::Extension> kExtensions;
     const nn::Capabilities kCapabilities;
     const std::pair<uint32_t, uint32_t> kNumberOfCacheFilesNeeded;
diff --git a/neuralnetworks/utils/common/include/nnapi/hal/ResilientDevice.h b/neuralnetworks/utils/common/include/nnapi/hal/ResilientDevice.h
index 8199c52..84ae799 100644
--- a/neuralnetworks/utils/common/include/nnapi/hal/ResilientDevice.h
+++ b/neuralnetworks/utils/common/include/nnapi/hal/ResilientDevice.h
@@ -53,7 +53,6 @@
     const std::string& getVersionString() const override;
     nn::Version getFeatureLevel() const override;
     nn::DeviceType getType() const override;
-    bool isUpdatable() const override;
     const std::vector<nn::Extension>& getSupportedExtensions() const override;
     const nn::Capabilities& getCapabilities() const override;
     std::pair<uint32_t, uint32_t> getNumberOfCacheFilesNeeded() const override;
diff --git a/neuralnetworks/utils/common/src/InvalidDevice.cpp b/neuralnetworks/utils/common/src/InvalidDevice.cpp
index 81bca7f..535ccb4 100644
--- a/neuralnetworks/utils/common/src/InvalidDevice.cpp
+++ b/neuralnetworks/utils/common/src/InvalidDevice.cpp
@@ -32,14 +32,13 @@
 namespace android::hardware::neuralnetworks::utils {
 
 InvalidDevice::InvalidDevice(std::string name, std::string versionString, nn::Version featureLevel,
-                             nn::DeviceType type, bool isUpdatable,
-                             std::vector<nn::Extension> extensions, nn::Capabilities capabilities,
+                             nn::DeviceType type, std::vector<nn::Extension> extensions,
+                             nn::Capabilities capabilities,
                              std::pair<uint32_t, uint32_t> numberOfCacheFilesNeeded)
     : kName(std::move(name)),
       kVersionString(std::move(versionString)),
       kFeatureLevel(featureLevel),
       kType(type),
-      kIsUpdatable(isUpdatable),
       kExtensions(std::move(extensions)),
       kCapabilities(std::move(capabilities)),
       kNumberOfCacheFilesNeeded(numberOfCacheFilesNeeded) {}
@@ -60,10 +59,6 @@
     return kType;
 }
 
-bool InvalidDevice::isUpdatable() const {
-    return kIsUpdatable;
-}
-
 const std::vector<nn::Extension>& InvalidDevice::getSupportedExtensions() const {
     return kExtensions;
 }
diff --git a/neuralnetworks/utils/common/src/ResilientDevice.cpp b/neuralnetworks/utils/common/src/ResilientDevice.cpp
index 13965af..2023c9a 100644
--- a/neuralnetworks/utils/common/src/ResilientDevice.cpp
+++ b/neuralnetworks/utils/common/src/ResilientDevice.cpp
@@ -122,14 +122,12 @@
     };
     if (compare(&IDevice::getName) || compare(&IDevice::getVersionString) ||
         compare(&IDevice::getFeatureLevel) || compare(&IDevice::getType) ||
-        compare(&IDevice::isUpdatable) || compare(&IDevice::getSupportedExtensions) ||
-        compare(&IDevice::getCapabilities)) {
+        compare(&IDevice::getSupportedExtensions) || compare(&IDevice::getCapabilities)) {
         LOG(ERROR) << "Recovered device has different metadata than what is cached. Marking "
                       "IDevice object as invalid.";
         device = std::make_shared<const InvalidDevice>(
-                kName, kVersionString, mDevice->getFeatureLevel(), mDevice->getType(),
-                mDevice->isUpdatable(), kExtensions, kCapabilities,
-                mDevice->getNumberOfCacheFilesNeeded());
+                kName, kVersionString, mDevice->getFeatureLevel(), mDevice->getType(), kExtensions,
+                kCapabilities, mDevice->getNumberOfCacheFilesNeeded());
         mIsValid = false;
     }
 
@@ -153,10 +151,6 @@
     return getDevice()->getType();
 }
 
-bool ResilientDevice::isUpdatable() const {
-    return getDevice()->isUpdatable();
-}
-
 const std::vector<nn::Extension>& ResilientDevice::getSupportedExtensions() const {
     return kExtensions;
 }
diff --git a/neuralnetworks/utils/common/test/MockDevice.h b/neuralnetworks/utils/common/test/MockDevice.h
index b274716..a9428bc 100644
--- a/neuralnetworks/utils/common/test/MockDevice.h
+++ b/neuralnetworks/utils/common/test/MockDevice.h
@@ -29,7 +29,6 @@
     MOCK_METHOD(const std::string&, getVersionString, (), (const, override));
     MOCK_METHOD(Version, getFeatureLevel, (), (const, override));
     MOCK_METHOD(DeviceType, getType, (), (const, override));
-    MOCK_METHOD(bool, isUpdatable, (), (const, override));
     MOCK_METHOD(const std::vector<Extension>&, getSupportedExtensions, (), (const, override));
     MOCK_METHOD(const Capabilities&, getCapabilities, (), (const, override));
     MOCK_METHOD((std::pair<uint32_t, uint32_t>), getNumberOfCacheFilesNeeded, (),
diff --git a/neuralnetworks/utils/service/include/nnapi/hal/Service.h b/neuralnetworks/utils/service/include/nnapi/hal/Service.h
index e339627..2fd5237 100644
--- a/neuralnetworks/utils/service/include/nnapi/hal/Service.h
+++ b/neuralnetworks/utils/service/include/nnapi/hal/Service.h
@@ -22,10 +22,15 @@
 #include <memory>
 #include <vector>
 
-namespace android::nn::hal {
+namespace android::hardware::neuralnetworks::service {
 
-std::vector<nn::SharedDevice> getDevices();
+struct SharedDeviceAndUpdatability {
+    nn::SharedDevice device;
+    bool isDeviceUpdatable = false;
+};
 
-}  // namespace android::nn::hal
+std::vector<SharedDeviceAndUpdatability> getDevices(bool includeUpdatableDrivers);
+
+}  // namespace android::hardware::neuralnetworks::service
 
 #endif  // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_SERVICE_H
diff --git a/neuralnetworks/utils/service/src/Service.cpp b/neuralnetworks/utils/service/src/Service.cpp
index 75ab1f9..2286288 100644
--- a/neuralnetworks/utils/service/src/Service.cpp
+++ b/neuralnetworks/utils/service/src/Service.cpp
@@ -35,6 +35,7 @@
 #include <nnapi/hal/1.2/Service.h>
 #include <nnapi/hal/1.3/Service.h>
 #include <nnapi/hal/aidl/Service.h>
+#include <nnapi/hal/aidl/Utils.h>
 
 #include <functional>
 #include <memory>
@@ -50,7 +51,7 @@
 using getDeviceFn = std::add_pointer_t<nn::GeneralResult<nn::SharedDevice>(const std::string&)>;
 
 void getHidlDevicesForVersion(const std::string& descriptor, getDeviceFn getDevice,
-                              std::vector<nn::SharedDevice>* devices,
+                              std::vector<SharedDeviceAndUpdatability>* devices,
                               std::unordered_set<std::string>* registeredDevices) {
     CHECK(devices != nullptr);
     CHECK(registeredDevices != nullptr);
@@ -62,7 +63,7 @@
             if (maybeDevice.has_value()) {
                 auto device = std::move(maybeDevice).value();
                 CHECK(device != nullptr);
-                devices->push_back(std::move(device));
+                devices->push_back({.device = std::move(device)});
             } else {
                 LOG(ERROR) << "getDevice(" << name << ") failed with " << maybeDevice.error().code
                            << ": " << maybeDevice.error().message;
@@ -71,8 +72,9 @@
     }
 }
 
-void getAidlDevices(std::vector<nn::SharedDevice>* devices,
-                    std::unordered_set<std::string>* registeredDevices) {
+void getAidlDevices(std::vector<SharedDeviceAndUpdatability>* devices,
+                    std::unordered_set<std::string>* registeredDevices,
+                    bool includeUpdatableDrivers) {
     CHECK(devices != nullptr);
     CHECK(registeredDevices != nullptr);
 
@@ -89,12 +91,21 @@
     }
 
     for (const auto& name : names) {
+        bool isDeviceUpdatable = false;
+        if (__builtin_available(android __NNAPI_AIDL_MIN_ANDROID_API__, *)) {
+            const auto instance = std::string(aidl_hal::IDevice::descriptor) + '/' + name;
+            isDeviceUpdatable = AServiceManager_isUpdatableViaApex(instance.c_str());
+        }
+        if (isDeviceUpdatable && !includeUpdatableDrivers) {
+            continue;
+        }
         if (const auto [it, unregistered] = registeredDevices->insert(name); unregistered) {
             auto maybeDevice = aidl_hal::utils::getDevice(name);
             if (maybeDevice.has_value()) {
                 auto device = std::move(maybeDevice).value();
                 CHECK(device != nullptr);
-                devices->push_back(std::move(device));
+                devices->push_back(
+                        {.device = std::move(device), .isDeviceUpdatable = isDeviceUpdatable});
             } else {
                 LOG(ERROR) << "getDevice(" << name << ") failed with " << maybeDevice.error().code
                            << ": " << maybeDevice.error().message;
@@ -103,11 +114,13 @@
     }
 }
 
-std::vector<nn::SharedDevice> getDevices() {
-    std::vector<nn::SharedDevice> devices;
+}  // namespace
+
+std::vector<SharedDeviceAndUpdatability> getDevices(bool includeUpdatableDrivers) {
+    std::vector<SharedDeviceAndUpdatability> devices;
     std::unordered_set<std::string> registeredDevices;
 
-    getAidlDevices(&devices, &registeredDevices);
+    getAidlDevices(&devices, &registeredDevices, includeUpdatableDrivers);
 
     getHidlDevicesForVersion(V1_3::IDevice::descriptor, &V1_3::utils::getDevice, &devices,
                              &registeredDevices);
@@ -121,13 +134,4 @@
     return devices;
 }
 
-}  // namespace
 }  // namespace android::hardware::neuralnetworks::service
-
-namespace android::nn::hal {
-
-std::vector<nn::SharedDevice> getDevices() {
-    return hardware::neuralnetworks::service::getDevices();
-}
-
-}  // namespace android::nn::hal
diff --git a/radio/1.6/IRadio.hal b/radio/1.6/IRadio.hal
index a4e8811..e2d35d0 100644
--- a/radio/1.6/IRadio.hal
+++ b/radio/1.6/IRadio.hal
@@ -145,7 +145,6 @@
      *
      * Response function is IRadioResponse.setupDataCallResponse_1_6()
      *
-     * Note this API is the same as the 1.5
      */
     oneway setupDataCall_1_6(int32_t serial, AccessNetwork accessNetwork,
             DataProfileInfo dataProfileInfo, bool roamingAllowed,
@@ -177,7 +176,7 @@
      * @param serial Serial number of request.
      * @param message GsmSmsMessage as defined in types.hal
      *
-     * Response function is IRadioResponse.sendSMSExpectMoreResponse_1_6()
+     * Response function is IRadioResponse.sendSmsExpectMoreResponse_1_6()
      *
      * Note this API is the same as the 1.0
      *
@@ -185,7 +184,7 @@
      * fails. RadioError:SMS_SEND_FAIL_RETRY means retry (i.e. error cause is 332)
      * and RadioError:GENERIC_FAILURE means no retry (i.e. error cause is 500)
      */
-    oneway sendSMSExpectMore_1_6(int32_t serial, GsmSmsMessage message);
+    oneway sendSmsExpectMore_1_6(int32_t serial, GsmSmsMessage message);
 
     /**
      * Send a CDMA SMS message
@@ -267,7 +266,7 @@
      * 2. Disable NR dual connectivity {NrDualConnectivityState:DISABLE}
      * 3. Disable NR dual connectivity and force secondary cell to be released
      * {NrDualConnectivityState:DISABLE_IMMEDIATE}
-
+     *
      * Response callback is IRadioResponse.setNRDualConnectivityStateResponse()
      */
     oneway setNrDualConnectivityState(int32_t serial,
@@ -372,7 +371,7 @@
      *
      * Response callback is IRadioResponse.getAllowedNetworkTypesBitmapResponse()
      */
-    oneway getAllowedNetworkTypesBitmap(uint32_t serial);
+    oneway getAllowedNetworkTypesBitmap(int32_t serial);
 
     /**
      * Control data throttling at modem.
diff --git a/radio/1.6/IRadioIndication.hal b/radio/1.6/IRadioIndication.hal
index 9788345..05a7585 100644
--- a/radio/1.6/IRadioIndication.hal
+++ b/radio/1.6/IRadioIndication.hal
@@ -107,7 +107,7 @@
     /**
      * Indicates physical channel configurations.
      *
-     * An empty configs list indicates that the radio is in idle mode.
+     * An empty configs list shall be returned when the radio is in idle mode (i.e. RRC idle).
      *
      * @param type Type of radio indication
      * @param configs Vector of PhysicalChannelConfigs
diff --git a/radio/1.6/IRadioResponse.hal b/radio/1.6/IRadioResponse.hal
index 33fe94f..3ee46c2 100644
--- a/radio/1.6/IRadioResponse.hal
+++ b/radio/1.6/IRadioResponse.hal
@@ -139,7 +139,7 @@
      *   RadioError:ACCESS_BARRED
      *   RadioError:BLOCKED_DUE_TO_CALL
      */
-    oneway sendSMSExpectMoreResponse_1_6(RadioResponseInfo info, SendSmsResult sms);
+    oneway sendSmsExpectMoreResponse_1_6(RadioResponseInfo info, SendSmsResult sms);
 
     /**
      * @param info Response info struct containing response type, serial no. and error
@@ -232,6 +232,7 @@
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:INTERNAL_ERR
      *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:INVALID_STATE
      */
     oneway setNrDualConnectivityStateResponse(RadioResponseInfo info);
 
diff --git a/radio/1.6/types.hal b/radio/1.6/types.hal
index 3fd31cc..1b697a9 100644
--- a/radio/1.6/types.hal
+++ b/radio/1.6/types.hal
@@ -55,9 +55,9 @@
 
 struct QosBandwidth {
     /** Maximum bit rate possible on the bearer */
-    int32_t maxBitrateKbps;
+    uint32_t maxBitrateKbps;
     /** Minimum bit rate that is guaranteed to be provided by the network */
-    int32_t guaranteedBitrateKbps;
+    uint32_t guaranteedBitrateKbps;
 };
 
 /** LTE/EPS Quality of Service parameters as per 3gpp spec 24.301 sec 9.9.4.3. */
@@ -106,7 +106,7 @@
 /**
  * Next header protocol numbers defined by IANA, RFC 5237
  */
-enum QosProtocol : int32_t {
+enum QosProtocol : int8_t {
     /** No protocol specified */
     UNSPECIFIED = -1,
     /** Transmission Control Protocol */
@@ -119,14 +119,14 @@
     AH = 51,
 };
 
-enum QosFilterDirection : int32_t {
+enum QosFilterDirection : int8_t {
     DOWNLINK = 0,
     UPLINK = 1,
     BIDIRECTIONAL = 2,
 };
 
 /** Allowed port numbers */
-enum QosPortRange : int32_t {
+enum QosPortRange : uint16_t {
     MIN = 20,
     MAX = 65535
 };
@@ -248,7 +248,7 @@
 };
 
 /** The allowed failure modes on an IWLAN handover failure. */
-enum HandoverFailureMode : int32_t {
+enum HandoverFailureMode : int8_t {
     /**
      * On data handover failure, fallback to the source data transport when the
      * fail cause is due to a hand off preference change.
@@ -379,7 +379,7 @@
 /**
  * NR Dual connectivity state
  */
-enum NrDualConnectivityState: int32_t {
+enum NrDualConnectivityState: int8_t {
     /**
      * Enable NR dual connectivity. Enabled state does not mean dual connectivity
      * is active. It means device is allowed to connect to both primary and secondary.
@@ -408,7 +408,7 @@
     * the estimated maximum sustainable link bandwidth (as would be measured
     * at the Upper PDCP or SNDCP SAP). If the DL Aggregate Maximum Bit Rate is known,
     * this value shall not exceed the DL-AMBR for the Internet PDN connection.
-    * This must be filled with -1 if network is not connected.
+    * This must be filled with 0 if network is not connected.
     */
    uint32_t downlinkCapacityKbps;
 
@@ -418,7 +418,7 @@
     * estimated maximum sustainable link bandwidth (as would be measured at the
     * Upper PDCP or SNDCP SAP). If the UL Aggregate Maximum Bit Rate is known,
     * this value shall not exceed the UL-AMBR for the Internet PDN connection.
-    * This must be filled with -1 if network is not connected.
+    * This must be filled with 0 if network is not connected.
     */
    uint32_t uplinkCapacityKbps;
 
@@ -427,7 +427,7 @@
     * This bandwidth estimate shall be the estimated maximum sustainable link bandwidth
     * (as would be measured at the Upper PDCP or SNDCP SAP). This is valid only
     * in if device is connected to both primary and secodary in dual connected
-    * mode. This must be filled with -1 if secondary is not connected or if
+    * mode. This must be filled with 0 if secondary is not connected or if
     * modem does not support this feature.
     */
    uint32_t secondaryDownlinkCapacityKbps;
@@ -437,13 +437,13 @@
     * This bandwidth estimate shall be the estimated
     * maximum sustainable link bandwidth (as would be measured at the Upper PDCP or SNDCP SAP).
     * This is valid only in if device is connected to both primary and secodary in dual connected
-    * mode.This must be filled with -1 if secondary is not connected or if modem
+    * mode.This must be filled with 0 if secondary is not connected or if modem
     * does not support this feature.
     */
    uint32_t secondaryUplinkCapacityKbps;
 };
 
-enum DataThrottlingAction : int32_t {
+enum DataThrottlingAction : int8_t {
     /* Clear all existing data throttling. */
     NO_DATA_THROTTLING = 0,
 
@@ -581,9 +581,9 @@
      *
      * Reference: 3GPP TS 138.214 section 5.2.2.1.
      *
-     * Range [0, 15], INT_MAX means invalid/unreported.
+     * Range [0, 15], 0xFF means invalid/unreported.
      */
-    vec<uint32_t> csiCqiReport;
+    vec<uint8_t> csiCqiReport;
 };
 
 /**
@@ -740,22 +740,19 @@
 
         EutranRegistrationInfo eutranInfo;
 
-        struct NgranRegistrationInfo {
-            /**
-             * Network capabilities for voice over PS services. This info is valid only on NR
-             * network and must be present when the device is camped on NR. VopsInfo must be
-             * empty when the device is not camped on NR.
-             */
-            NrVopsInfo nrVopsInfo;
-        } ngranInfo;
+        /**
+         * Network capabilities for voice over PS services. This info is valid only on NR
+         * network and must be present when the device is camped on NR. VopsInfo must be
+         * empty when the device is not camped on NR.
+         */
+        NrVopsInfo ngranNrVopsInfo;
 
-        struct GeranRegistrationInfo {
-            /**
-             * True if the dual transfer mode is supported.
-             * Refer to 3GPP TS 44.108 section 3.4.25.3
-             */
-            bool dtmSupported;
-        } geranInfo;
+        /**
+         * True if the dual transfer mode is supported.
+         * Refer to 3GPP TS 44.108 section 3.4.25.3
+         */
+        bool geranDtmSupported;
+
     } accessTechnologySpecificInfo;
 };
 
@@ -874,10 +871,10 @@
     int32_t uplinkChannelNumber;
 
     /** Downlink cell bandwidth, in kHz */
-    int32_t cellBandwidthDownlink;
+    int32_t cellBandwidthDownlinkKhz;
 
     /** Uplink cell bandwidth, in kHz */
-    int32_t cellBandwidthUplink;
+    int32_t cellBandwidthUplinkKhz;
 
     /**
      * A list of data calls mapped to this physical channel. The context id must match the cid of
@@ -1059,7 +1056,7 @@
     SscMode value;
 };
 
-enum SliceStatus : int32_t {
+enum SliceStatus : int8_t {
     UNKNOWN,
     CONFIGURED, // Configured but not allowed or rejected yet
     ALLOWED,    // Allowed to be used
@@ -1072,7 +1069,7 @@
  * Enum representing session and service continuity mode as defined in
  * 3GPP TS 23.501.
  */
-enum SscMode : int32_t {
+enum SscMode : int8_t {
     MODE_1 = 1,
     MODE_2 = 2,
     MODE_3 = 3,
@@ -1081,7 +1078,7 @@
 /**
  * Public key type from carrier certificate.
  */
-enum PublicKeyType : int32_t {
+enum PublicKeyType : int8_t {
     EPDG    = 1,                   // Key type to be used for ePDG
     WLAN    = 2,                   // Key type to be used for WLAN
 };
@@ -1190,7 +1187,7 @@
  *   chunk of phonebook data, means this is a last indication with the left
  *   data.
  */
-enum PbReceivedStatus : int32_t {
+enum PbReceivedStatus : int8_t {
     PB_RECEIVED_OK = 1,
     PB_RECEIVED_ERROR = 2,
     PB_RECEIVED_ABORT = 3,
diff --git a/radio/1.6/vts/functional/Android.bp b/radio/1.6/vts/functional/Android.bp
index 65b0dd0..2bc6af3 100644
--- a/radio/1.6/vts/functional/Android.bp
+++ b/radio/1.6/vts/functional/Android.bp
@@ -28,6 +28,7 @@
     defaults: ["VtsHalTargetTestDefaults"],
     srcs: [
         "radio_hidl_hal_api.cpp",
+        "radio_hidl_hal_misc.cpp",
         "radio_hidl_hal_test.cpp",
         "radio_response.cpp",
         "radio_indication.cpp",
diff --git a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
index f092e3d..f09b74e 100644
--- a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
@@ -218,10 +218,10 @@
 }
 
 /*
- * Test IRadio_1_6.sendSMSExpectMore() for the response returned.
+ * Test IRadio_1_6.sendSmsExpectMore() for the response returned.
  */
-TEST_P(RadioHidlTest_v1_6, sendSMSExpectMore_1_6) {
-    LOG(DEBUG) << "sendSMSExpectMore";
+TEST_P(RadioHidlTest_v1_6, sendSmsExpectMore_1_6) {
+    LOG(DEBUG) << "sendSmsExpectMore";
     serial = GetRandomSerialNumber();
     GsmSmsMessage msg;
     msg.smscPdu = "";
@@ -241,7 +241,7 @@
              ::android::hardware::radio::V1_6::RadioError::SIM_ABSENT},
             CHECK_GENERAL_ERROR));
     }
-    LOG(DEBUG) << "sendSMSExpectMore finished";
+    LOG(DEBUG) << "sendSmsExpectMore finished";
 }
 
 /*
@@ -392,6 +392,7 @@
                 CheckAnyOfErrors(radioRsp_v1_6->rspInfo.error,
                                  {::android::hardware::radio::V1_6::RadioError::RADIO_NOT_AVAILABLE,
                                   ::android::hardware::radio::V1_6::RadioError::INTERNAL_ERR,
+                                  ::android::hardware::radio::V1_6::RadioError::INVALID_STATE,
                                   ::android::hardware::radio::V1_6::RadioError::NONE}));
     }
 }
@@ -755,7 +756,7 @@
 /*
  * Test IRadio.getSimPhonebookRecords() for the response returned.
  */
-TEST_F(RadioHidlTest_v1_6, getSimPhonebookRecords) {
+TEST_P(RadioHidlTest_v1_6, getSimPhonebookRecords) {
     serial = GetRandomSerialNumber();
     radio_v1_6->getSimPhonebookRecords(serial);
     EXPECT_EQ(std::cv_status::no_timeout, wait());
diff --git a/radio/1.6/vts/functional/radio_hidl_hal_misc.cpp b/radio/1.6/vts/functional/radio_hidl_hal_misc.cpp
new file mode 100644
index 0000000..4222441
--- /dev/null
+++ b/radio/1.6/vts/functional/radio_hidl_hal_misc.cpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <regex>
+
+#include <android-base/logging.h>
+#include <radio_hidl_hal_utils_v1_6.h>
+
+/*
+ * Test IRadio.getAvailableNetworks() for the response returned.
+ */
+TEST_P(RadioHidlTest_v1_6, getAvailableNetworks) {
+    LOG(DEBUG) << "getAvailableNetworks";
+    serial = GetRandomSerialNumber();
+
+    radio_v1_6->getAvailableNetworks(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(serial, radioRsp_v1_6->rspInfo_v1_0.serial);
+    ASSERT_TRUE(radioRsp_v1_6->rspInfo_v1_0.type == RadioResponseType::SOLICITED ||
+                radioRsp_v1_6->rspInfo_v1_0.type == RadioResponseType::SOLICITED_ACK_EXP);
+
+    if (cardStatus.base.base.base.cardState == CardState::ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(
+                radioRsp_v1_6->rspInfo_v1_0.error,
+                {::android::hardware::radio::V1_0::RadioError::NONE,
+                 ::android::hardware::radio::V1_0::RadioError::CANCELLED,
+                 ::android::hardware::radio::V1_0::RadioError::DEVICE_IN_USE,
+                 ::android::hardware::radio::V1_0::RadioError::MODEM_ERR,
+                 ::android::hardware::radio::V1_0::RadioError::OPERATION_NOT_ALLOWED},
+                CHECK_GENERAL_ERROR));
+    } else if (radioRsp_v1_6->rspInfo_v1_0.error ==
+               ::android::hardware::radio::V1_0::RadioError::NONE) {
+        static const std::regex kOperatorNumericRe("^[0-9]{5,6}$");
+        for (OperatorInfo info : radioRsp_v1_6->networkInfos) {
+            if (info.operatorNumeric != nullptr) {
+                ASSERT_TRUE(
+                        std::regex_match(std::string(info.operatorNumeric), kOperatorNumericRe));
+            }
+        }
+    }
+
+    LOG(DEBUG) << "getAvailableNetworks finished";
+}
diff --git a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h
index 114091a..3185f98 100644
--- a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h
+++ b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h
@@ -60,6 +60,7 @@
 
   public:
     hidl_vec<RadioBandMode> radioBandModes;
+    hidl_vec<OperatorInfo> networkInfos;
 
     ::android::hardware::radio::V1_0::RadioResponseInfo rspInfo_v1_0;
     ::android::hardware::radio::V1_6::RadioResponseInfo rspInfo;
@@ -760,7 +761,7 @@
             const ::android::hardware::radio::V1_6::RadioResponseInfo& info,
             const SendSmsResult& sms);
 
-    Return<void> sendSMSExpectMoreResponse_1_6(
+    Return<void> sendSmsExpectMoreResponse_1_6(
             const ::android::hardware::radio::V1_6::RadioResponseInfo& info,
             const SendSmsResult& sms);
 
diff --git a/radio/1.6/vts/functional/radio_response.cpp b/radio/1.6/vts/functional/radio_response.cpp
index 2b6d1bb..6e7b86f 100644
--- a/radio/1.6/vts/functional/radio_response.cpp
+++ b/radio/1.6/vts/functional/radio_response.cpp
@@ -274,8 +274,11 @@
 }
 
 Return<void> RadioResponse_v1_6::getAvailableNetworksResponse(
-        const ::android::hardware::radio::V1_0::RadioResponseInfo& /*info*/,
-        const ::android::hardware::hidl_vec<OperatorInfo>& /*networkInfos*/) {
+        const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
+        const ::android::hardware::hidl_vec<OperatorInfo>& networkInfos) {
+    rspInfo_v1_0 = info;
+    this->networkInfos = networkInfos;
+    parent_v1_6.notify(info.serial);
     return Void();
 }
 
@@ -1090,7 +1093,7 @@
     return Void();
 }
 
-Return<void> RadioResponse_v1_6::sendSMSExpectMoreResponse_1_6(
+Return<void> RadioResponse_v1_6::sendSmsExpectMoreResponse_1_6(
         const ::android::hardware::radio::V1_6::RadioResponseInfo& info,
         const SendSmsResult& sms) {
     rspInfo = info;
diff --git a/radio/config/1.3/IRadioConfigResponse.hal b/radio/config/1.3/IRadioConfigResponse.hal
index 15eefed..f6aee31 100644
--- a/radio/config/1.3/IRadioConfigResponse.hal
+++ b/radio/config/1.3/IRadioConfigResponse.hal
@@ -37,6 +37,8 @@
      *        - Requesting android.hardware.radio@1.6::IRadio.setDataThrottling()
      *        - Providing android.hardware.radio@1.6::SlicingConfig through
      *          android.hardware.radio@1.6::getSlicingConfig()
+     *        - Providing android.hardware.radio@1.6::PhysicalChannelConfig through
+     *          android.hardware.radio@1.6::IRadioIndication.currentPhysicalChannelConfigs_1_6()
      *
      * Valid errors returned:
      *   RadioError:NONE
diff --git a/rebootescrow/aidl/default/Android.bp b/rebootescrow/aidl/default/Android.bp
index b9fb2a9..1f67a3e 100644
--- a/rebootescrow/aidl/default/Android.bp
+++ b/rebootescrow/aidl/default/Android.bp
@@ -87,7 +87,9 @@
     ],
     static_libs: [
         "libhadamardutils",
-        "libgtest_prod",
+    ],
+    header_libs: [
+        "libgtest_prod_headers",
     ],
     shared_libs: [
         "liblog",
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
index 88c479c..f566462 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
@@ -35,6 +35,7 @@
 /* @hide */
 @VintfStability
 interface IRemotelyProvisionedComponent {
+  android.hardware.security.keymint.RpcHardwareInfo getHardwareInfo();
   byte[] generateEcdsaP256KeyPair(in boolean testMode, out android.hardware.security.keymint.MacedPublicKey macedPublicKey);
   byte[] generateCertificateRequest(in boolean testMode, in android.hardware.security.keymint.MacedPublicKey[] keysToSign, in byte[] endpointEncryptionCertChain, in byte[] challenge, out android.hardware.security.keymint.DeviceInfo deviceInfo, out android.hardware.security.keymint.ProtectedData protectedData);
   const int STATUS_FAILED = 1;
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/RpcHardwareInfo.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/RpcHardwareInfo.aidl
new file mode 100644
index 0000000..06bce19
--- /dev/null
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/RpcHardwareInfo.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.security.keymint;
+/* @hide */
+@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability
+parcelable RpcHardwareInfo {
+  int versionNumber;
+  @utf8InCpp String rpcAuthorName;
+  int supportedEekCurve = 0;
+  const int CURVE_NONE = 0;
+  const int CURVE_P256 = 1;
+  const int CURVE_25519 = 2;
+}
diff --git a/security/keymint/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl b/security/keymint/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
index 1ae6762..b6285d9 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
@@ -19,6 +19,7 @@
 import android.hardware.security.keymint.DeviceInfo;
 import android.hardware.security.keymint.MacedPublicKey;
 import android.hardware.security.keymint.ProtectedData;
+import android.hardware.security.keymint.RpcHardwareInfo;
 
 /**
  * An IRemotelyProvisionedComponent is a secure-side component for which certificates can be
@@ -121,6 +122,12 @@
     const int STATUS_INVALID_EEK = 5;
 
     /**
+     * @return info which contains information about the underlying IRemotelyProvisionedComponent
+     *         hardware, such as version number, component name, author name, and supported curve.
+     */
+    RpcHardwareInfo getHardwareInfo();
+
+    /**
      * generateKeyPair generates a new ECDSA P-256 key pair that can be certified.  Note that this
      * method only generates ECDSA P-256 key pairs, but the interface can be extended to add methods
      * for generating keys for other algorithms, if necessary.
diff --git a/security/keymint/aidl/android/hardware/security/keymint/RpcHardwareInfo.aidl b/security/keymint/aidl/android/hardware/security/keymint/RpcHardwareInfo.aidl
new file mode 100644
index 0000000..d297f87
--- /dev/null
+++ b/security/keymint/aidl/android/hardware/security/keymint/RpcHardwareInfo.aidl
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.security.keymint;
+
+/**
+ * RpcHardwareInfo is the hardware information returned by calling RemotelyProvisionedComponent
+ * getHardwareInfo()
+ * @hide
+ */
+@VintfStability
+@RustDerive(Clone=true, Eq=true, PartialEq=true, Ord=true, PartialOrd=true, Hash=true)
+parcelable RpcHardwareInfo {
+    const int CURVE_NONE = 0;
+    const int CURVE_P256 = 1;
+    const int CURVE_25519 = 2;
+
+    /**
+     * Implementation version of the remotely provisioned component hardware.  The version number is
+     * implementation defined, and not necessarily globally meaningful.  The version is used to
+     * distinguish between different versions of a given implementation.
+     */
+    int versionNumber;
+
+    /**
+     * rpcAuthorName is the name of the author of the IRemotelyProvisionedComponent implementation
+     * (organization name, not individual). This name is implementation defined, so it can be used
+     * to distinguish between different implementations from the same author.
+     */
+    @utf8InCpp String rpcAuthorName;
+
+    /**
+     * supportedEekCurve returns an int representing which curve is supported for validating
+     * signatures over the Endpoint Encryption Key certificate chain and for using the corresponding
+     * signed encryption key in ECDH. Only one curve should be supported, with preference for 25519
+     * if it's available. These values are defined as constants above.
+     *
+     * CURVE_NONE is made the default to help ensure that an implementor doesn't accidentally forget
+     * to provide the correct information here, as the VTS tests will check to make certain that
+     * a passing implementation does not provide CURVE_NONE.
+     */
+    int supportedEekCurve = CURVE_NONE;
+}
diff --git a/security/keymint/aidl/default/Android.bp b/security/keymint/aidl/default/Android.bp
index ebdc9b7..230534c 100644
--- a/security/keymint/aidl/default/Android.bp
+++ b/security/keymint/aidl/default/Android.bp
@@ -33,7 +33,6 @@
         "libkeymint",
         "liblog",
         "libpuresoftkeymasterdevice",
-        "libremote_provisioner",
         "libutils",
     ],
     srcs: [
@@ -51,28 +50,3 @@
     vendor: true,
     src: "android.hardware.hardware_keystore.xml",
 }
-
-cc_library {
-    name: "libremote_provisioner",
-    vendor_available: true,
-    static_libs: [
-        "libkeymint_remote_prov_support",
-    ],
-    shared_libs: [
-        "android.hardware.security.keymint-V1-ndk_platform",
-        "libbinder_ndk",
-        "libcppbor_external",
-        "libcppcose",
-        "libcrypto",
-        "libkeymaster_portable",
-        "libkeymint",
-        "liblog",
-        "libpuresoftkeymasterdevice",
-    ],
-    export_include_dirs: [
-        ".",
-    ],
-    srcs: [
-        "RemotelyProvisionedComponent.cpp",
-    ],
-}
diff --git a/security/keymint/aidl/default/RemotelyProvisionedComponent.cpp b/security/keymint/aidl/default/RemotelyProvisionedComponent.cpp
deleted file mode 100644
index 5b02729..0000000
--- a/security/keymint/aidl/default/RemotelyProvisionedComponent.cpp
+++ /dev/null
@@ -1,464 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "RemotelyProvisionedComponent.h"
-
-#include <assert.h>
-#include <variant>
-
-#include <cppbor.h>
-#include <cppbor_parse.h>
-
-#include <KeyMintUtils.h>
-#include <cppcose/cppcose.h>
-#include <keymaster/keymaster_configuration.h>
-#include <remote_prov/remote_prov_utils.h>
-
-#include <openssl/bn.h>
-#include <openssl/ec.h>
-#include <openssl/rand.h>
-#include <openssl/x509.h>
-
-namespace aidl::android::hardware::security::keymint {
-
-using ::std::string;
-using ::std::tuple;
-using ::std::unique_ptr;
-using ::std::variant;
-using ::std::vector;
-using bytevec = ::std::vector<uint8_t>;
-
-using namespace cppcose;
-using namespace keymaster;
-
-namespace {
-
-// Hard-coded set of acceptable public keys that can act as roots of EEK chains.
-inline const vector<bytevec> kAuthorizedEekRoots = {
-        // TODO(drysdale): replace this random value with real root pubkey(s).
-        {0x5c, 0xea, 0x4b, 0xd2, 0x31, 0x27, 0x15, 0x5e, 0x62, 0x94, 0x70,
-         0x53, 0x94, 0x43, 0x0f, 0x9a, 0x89, 0xd5, 0xc5, 0x0f, 0x82, 0x9b,
-         0xcd, 0x10, 0xe0, 0x79, 0xef, 0xf3, 0xfa, 0x40, 0xeb, 0x0a},
-};
-
-constexpr auto STATUS_FAILED = RemotelyProvisionedComponent::STATUS_FAILED;
-constexpr auto STATUS_INVALID_EEK = RemotelyProvisionedComponent::STATUS_INVALID_EEK;
-constexpr auto STATUS_INVALID_MAC = RemotelyProvisionedComponent::STATUS_INVALID_MAC;
-constexpr uint32_t kAffinePointLength = 32;
-struct AStatusDeleter {
-    void operator()(AStatus* p) { AStatus_delete(p); }
-};
-
-// TODO(swillden): Remove the dependency on AStatus stuff.  The COSE lib should use something like
-// StatusOr, but it shouldn't depend on AStatus.
-class Status {
-  public:
-    Status() {}
-    Status(int32_t errCode, const std::string& errMsg)
-        : status_(AStatus_fromServiceSpecificErrorWithMessage(errCode, errMsg.c_str())) {}
-    explicit Status(const std::string& errMsg)
-        : status_(AStatus_fromServiceSpecificErrorWithMessage(STATUS_FAILED, errMsg.c_str())) {}
-    Status(AStatus* status) : status_(status) {}
-    Status(Status&&) = default;
-    Status(const Status&) = delete;
-
-    operator ::ndk::ScopedAStatus() && { return ndk::ScopedAStatus(status_.release()); }
-
-    bool isOk() { return !status_; }
-
-    // Don't call getMessage() unless isOk() returns false;
-    const char* getMessage() const { return AStatus_getMessage(status_.get()); }
-
-  private:
-    std::unique_ptr<AStatus, AStatusDeleter> status_;
-};
-
-template <typename T>
-class StatusOr {
-  public:
-    StatusOr(AStatus* status) : status_(status) {}
-    StatusOr(Status status) : status_(std::move(status)) {}
-    StatusOr(T val) : value_(std::move(val)) {}
-
-    bool isOk() { return status_.isOk(); }
-
-    T* operator->() & {
-        assert(isOk());
-        return &value_.value();
-    }
-    T& operator*() & {
-        assert(isOk());
-        return value_.value();
-    }
-    T&& operator*() && {
-        assert(isOk());
-        return std::move(value_).value();
-    }
-
-    const char* getMessage() const {
-        assert(!isOk());
-        return status_.getMessage();
-    }
-
-    Status moveError() {
-        assert(!isOk());
-        return std::move(status_);
-    }
-
-    T moveValue() { return std::move(value_).value(); }
-
-  private:
-    Status status_;
-    std::optional<T> value_;
-};
-
-StatusOr<std::pair<bytevec /* EEK pub */, bytevec /* EEK ID */>> validateAndExtractEekPubAndId(
-        bool testMode, const bytevec& endpointEncryptionCertChain) {
-    auto [item, newPos, errMsg] = cppbor::parse(endpointEncryptionCertChain);
-
-    if (!item || !item->asArray()) {
-        return Status("Error parsing EEK chain" + errMsg);
-    }
-
-    const cppbor::Array* certArr = item->asArray();
-    bytevec lastPubKey;
-    for (int i = 0; i < certArr->size(); ++i) {
-        auto cosePubKey = verifyAndParseCoseSign1(testMode, certArr->get(i)->asArray(),
-                                                  std::move(lastPubKey), bytevec{} /* AAD */);
-        if (!cosePubKey) {
-            return Status(STATUS_INVALID_EEK,
-                          "Failed to validate EEK chain: " + cosePubKey.moveMessage());
-        }
-        lastPubKey = *std::move(cosePubKey);
-
-        // In prod mode the first pubkey should match a well-known Google public key.
-        if (!testMode && i == 0 &&
-            std::find(kAuthorizedEekRoots.begin(), kAuthorizedEekRoots.end(), lastPubKey) ==
-                    kAuthorizedEekRoots.end()) {
-            return Status(STATUS_INVALID_EEK, "Unrecognized root of EEK chain");
-        }
-    }
-
-    auto eek = CoseKey::parseX25519(lastPubKey, true /* requireKid */);
-    if (!eek) return Status(STATUS_INVALID_EEK, "Failed to get EEK: " + eek.moveMessage());
-
-    return std::make_pair(eek->getBstrValue(CoseKey::PUBKEY_X).value(),
-                          eek->getBstrValue(CoseKey::KEY_ID).value());
-}
-
-StatusOr<bytevec /* pubkeys */> validateAndExtractPubkeys(bool testMode,
-                                                          const vector<MacedPublicKey>& keysToSign,
-                                                          const bytevec& macKey) {
-    auto pubKeysToMac = cppbor::Array();
-    for (auto& keyToSign : keysToSign) {
-        auto [macedKeyItem, _, coseMacErrMsg] = cppbor::parse(keyToSign.macedKey);
-        if (!macedKeyItem || !macedKeyItem->asArray() ||
-            macedKeyItem->asArray()->size() != kCoseMac0EntryCount) {
-            return Status("Invalid COSE_Mac0 structure");
-        }
-
-        auto protectedParms = macedKeyItem->asArray()->get(kCoseMac0ProtectedParams)->asBstr();
-        auto unprotectedParms = macedKeyItem->asArray()->get(kCoseMac0UnprotectedParams)->asMap();
-        auto payload = macedKeyItem->asArray()->get(kCoseMac0Payload)->asBstr();
-        auto tag = macedKeyItem->asArray()->get(kCoseMac0Tag)->asBstr();
-        if (!protectedParms || !unprotectedParms || !payload || !tag) {
-            return Status("Invalid COSE_Mac0 contents");
-        }
-
-        auto [protectedMap, __, errMsg] = cppbor::parse(protectedParms);
-        if (!protectedMap || !protectedMap->asMap()) {
-            return Status("Invalid Mac0 protected: " + errMsg);
-        }
-        auto& algo = protectedMap->asMap()->get(ALGORITHM);
-        if (!algo || !algo->asInt() || algo->asInt()->value() != HMAC_256) {
-            return Status("Unsupported Mac0 algorithm");
-        }
-
-        auto pubKey = CoseKey::parse(payload->value(), EC2, ES256, P256);
-        if (!pubKey) return Status(pubKey.moveMessage());
-
-        bool testKey = static_cast<bool>(pubKey->getMap().get(CoseKey::TEST_KEY));
-        if (testMode && !testKey) {
-            return Status(BnRemotelyProvisionedComponent::STATUS_PRODUCTION_KEY_IN_TEST_REQUEST,
-                          "Production key in test request");
-        } else if (!testMode && testKey) {
-            return Status(BnRemotelyProvisionedComponent::STATUS_TEST_KEY_IN_PRODUCTION_REQUEST,
-                          "Test key in production request");
-        }
-
-        auto macTag = generateCoseMac0Mac(macKey, {} /* external_aad */, payload->value());
-        if (!macTag) return Status(STATUS_INVALID_MAC, macTag.moveMessage());
-        if (macTag->size() != tag->value().size() ||
-            CRYPTO_memcmp(macTag->data(), tag->value().data(), macTag->size()) != 0) {
-            return Status(STATUS_INVALID_MAC, "MAC tag mismatch");
-        }
-
-        pubKeysToMac.add(pubKey->moveMap());
-    }
-
-    return pubKeysToMac.encode();
-}
-
-StatusOr<std::pair<bytevec, bytevec>> buildCosePublicKeyFromKmCert(
-        const keymaster_blob_t* km_cert) {
-    if (km_cert == nullptr) {
-        return Status(STATUS_FAILED, "km_cert is a nullptr");
-    }
-    const uint8_t* temp = km_cert->data;
-    X509* cert = d2i_X509(NULL, &temp, km_cert->data_length);
-    if (cert == nullptr) {
-        return Status(STATUS_FAILED, "d2i_X509 returned null when attempting to get the cert.");
-    }
-    EVP_PKEY* pubKey = X509_get_pubkey(cert);
-    if (pubKey == nullptr) {
-        return Status(STATUS_FAILED, "Boringssl failed to get the public key from the cert");
-    }
-    EC_KEY* ecKey = EVP_PKEY_get0_EC_KEY(pubKey);
-    if (ecKey == nullptr) {
-        return Status(STATUS_FAILED,
-                      "The key in the certificate returned from GenerateKey is not "
-                      "an EC key.");
-    }
-    const EC_POINT* jacobian_coords = EC_KEY_get0_public_key(ecKey);
-    BIGNUM x;
-    BIGNUM y;
-    BN_CTX* ctx = BN_CTX_new();
-    if (ctx == nullptr) {
-        return Status(STATUS_FAILED, "Memory allocation failure for BN_CTX");
-    }
-    if (!EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(ecKey), jacobian_coords, &x, &y,
-                                             ctx)) {
-        return Status(STATUS_FAILED, "Failed to get affine coordinates");
-    }
-    bytevec x_bytestring(kAffinePointLength);
-    bytevec y_bytestring(kAffinePointLength);
-    if (BN_bn2binpad(&x, x_bytestring.data(), kAffinePointLength) != kAffinePointLength) {
-        return Status(STATUS_FAILED, "Wrote incorrect number of bytes for x coordinate");
-    }
-    if (BN_bn2binpad(&y, y_bytestring.data(), kAffinePointLength) != kAffinePointLength) {
-        return Status(STATUS_FAILED, "Wrote incorrect number of bytes for y coordinate");
-    }
-    BN_CTX_free(ctx);
-    return std::make_pair(x_bytestring, y_bytestring);
-}
-
-cppbor::Array buildCertReqRecipients(const bytevec& pubkey, const bytevec& kid) {
-    return cppbor::Array()                   // Array of recipients
-            .add(cppbor::Array()             // Recipient
-                         .add(cppbor::Map()  // Protected
-                                      .add(ALGORITHM, ECDH_ES_HKDF_256)
-                                      .canonicalize()
-                                      .encode())
-                         .add(cppbor::Map()  // Unprotected
-                                      .add(COSE_KEY, cppbor::Map()
-                                                             .add(CoseKey::KEY_TYPE, OCTET_KEY_PAIR)
-                                                             .add(CoseKey::CURVE, cppcose::X25519)
-                                                             .add(CoseKey::PUBKEY_X, pubkey)
-                                                             .canonicalize())
-                                      .add(KEY_ID, kid)
-                                      .canonicalize())
-                         .add(cppbor::Null()));  // No ciphertext
-}
-
-static keymaster_key_param_t kKeyMintEcdsaP256Params[] = {
-        Authorization(TAG_PURPOSE, KM_PURPOSE_ATTEST_KEY),
-        Authorization(TAG_ALGORITHM, KM_ALGORITHM_EC), Authorization(TAG_KEY_SIZE, 256),
-        Authorization(TAG_DIGEST, KM_DIGEST_SHA_2_256),
-        Authorization(TAG_EC_CURVE, KM_EC_CURVE_P_256), Authorization(TAG_NO_AUTH_REQUIRED),
-        // The certificate generated by KM will be discarded, these values don't matter.
-        Authorization(TAG_CERTIFICATE_NOT_BEFORE, 0), Authorization(TAG_CERTIFICATE_NOT_AFTER, 0)};
-
-}  // namespace
-
-RemotelyProvisionedComponent::RemotelyProvisionedComponent(
-        std::shared_ptr<keymint::AndroidKeyMintDevice> keymint) {
-    std::tie(devicePrivKey_, bcc_) = generateBcc();
-    impl_ = keymint->getKeymasterImpl();
-}
-
-RemotelyProvisionedComponent::~RemotelyProvisionedComponent() {}
-
-ScopedAStatus RemotelyProvisionedComponent::generateEcdsaP256KeyPair(bool testMode,
-                                                                     MacedPublicKey* macedPublicKey,
-                                                                     bytevec* privateKeyHandle) {
-    // TODO(jbires): The following should move from ->GenerateKey to ->GenerateRKPKey and everything
-    //              after the GenerateKey call should basically be moved into that new function call
-    //              as well once the issue with libcppbor in system/keymaster is sorted out
-    GenerateKeyRequest request(impl_->message_version());
-    request.key_description.Reinitialize(kKeyMintEcdsaP256Params,
-                                         array_length(kKeyMintEcdsaP256Params));
-    GenerateKeyResponse response(impl_->message_version());
-    impl_->GenerateKey(request, &response);
-    if (response.error != KM_ERROR_OK) {
-        return km_utils::kmError2ScopedAStatus(response.error);
-    }
-
-    if (response.certificate_chain.entry_count != 1) {
-        // Error: Need the single non-signed certificate with the public key in it.
-        return Status(STATUS_FAILED,
-                      "Expected to receive a single certificate from GenerateKey. Instead got: " +
-                              std::to_string(response.certificate_chain.entry_count));
-    }
-    auto affineCoords = buildCosePublicKeyFromKmCert(response.certificate_chain.begin());
-    if (!affineCoords.isOk()) return affineCoords.moveError();
-    cppbor::Map cosePublicKeyMap = cppbor::Map()
-                                           .add(CoseKey::KEY_TYPE, EC2)
-                                           .add(CoseKey::ALGORITHM, ES256)
-                                           .add(CoseKey::CURVE, cppcose::P256)
-                                           .add(CoseKey::PUBKEY_X, affineCoords->first)
-                                           .add(CoseKey::PUBKEY_Y, affineCoords->second);
-    if (testMode) {
-        cosePublicKeyMap.add(CoseKey::TEST_KEY, cppbor::Null());
-    }
-
-    bytevec cosePublicKey = cosePublicKeyMap.canonicalize().encode();
-
-    auto macedKey = constructCoseMac0(testMode ? remote_prov::kTestMacKey : macKey_,
-                                      {} /* externalAad */, cosePublicKey);
-    if (!macedKey) return Status(macedKey.moveMessage());
-
-    macedPublicKey->macedKey = macedKey->encode();
-    *privateKeyHandle = km_utils::kmBlob2vector(response.key_blob);
-    return ScopedAStatus::ok();
-}
-
-ScopedAStatus RemotelyProvisionedComponent::generateCertificateRequest(
-        bool testMode, const vector<MacedPublicKey>& keysToSign,
-        const bytevec& endpointEncCertChain, const bytevec& challenge, DeviceInfo* deviceInfo,
-        ProtectedData* protectedData, bytevec* keysToSignMac) {
-    auto pubKeysToSign = validateAndExtractPubkeys(testMode, keysToSign,
-                                                   testMode ? remote_prov::kTestMacKey : macKey_);
-    if (!pubKeysToSign.isOk()) return pubKeysToSign.moveError();
-
-    bytevec ephemeralMacKey = remote_prov::randomBytes(SHA256_DIGEST_LENGTH);
-
-    auto pubKeysToSignMac = generateCoseMac0Mac(ephemeralMacKey, bytevec{}, *pubKeysToSign);
-    if (!pubKeysToSignMac) return Status(pubKeysToSignMac.moveMessage());
-    *keysToSignMac = *std::move(pubKeysToSignMac);
-
-    bytevec devicePrivKey;
-    cppbor::Array bcc;
-    if (testMode) {
-        std::tie(devicePrivKey, bcc) = generateBcc();
-    } else {
-        devicePrivKey = devicePrivKey_;
-        bcc = bcc_.clone();
-    }
-
-    std::unique_ptr<cppbor::Map> deviceInfoMap = createDeviceInfo();
-    deviceInfo->deviceInfo = deviceInfoMap->encode();
-    auto signedMac = constructCoseSign1(devicePrivKey /* Signing key */,  //
-                                        ephemeralMacKey /* Payload */,
-                                        cppbor::Array() /* AAD */
-                                                .add(challenge)
-                                                .add(std::move(deviceInfoMap))
-                                                .encode());
-    if (!signedMac) return Status(signedMac.moveMessage());
-
-    bytevec ephemeralPrivKey(X25519_PRIVATE_KEY_LEN);
-    bytevec ephemeralPubKey(X25519_PUBLIC_VALUE_LEN);
-    X25519_keypair(ephemeralPubKey.data(), ephemeralPrivKey.data());
-
-    auto eek = validateAndExtractEekPubAndId(testMode, endpointEncCertChain);
-    if (!eek.isOk()) return eek.moveError();
-
-    auto sessionKey = x25519_HKDF_DeriveKey(ephemeralPubKey, ephemeralPrivKey, eek->first,
-                                            true /* senderIsA */);
-    if (!sessionKey) return Status(sessionKey.moveMessage());
-
-    auto coseEncrypted =
-            constructCoseEncrypt(*sessionKey, remote_prov::randomBytes(kAesGcmNonceLength),
-                                 cppbor::Array()  // payload
-                                         .add(signedMac.moveValue())
-                                         .add(std::move(bcc))
-                                         .encode(),
-                                 {},  // aad
-                                 buildCertReqRecipients(ephemeralPubKey, eek->second));
-
-    if (!coseEncrypted) return Status(coseEncrypted.moveMessage());
-    protectedData->protectedData = coseEncrypted->encode();
-
-    return ScopedAStatus::ok();
-}
-
-bytevec RemotelyProvisionedComponent::deriveBytesFromHbk(const string& context,
-                                                         size_t numBytes) const {
-    bytevec fakeHbk(32, 0);
-    bytevec result(numBytes);
-
-    // TODO(swillden): Figure out if HKDF can fail.  It doesn't seem like it should be able to,
-    // but the function does return an error code.
-    HKDF(result.data(), numBytes,               //
-         EVP_sha256(),                          //
-         fakeHbk.data(), fakeHbk.size(),        //
-         nullptr /* salt */, 0 /* salt len */,  //
-         reinterpret_cast<const uint8_t*>(context.data()), context.size());
-
-    return result;
-}
-
-std::unique_ptr<cppbor::Map> RemotelyProvisionedComponent::createDeviceInfo() const {
-    auto result = std::make_unique<cppbor::Map>(cppbor::Map());
-
-    // The following placeholders show how the DeviceInfo map would be populated.
-    // result->add(cppbor::Tstr("brand"), cppbor::Tstr("Google"));
-    // result->add(cppbor::Tstr("manufacturer"), cppbor::Tstr("Google"));
-    // result->add(cppbor::Tstr("product"), cppbor::Tstr("Fake"));
-    // result->add(cppbor::Tstr("model"), cppbor::Tstr("Imaginary"));
-    // result->add(cppbor::Tstr("board"), cppbor::Tstr("Chess"));
-    // result->add(cppbor::Tstr("vb_state"), cppbor::Tstr("orange"));
-    // result->add(cppbor::Tstr("bootloader_state"), cppbor::Tstr("unlocked"));
-    // result->add(cppbor::Tstr("os_version"), cppbor::Tstr("SC"));
-    // result->add(cppbor::Tstr("system_patch_level"), cppbor::Uint(20210331));
-    // result->add(cppbor::Tstr("boot_patch_level"), cppbor::Uint(20210331));
-    // result->add(cppbor::Tstr("vendor_patch_level"), cppbor::Uint(20210331));
-
-    result->canonicalize();
-    return result;
-}
-
-std::pair<bytevec /* privKey */, cppbor::Array /* BCC */>
-RemotelyProvisionedComponent::generateBcc() {
-    bytevec privKey(ED25519_PRIVATE_KEY_LEN);
-    bytevec pubKey(ED25519_PUBLIC_KEY_LEN);
-
-    ED25519_keypair(pubKey.data(), privKey.data());
-
-    auto coseKey = cppbor::Map()
-                           .add(CoseKey::KEY_TYPE, OCTET_KEY_PAIR)
-                           .add(CoseKey::ALGORITHM, EDDSA)
-                           .add(CoseKey::CURVE, ED25519)
-                           .add(CoseKey::KEY_OPS, VERIFY)
-                           .add(CoseKey::PUBKEY_X, pubKey)
-                           .canonicalize()
-                           .encode();
-    auto sign1Payload = cppbor::Map()
-                                .add(1 /* Issuer */, "Issuer")
-                                .add(2 /* Subject */, "Subject")
-                                .add(-4670552 /* Subject Pub Key */, coseKey)
-                                .add(-4670553 /* Key Usage (little-endian order) */,
-                                     std::vector<uint8_t>{0x20} /* keyCertSign = 1<<5 */)
-                                .canonicalize()
-                                .encode();
-    auto coseSign1 = constructCoseSign1(privKey,       /* signing key */
-                                        cppbor::Map(), /* extra protected */
-                                        sign1Payload, {} /* AAD */);
-    assert(coseSign1);
-
-    return {privKey, cppbor::Array().add(coseKey).add(coseSign1.moveValue())};
-}
-
-}  // namespace aidl::android::hardware::security::keymint
diff --git a/security/keymint/aidl/default/RemotelyProvisionedComponent.h b/security/keymint/aidl/default/RemotelyProvisionedComponent.h
deleted file mode 100644
index 8185e26..0000000
--- a/security/keymint/aidl/default/RemotelyProvisionedComponent.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <AndroidKeyMintDevice.h>
-#include <aidl/android/hardware/security/keymint/BnRemotelyProvisionedComponent.h>
-#include <aidl/android/hardware/security/keymint/SecurityLevel.h>
-#include <cppbor.h>
-#include <keymaster/UniquePtr.h>
-#include <keymaster/android_keymaster.h>
-
-namespace aidl::android::hardware::security::keymint {
-
-using ::ndk::ScopedAStatus;
-
-class RemotelyProvisionedComponent : public BnRemotelyProvisionedComponent {
-  public:
-    explicit RemotelyProvisionedComponent(std::shared_ptr<keymint::AndroidKeyMintDevice> keymint);
-    virtual ~RemotelyProvisionedComponent();
-
-    ScopedAStatus generateEcdsaP256KeyPair(bool testMode, MacedPublicKey* macedPublicKey,
-                                           std::vector<uint8_t>* privateKeyHandle) override;
-
-    ScopedAStatus generateCertificateRequest(bool testMode,
-                                             const std::vector<MacedPublicKey>& keysToSign,
-                                             const std::vector<uint8_t>& endpointEncCertChain,
-                                             const std::vector<uint8_t>& challenge,
-                                             DeviceInfo* deviceInfo, ProtectedData* protectedData,
-                                             std::vector<uint8_t>* keysToSignMac) override;
-
-  private:
-    // TODO(swillden): Move these into an appropriate Context class.
-    std::vector<uint8_t> deriveBytesFromHbk(const std::string& context, size_t numBytes) const;
-    std::unique_ptr<cppbor::Map> createDeviceInfo() const;
-    std::pair<std::vector<uint8_t>, cppbor::Array> generateBcc();
-
-    std::vector<uint8_t> macKey_ = deriveBytesFromHbk("Key to MAC public keys", 32);
-    std::vector<uint8_t> devicePrivKey_;
-    cppbor::Array bcc_;
-    std::shared_ptr<::keymaster::AndroidKeymaster> impl_;
-};
-
-}  // namespace aidl::android::hardware::security::keymint
diff --git a/security/keymint/aidl/default/service.cpp b/security/keymint/aidl/default/service.cpp
index bcebbaf..8092e34 100644
--- a/security/keymint/aidl/default/service.cpp
+++ b/security/keymint/aidl/default/service.cpp
@@ -21,14 +21,13 @@
 #include <android/binder_process.h>
 
 #include <AndroidKeyMintDevice.h>
+#include <AndroidRemotelyProvisionedComponentDevice.h>
 #include <AndroidSecureClock.h>
 #include <AndroidSharedSecret.h>
 #include <keymaster/soft_keymaster_logger.h>
 
-#include "RemotelyProvisionedComponent.h"
-
 using aidl::android::hardware::security::keymint::AndroidKeyMintDevice;
-using aidl::android::hardware::security::keymint::RemotelyProvisionedComponent;
+using aidl::android::hardware::security::keymint::AndroidRemotelyProvisionedComponentDevice;
 using aidl::android::hardware::security::keymint::SecurityLevel;
 using aidl::android::hardware::security::secureclock::AndroidSecureClock;
 using aidl::android::hardware::security::sharedsecret::AndroidSharedSecret;
@@ -56,7 +55,7 @@
     // Add Shared Secret Service
     addService<AndroidSharedSecret>(keyMint);
     // Add Remotely Provisioned Component Service
-    addService<RemotelyProvisionedComponent>(keyMint);
+    addService<AndroidRemotelyProvisionedComponentDevice>(keyMint);
     ABinderProcess_joinThreadPool();
     return EXIT_FAILURE;  // should not reach
 }
diff --git a/security/keymint/aidl/vts/functional/Android.bp b/security/keymint/aidl/vts/functional/Android.bp
index 6c7309e..d5c45e2 100644
--- a/security/keymint/aidl/vts/functional/Android.bp
+++ b/security/keymint/aidl/vts/functional/Android.bp
@@ -31,6 +31,7 @@
     ],
     srcs: [
         "AttestKeyTest.cpp",
+        "DeviceUniqueAttestationTest.cpp",
         "KeyMintTest.cpp",
     ],
     shared_libs: [
@@ -43,7 +44,7 @@
         "android.hardware.security.keymint-V1-ndk_platform",
         "android.hardware.security.secureclock-V1-ndk_platform",
         "libcppbor_external",
-        "libcppcose",
+        "libcppcose_rkp",
         "libkeymint_remote_prov_support",
         "libkeymint_vts_test_utils",
     ],
@@ -75,7 +76,7 @@
         "android.hardware.security.keymint-V1-ndk_platform",
         "android.hardware.security.secureclock-V1-ndk_platform",
         "libcppbor_external",
-        "libcppcose",
+        "libcppcose_rkp",
         "libgmock_ndk",
         "libkeymint_remote_prov_support",
     ],
@@ -92,21 +93,20 @@
     ],
     shared_libs: [
         "libbinder_ndk",
-        "libcppbor_external",
         "libcrypto",
-        "libkeymaster_portable",
-        "libpuresoftkeymasterdevice",
     ],
     static_libs: [
         "android.hardware.security.keymint-V1-ndk_platform",
         "android.hardware.security.secureclock-V1-ndk_platform",
-        "libcppcose",
+        "libcppbor_external",
+        "libcppcose_rkp",
         "libgmock_ndk",
+        "libkeymaster_portable",
         "libkeymint",
         "libkeymint_support",
         "libkeymint_remote_prov_support",
         "libkeymint_vts_test_utils",
-        "libremote_provisioner",
+        "libpuresoftkeymasterdevice",
     ],
     test_suites: [
         "general-tests",
diff --git a/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp b/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp
new file mode 100644
index 0000000..7009c6e
--- /dev/null
+++ b/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2021 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 "keymint_1_attest_key_test"
+
+#include <cutils/log.h>
+#include <cutils/properties.h>
+#include <keymint_support/key_param_output.h>
+#include <keymint_support/openssl_utils.h>
+
+#include "KeyMintAidlTestBase.h"
+
+namespace aidl::android::hardware::security::keymint::test {
+
+class DeviceUniqueAttestationTest : public KeyMintAidlTestBase {
+  protected:
+    void CheckUniqueAttestationResults(const vector<uint8_t>& key_blob,
+                                       const vector<KeyCharacteristics>& key_characteristics,
+                                       const AuthorizationSet& hw_enforced, int key_size) {
+        ASSERT_GT(cert_chain_.size(), 0);
+
+        if (KeyMintAidlTestBase::dump_Attestations) {
+            std::cout << bin2hex(cert_chain_[0].encodedCertificate) << std::endl;
+        }
+
+        ASSERT_GT(key_blob.size(), 0U);
+
+        AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
+
+        EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size)) << "Key size missing";
+
+        EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
+        ASSERT_GT(cert_chain_.size(), 0);
+
+        AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics);
+        EXPECT_TRUE(verify_attestation_record("challenge", "foo", sw_enforced, hw_enforced,
+                                              SecLevel(), cert_chain_[0].encodedCertificate));
+    }
+};
+
+/*
+ * DeviceUniqueAttestationTest.RsaNonStrongBoxUnimplemented
+ *
+ * Verifies that non strongbox implementations do not implement Rsa device unique
+ * attestation.
+ */
+TEST_P(DeviceUniqueAttestationTest, RsaNonStrongBoxUnimplemented) {
+    if (SecLevel() == SecurityLevel::STRONGBOX) return;
+
+    vector<uint8_t> key_blob;
+    vector<KeyCharacteristics> key_characteristics;
+
+    // Check RSA implementation
+    auto result = GenerateKey(AuthorizationSetBuilder()
+                                      .Authorization(TAG_NO_AUTH_REQUIRED)
+                                      .RsaSigningKey(2048, 65537)
+                                      .Digest(Digest::SHA_2_256)
+                                      .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN)
+                                      .Authorization(TAG_INCLUDE_UNIQUE_ID)
+                                      .Authorization(TAG_NO_AUTH_REQUIRED)
+                                      .AttestationChallenge("challenge")
+                                      .AttestationApplicationId("foo")
+                                      .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION),
+                              &key_blob, &key_characteristics);
+
+    ASSERT_TRUE(result == ErrorCode::UNSUPPORTED_TAG);
+}
+
+/*
+ * DeviceUniqueAttestationTest.EcdsaNonStrongBoxUnimplemented
+ *
+ * Verifies that non strongbox implementations do not implement Ecdsa device unique
+ * attestation.
+ */
+TEST_P(DeviceUniqueAttestationTest, EcdsaNonStrongBoxUnimplemented) {
+    if (SecLevel() == SecurityLevel::STRONGBOX) return;
+
+    vector<uint8_t> key_blob;
+    vector<KeyCharacteristics> key_characteristics;
+
+    // Check Ecdsa implementation
+    auto result = GenerateKey(AuthorizationSetBuilder()
+                                      .Authorization(TAG_NO_AUTH_REQUIRED)
+                                      .EcdsaSigningKey(EcCurve::P_256)
+                                      .Digest(Digest::SHA_2_256)
+                                      .Authorization(TAG_INCLUDE_UNIQUE_ID)
+                                      .AttestationChallenge("challenge")
+                                      .AttestationApplicationId("foo")
+                                      .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION),
+                              &key_blob, &key_characteristics);
+
+    ASSERT_TRUE(result == ErrorCode::UNSUPPORTED_TAG);
+}
+
+/*
+ * DeviceUniqueAttestationTest.RsaDeviceUniqueAttestation
+ *
+ * Verifies that strongbox implementations of Rsa implements device unique
+ * attestation correctly, if implemented.
+ */
+TEST_P(DeviceUniqueAttestationTest, RsaDeviceUniqueAttestation) {
+    if (SecLevel() != SecurityLevel::STRONGBOX) return;
+
+    vector<uint8_t> key_blob;
+    vector<KeyCharacteristics> key_characteristics;
+    int key_size = 2048;
+
+    auto result = GenerateKey(AuthorizationSetBuilder()
+                                      .Authorization(TAG_NO_AUTH_REQUIRED)
+                                      .RsaSigningKey(key_size, 65537)
+                                      .Digest(Digest::SHA_2_256)
+                                      .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN)
+                                      .Authorization(TAG_INCLUDE_UNIQUE_ID)
+                                      .Authorization(TAG_NO_AUTH_REQUIRED)
+                                      .AttestationChallenge("challenge")
+                                      .AttestationApplicationId("foo")
+                                      .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION),
+                              &key_blob, &key_characteristics);
+
+    // It is optional for Strong box to support DeviceUniqueAttestation.
+    if (result == ErrorCode::CANNOT_ATTEST_IDS) return;
+
+    ASSERT_EQ(ErrorCode::OK, result);
+
+    AuthorizationSet hw_enforced = AuthorizationSetBuilder()
+                                           .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION)
+                                           .Authorization(TAG_NO_AUTH_REQUIRED)
+                                           .RsaSigningKey(2048, 65537)
+                                           .Digest(Digest::SHA_2_256)
+                                           .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN)
+                                           .Authorization(TAG_ORIGIN, KeyOrigin::GENERATED)
+                                           .Authorization(TAG_OS_VERSION, os_version())
+                                           .Authorization(TAG_OS_PATCHLEVEL, os_patch_level());
+
+    CheckUniqueAttestationResults(key_blob, key_characteristics, hw_enforced, key_size);
+}
+
+/*
+ * DeviceUniqueAttestationTest.EcdsaDeviceUniqueAttestation
+ *
+ * Verifies that strongbox implementations of Rsa implements device unique
+ * attestation correctly, if implemented.
+ */
+TEST_P(DeviceUniqueAttestationTest, EcdsaDeviceUniqueAttestation) {
+    if (SecLevel() != SecurityLevel::STRONGBOX) return;
+
+    vector<uint8_t> key_blob;
+    vector<KeyCharacteristics> key_characteristics;
+    int key_size = 256;
+
+    auto result = GenerateKey(AuthorizationSetBuilder()
+                                      .Authorization(TAG_NO_AUTH_REQUIRED)
+                                      .EcdsaSigningKey(256)
+                                      .Digest(Digest::SHA_2_256)
+                                      .Authorization(TAG_INCLUDE_UNIQUE_ID)
+                                      .AttestationChallenge("challenge")
+                                      .AttestationApplicationId("foo")
+                                      .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION),
+                              &key_blob, &key_characteristics);
+
+    // It is optional for Strong box to support DeviceUniqueAttestation.
+    if (result == ErrorCode::CANNOT_ATTEST_IDS) return;
+    ASSERT_EQ(ErrorCode::OK, result);
+
+    AuthorizationSet hw_enforced = AuthorizationSetBuilder()
+                                           .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION)
+                                           .Authorization(TAG_NO_AUTH_REQUIRED)
+                                           .EcdsaSigningKey(EcCurve::P_256)
+                                           .Digest(Digest::SHA_2_256)
+                                           .Authorization(TAG_EC_CURVE, EcCurve::P_256)
+                                           .Authorization(TAG_ORIGIN, KeyOrigin::GENERATED)
+                                           .Authorization(TAG_OS_VERSION, os_version())
+                                           .Authorization(TAG_OS_PATCHLEVEL, os_patch_level());
+
+    CheckUniqueAttestationResults(key_blob, key_characteristics, hw_enforced, key_size);
+}
+
+INSTANTIATE_KEYMINT_AIDL_TEST(DeviceUniqueAttestationTest);
+
+}  // namespace aidl::android::hardware::security::keymint::test
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
index 3da0484..59cb57b 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
@@ -23,12 +23,12 @@
 #include <android-base/logging.h>
 #include <android/binder_manager.h>
 #include <cppbor_parse.h>
-#include <cppcose/cppcose.h>
 #include <cutils/properties.h>
 #include <gmock/gmock.h>
 #include <openssl/mem.h>
 #include <remote_prov/remote_prov_utils.h>
 
+#include <keymaster/cppcose/cppcose.h>
 #include <keymint_support/attestation_record.h>
 #include <keymint_support/key_param_output.h>
 #include <keymint_support/keymint_utils.h>
@@ -883,16 +883,20 @@
     if (error != ErrorCode::OK) return false;
 
     EXPECT_GE(att_attestation_version, 3U);
+    vector<uint8_t> appId(app_id.begin(), app_id.end());
 
-    expected_sw_enforced.push_back(TAG_ATTESTATION_APPLICATION_ID,
-                                   vector<uint8_t>(app_id.begin(), app_id.end()));
+    // check challenge and app id only if we expects a non-fake certificate
+    if (challenge.length() > 0) {
+        EXPECT_EQ(challenge.length(), att_challenge.size());
+        EXPECT_EQ(0, memcmp(challenge.data(), att_challenge.data(), challenge.length()));
+
+        expected_sw_enforced.push_back(TAG_ATTESTATION_APPLICATION_ID, appId);
+    }
 
     EXPECT_GE(att_keymaster_version, 4U);
     EXPECT_EQ(security_level, att_keymaster_security_level);
     EXPECT_EQ(security_level, att_attestation_security_level);
 
-    EXPECT_EQ(challenge.length(), att_challenge.size());
-    EXPECT_EQ(0, memcmp(challenge.data(), att_challenge.data(), challenge.length()));
 
     char property_value[PROPERTY_VALUE_MAX] = {};
     // TODO(b/136282179): When running under VTS-on-GSI the TEE-backed
diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
index 2d28845..09cdab1 100644
--- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
@@ -359,10 +359,10 @@
  * have correct characteristics.
  */
 TEST_P(NewKeyGenerationTest, RsaWithAttestation) {
-    for (auto key_size : ValidKeySizes(Algorithm::RSA)) {
-        auto challenge = "hello";
-        auto app_id = "foo";
+    auto challenge = "hello";
+    auto app_id = "foo";
 
+    for (auto key_size : ValidKeySizes(Algorithm::RSA)) {
         vector<uint8_t> key_blob;
         vector<KeyCharacteristics> key_characteristics;
         ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
@@ -470,6 +470,163 @@
 }
 
 /*
+ * NewKeyGenerationTest.RsaEncryptionWithAttestation
+ *
+ * Verifies that keymint attestation for RSA encryption keys with challenge and
+ * app id is also successful.
+ */
+TEST_P(NewKeyGenerationTest, RsaEncryptionWithAttestation) {
+    auto key_size = 2048;
+    auto challenge = "hello";
+    auto app_id = "foo";
+
+    vector<uint8_t> key_blob;
+    vector<KeyCharacteristics> key_characteristics;
+    ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
+                                                 .RsaEncryptionKey(key_size, 65537)
+                                                 .Padding(PaddingMode::NONE)
+                                                 .AttestationChallenge(challenge)
+                                                 .AttestationApplicationId(app_id)
+                                                 .Authorization(TAG_NO_AUTH_REQUIRED)
+                                                 .SetDefaultValidity(),
+                                         &key_blob, &key_characteristics));
+
+    ASSERT_GT(key_blob.size(), 0U);
+    AuthorizationSet auths;
+    for (auto& entry : key_characteristics) {
+        auths.push_back(AuthorizationSet(entry.authorizations));
+    }
+
+    EXPECT_TRUE(auths.Contains(TAG_ORIGIN, KeyOrigin::GENERATED));
+    EXPECT_TRUE(auths.Contains(TAG_PURPOSE, KeyPurpose::DECRYPT));
+
+    // Verify that App data and ROT are NOT included.
+    EXPECT_FALSE(auths.Contains(TAG_ROOT_OF_TRUST));
+    EXPECT_FALSE(auths.Contains(TAG_APPLICATION_DATA));
+
+    // Check that some unexpected tags/values are NOT present.
+    EXPECT_FALSE(auths.Contains(TAG_PURPOSE, KeyPurpose::SIGN));
+    EXPECT_FALSE(auths.Contains(TAG_PURPOSE, KeyPurpose::VERIFY));
+
+    EXPECT_FALSE(auths.Contains(TAG_AUTH_TIMEOUT, 301U));
+
+    auto os_ver = auths.GetTagValue(TAG_OS_VERSION);
+    ASSERT_TRUE(os_ver);
+    EXPECT_EQ(*os_ver, os_version());
+
+    AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
+
+    EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::RSA));
+    EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size))
+            << "Key size " << key_size << "missing";
+    EXPECT_TRUE(crypto_params.Contains(TAG_RSA_PUBLIC_EXPONENT, 65537U));
+
+    EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
+    ASSERT_GT(cert_chain_.size(), 0);
+
+    AuthorizationSet hw_enforced = HwEnforcedAuthorizations(key_characteristics);
+    AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics);
+    EXPECT_TRUE(verify_attestation_record(challenge, app_id,  //
+                                          sw_enforced, hw_enforced, SecLevel(),
+                                          cert_chain_[0].encodedCertificate));
+
+    CheckedDeleteKey(&key_blob);
+}
+
+/*
+ * NewKeyGenerationTest.RsaWithSelfSign
+ *
+ * Verifies that attesting to RSA key generation is successful, and returns
+ * self signed certificate if no challenge is provided.  And signing etc
+ * works as expected.
+ */
+TEST_P(NewKeyGenerationTest, RsaWithSelfSign) {
+    for (auto key_size : ValidKeySizes(Algorithm::RSA)) {
+        vector<uint8_t> key_blob;
+        vector<KeyCharacteristics> key_characteristics;
+        ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
+                                                     .RsaSigningKey(key_size, 65537)
+                                                     .Digest(Digest::NONE)
+                                                     .Padding(PaddingMode::NONE)
+                                                     .Authorization(TAG_NO_AUTH_REQUIRED)
+                                                     .SetDefaultValidity(),
+                                             &key_blob, &key_characteristics));
+
+        ASSERT_GT(key_blob.size(), 0U);
+        CheckBaseParams(key_characteristics);
+
+        AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
+
+        EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::RSA));
+        EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size))
+                << "Key size " << key_size << "missing";
+        EXPECT_TRUE(crypto_params.Contains(TAG_RSA_PUBLIC_EXPONENT, 65537U));
+
+        EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
+        ASSERT_EQ(cert_chain_.size(), 1);
+
+        CheckedDeleteKey(&key_blob);
+    }
+}
+
+/*
+ * NewKeyGenerationTest.RsaWithAttestationMissAppId
+ *
+ * Verifies that attesting to RSA checks for missing app ID.
+ */
+TEST_P(NewKeyGenerationTest, RsaWithAttestationMissAppId) {
+    auto challenge = "hello";
+    vector<uint8_t> key_blob;
+    vector<KeyCharacteristics> key_characteristics;
+
+    ASSERT_EQ(ErrorCode::ATTESTATION_APPLICATION_ID_MISSING,
+              GenerateKey(AuthorizationSetBuilder()
+                                  .RsaSigningKey(2048, 65537)
+                                  .Digest(Digest::NONE)
+                                  .Padding(PaddingMode::NONE)
+                                  .AttestationChallenge(challenge)
+                                  .Authorization(TAG_NO_AUTH_REQUIRED)
+                                  .SetDefaultValidity(),
+                          &key_blob, &key_characteristics));
+}
+
+/*
+ * NewKeyGenerationTest.RsaWithAttestationAppIdIgnored
+ *
+ * Verifies that attesting to RSA ignores app id if challenge is missing.
+ */
+TEST_P(NewKeyGenerationTest, RsaWithAttestationAppIdIgnored) {
+    auto key_size = 2048;
+    auto app_id = "foo";
+
+    vector<uint8_t> key_blob;
+    vector<KeyCharacteristics> key_characteristics;
+    ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
+                                                 .RsaSigningKey(key_size, 65537)
+                                                 .Digest(Digest::NONE)
+                                                 .Padding(PaddingMode::NONE)
+                                                 .AttestationApplicationId(app_id)
+                                                 .Authorization(TAG_NO_AUTH_REQUIRED)
+                                                 .SetDefaultValidity(),
+                                         &key_blob, &key_characteristics));
+
+    ASSERT_GT(key_blob.size(), 0U);
+    CheckBaseParams(key_characteristics);
+
+    AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
+
+    EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::RSA));
+    EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size))
+            << "Key size " << key_size << "missing";
+    EXPECT_TRUE(crypto_params.Contains(TAG_RSA_PUBLIC_EXPONENT, 65537U));
+
+    EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
+    ASSERT_EQ(cert_chain_.size(), 1);
+
+    CheckedDeleteKey(&key_blob);
+}
+
+/*
  * NewKeyGenerationTest.LimitedUsageRsa
  *
  * Verifies that KeyMint can generate all required RSA key sizes with limited usage, and that the
@@ -516,10 +673,10 @@
  * resulting keys have correct characteristics and attestation.
  */
 TEST_P(NewKeyGenerationTest, LimitedUsageRsaWithAttestation) {
-    for (auto key_size : ValidKeySizes(Algorithm::RSA)) {
-        auto challenge = "hello";
-        auto app_id = "foo";
+    auto challenge = "hello";
+    auto app_id = "foo";
 
+    for (auto key_size : ValidKeySizes(Algorithm::RSA)) {
         vector<uint8_t> key_blob;
         vector<KeyCharacteristics> key_characteristics;
         ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
@@ -628,6 +785,188 @@
 }
 
 /*
+ * NewKeyGenerationTest.EcdsaAttestation
+ *
+ * Verifies that for all Ecdsa key sizes, if challenge and app id is provided,
+ * an attestation will be generated.
+ */
+TEST_P(NewKeyGenerationTest, EcdsaAttestation) {
+    auto challenge = "hello";
+    auto app_id = "foo";
+
+    for (auto key_size : ValidKeySizes(Algorithm::EC)) {
+        vector<uint8_t> key_blob;
+        vector<KeyCharacteristics> key_characteristics;
+        ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
+                                                     .Authorization(TAG_NO_AUTH_REQUIRED)
+                                                     .EcdsaSigningKey(key_size)
+                                                     .Digest(Digest::NONE)
+                                                     .AttestationChallenge(challenge)
+                                                     .AttestationApplicationId(app_id)
+                                                     .SetDefaultValidity(),
+                                             &key_blob, &key_characteristics));
+        ASSERT_GT(key_blob.size(), 0U);
+        CheckBaseParams(key_characteristics);
+
+        AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
+
+        EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::EC));
+        EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size))
+                << "Key size " << key_size << "missing";
+
+        EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
+        ASSERT_GT(cert_chain_.size(), 0);
+
+        AuthorizationSet hw_enforced = HwEnforcedAuthorizations(key_characteristics);
+        AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics);
+        EXPECT_TRUE(verify_attestation_record(challenge, app_id,  //
+                                              sw_enforced, hw_enforced, SecLevel(),
+                                              cert_chain_[0].encodedCertificate));
+
+        CheckedDeleteKey(&key_blob);
+    }
+}
+
+/*
+ * NewKeyGenerationTest.EcdsaSelfSignAttestation
+ *
+ * Verifies that if no challenge is provided to an Ecdsa key generation, then
+ * the key will generate a self signed attestation.
+ */
+TEST_P(NewKeyGenerationTest, EcdsaSelfSignAttestation) {
+    for (auto key_size : ValidKeySizes(Algorithm::EC)) {
+        vector<uint8_t> key_blob;
+        vector<KeyCharacteristics> key_characteristics;
+        ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
+                                                     .EcdsaSigningKey(key_size)
+                                                     .Digest(Digest::NONE)
+                                                     .SetDefaultValidity(),
+                                             &key_blob, &key_characteristics));
+        ASSERT_GT(key_blob.size(), 0U);
+        CheckBaseParams(key_characteristics);
+
+        AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
+
+        EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::EC));
+        EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size))
+                << "Key size " << key_size << "missing";
+
+        EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
+        ASSERT_EQ(cert_chain_.size(), 1);
+
+        AuthorizationSet hw_enforced = HwEnforcedAuthorizations(key_characteristics);
+        AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics);
+
+        CheckedDeleteKey(&key_blob);
+    }
+}
+
+/*
+ * NewKeyGenerationTest.EcdsaAttestationRequireAppId
+ *
+ * Verifies that if attestation challenge is provided to Ecdsa key generation, then
+ * app id must also be provided or else it will fail.
+ */
+TEST_P(NewKeyGenerationTest, EcdsaAttestationRequireAppId) {
+    auto challenge = "hello";
+    vector<uint8_t> key_blob;
+    vector<KeyCharacteristics> key_characteristics;
+
+    ASSERT_EQ(ErrorCode::ATTESTATION_APPLICATION_ID_MISSING,
+              GenerateKey(AuthorizationSetBuilder()
+                                  .EcdsaSigningKey(EcCurve::P_256)
+                                  .Digest(Digest::NONE)
+                                  .AttestationChallenge(challenge)
+                                  .SetDefaultValidity(),
+                          &key_blob, &key_characteristics));
+}
+
+/*
+ * NewKeyGenerationTest.EcdsaIgnoreAppId
+ *
+ * Verifies that if no challenge is provided to the Ecdsa key generation, then
+ * any appid will be ignored, and keymint will generate a self sign certificate.
+ */
+TEST_P(NewKeyGenerationTest, EcdsaIgnoreAppId) {
+    auto app_id = "foo";
+
+    for (auto key_size : ValidKeySizes(Algorithm::EC)) {
+        vector<uint8_t> key_blob;
+        vector<KeyCharacteristics> key_characteristics;
+        ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
+                                                     .EcdsaSigningKey(key_size)
+                                                     .Digest(Digest::NONE)
+                                                     .AttestationApplicationId(app_id)
+                                                     .SetDefaultValidity(),
+                                             &key_blob, &key_characteristics));
+
+        ASSERT_GT(key_blob.size(), 0U);
+        CheckBaseParams(key_characteristics);
+
+        AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
+
+        EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::EC));
+        EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size))
+                << "Key size " << key_size << "missing";
+
+        EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
+        ASSERT_EQ(cert_chain_.size(), 1);
+
+        AuthorizationSet hw_enforced = HwEnforcedAuthorizations(key_characteristics);
+        AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics);
+
+        CheckedDeleteKey(&key_blob);
+    }
+}
+
+/*
+ * NewKeyGenerationTest.AttestationApplicationIDLengthProperlyEncoded
+ *
+ * Verifies that the Attestation Application ID software enforced tag has a proper length encoding.
+ * Some implementations break strict encoding rules by encoding a length between 127 and 256 in one
+ * byte. Proper DER encoding specifies that for lengths greater than 127, one byte should be used
+ * to specify how many following bytes will be used to encode the length.
+ */
+TEST_P(NewKeyGenerationTest, AttestationApplicationIDLengthProperlyEncoded) {
+    auto challenge = "hello";
+    auto key_size = 256;
+    std::vector<uint32_t> app_id_lengths{143, 258};
+
+    for (uint32_t length : app_id_lengths) {
+        const string app_id(length, 'a');
+        vector<uint8_t> key_blob;
+        vector<KeyCharacteristics> key_characteristics;
+        ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
+                                                     .Authorization(TAG_NO_AUTH_REQUIRED)
+                                                     .EcdsaSigningKey(key_size)
+                                                     .Digest(Digest::NONE)
+                                                     .AttestationChallenge(challenge)
+                                                     .AttestationApplicationId(app_id)
+                                                     .SetDefaultValidity(),
+                                             &key_blob, &key_characteristics));
+        ASSERT_GT(key_blob.size(), 0U);
+        CheckBaseParams(key_characteristics);
+
+        AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
+
+        EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::EC));
+        EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size))
+                << "Key size " << key_size << "missing";
+
+        EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
+        ASSERT_GT(cert_chain_.size(), 0);
+
+        AuthorizationSet hw_enforced = HwEnforcedAuthorizations(key_characteristics);
+        AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics);
+        EXPECT_TRUE(verify_attestation_record(challenge, app_id,  //
+                                              sw_enforced, hw_enforced, SecLevel(),
+                                              cert_chain_[0].encodedCertificate));
+
+        CheckedDeleteKey(&key_blob);
+    }
+}
+
+/*
  * NewKeyGenerationTest.LimitedUsageEcdsa
  *
  * Verifies that KeyMint can generate all required EC key sizes with limited usage, and that the
@@ -789,6 +1128,41 @@
 }
 
 /*
+ * NewKeyGenerationTest.HmacNoAttestation
+ *
+ * Verifies that for Hmac key generation, no attestation will be generated even if challenge
+ * and app id are provided.
+ */
+TEST_P(NewKeyGenerationTest, HmacNoAttestation) {
+    auto challenge = "hello";
+    auto app_id = "foo";
+
+    for (auto digest : ValidDigests(false /* withNone */, true /* withMD5 */)) {
+        vector<uint8_t> key_blob;
+        vector<KeyCharacteristics> key_characteristics;
+        constexpr size_t key_size = 128;
+        ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
+                                                     .HmacKey(key_size)
+                                                     .Digest(digest)
+                                                     .AttestationChallenge(challenge)
+                                                     .AttestationApplicationId(app_id)
+                                                     .Authorization(TAG_MIN_MAC_LENGTH, 128),
+                                             &key_blob, &key_characteristics));
+
+        ASSERT_GT(key_blob.size(), 0U);
+        ASSERT_EQ(cert_chain_.size(), 0);
+        CheckBaseParams(key_characteristics);
+
+        AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
+        EXPECT_TRUE(crypto_params.Contains(TAG_ALGORITHM, Algorithm::HMAC));
+        EXPECT_TRUE(crypto_params.Contains(TAG_KEY_SIZE, key_size))
+                << "Key size " << key_size << "missing";
+
+        CheckedDeleteKey(&key_blob);
+    }
+}
+
+/*
  * NewKeyGenerationTest.LimitedUsageHmac
  *
  * Verifies that KeyMint supports all required digests with limited usage Hmac, and that the
@@ -922,6 +1296,47 @@
                                   .Authorization(TAG_MIN_MAC_LENGTH, 128)));
 }
 
+/*
+ * NewKeyGenerationTest.AesNoAttestation
+ *
+ * Verifies that attestation parameters to AES keys are ignored and generateKey
+ * will succeed.
+ */
+TEST_P(NewKeyGenerationTest, AesNoAttestation) {
+    auto challenge = "hello";
+    auto app_id = "foo";
+
+    ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
+                                                 .Authorization(TAG_NO_AUTH_REQUIRED)
+                                                 .AesEncryptionKey(128)
+                                                 .EcbMode()
+                                                 .Padding(PaddingMode::PKCS7)
+                                                 .AttestationChallenge(challenge)
+                                                 .AttestationApplicationId(app_id)));
+
+    ASSERT_EQ(cert_chain_.size(), 0);
+}
+
+/*
+ * NewKeyGenerationTest.TripleDesNoAttestation
+ *
+ * Verifies that attesting parameters to 3DES keys are ignored and generate key
+ * will be successful.  No attestation should be generated.
+ */
+TEST_P(NewKeyGenerationTest, TripleDesNoAttestation) {
+    auto challenge = "hello";
+    auto app_id = "foo";
+
+    ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
+                                                 .TripleDesEncryptionKey(168)
+                                                 .BlockMode(BlockMode::ECB)
+                                                 .Authorization(TAG_NO_AUTH_REQUIRED)
+                                                 .Padding(PaddingMode::NONE)
+                                                 .AttestationChallenge(challenge)
+                                                 .AttestationApplicationId(app_id)));
+    ASSERT_EQ(cert_chain_.size(), 0);
+}
+
 INSTANTIATE_KEYMINT_AIDL_TEST(NewKeyGenerationTest);
 
 typedef KeyMintAidlTestBase SigningOperationsTest;
diff --git a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp b/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
index 9e52b20..a2071c2 100644
--- a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
+++ b/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
@@ -16,13 +16,13 @@
 
 #define LOG_TAG "VtsRemotelyProvisionableComponentTests"
 
-#include <RemotelyProvisionedComponent.h>
+#include <AndroidRemotelyProvisionedComponentDevice.h>
 #include <aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.h>
 #include <aidl/android/hardware/security/keymint/SecurityLevel.h>
 #include <android/binder_manager.h>
 #include <cppbor_parse.h>
-#include <cppcose/cppcose.h>
 #include <gmock/gmock.h>
+#include <keymaster/cppcose/cppcose.h>
 #include <keymaster/keymaster_configuration.h>
 #include <keymint_support/authorization_set.h>
 #include <openssl/ec.h>
diff --git a/security/keymint/support/Android.bp b/security/keymint/support/Android.bp
index 4c4258b..718133a 100644
--- a/security/keymint/support/Android.bp
+++ b/security/keymint/support/Android.bp
@@ -57,25 +57,8 @@
         "include",
     ],
     shared_libs: [
-        "libcppcose",
         "libcppbor_external",
+        "libcppcose_rkp",
         "libcrypto",
     ],
 }
-
-cc_library {
-    name: "libcppcose",
-    vendor_available: true,
-    host_supported: true,
-    srcs: [
-        "cppcose.cpp",
-    ],
-    export_include_dirs: [
-        "include",
-    ],
-    shared_libs: [
-        "libcppbor_external",
-        "libcrypto",
-        "liblog",
-    ],
-}
diff --git a/security/keymint/support/cppcose.cpp b/security/keymint/support/cppcose.cpp
deleted file mode 100644
index bafb2b6..0000000
--- a/security/keymint/support/cppcose.cpp
+++ /dev/null
@@ -1,467 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <cppcose/cppcose.h>
-
-#include <stdio.h>
-#include <iostream>
-
-#include <cppbor.h>
-#include <cppbor_parse.h>
-
-#include <openssl/err.h>
-
-namespace cppcose {
-
-namespace {
-
-ErrMsgOr<bssl::UniquePtr<EVP_CIPHER_CTX>> aesGcmInitAndProcessAad(const bytevec& key,
-                                                                  const bytevec& nonce,
-                                                                  const bytevec& aad,
-                                                                  bool encrypt) {
-    if (key.size() != kAesGcmKeySize) return "Invalid key size";
-
-    bssl::UniquePtr<EVP_CIPHER_CTX> ctx(EVP_CIPHER_CTX_new());
-    if (!ctx) return "Failed to allocate cipher context";
-
-    if (!EVP_CipherInit_ex(ctx.get(), EVP_aes_256_gcm(), nullptr /* engine */, key.data(),
-                           nonce.data(), encrypt ? 1 : 0)) {
-        return "Failed to initialize cipher";
-    }
-
-    int outlen;
-    if (!aad.empty() && !EVP_CipherUpdate(ctx.get(), nullptr /* out; null means AAD */, &outlen,
-                                          aad.data(), aad.size())) {
-        return "Failed to process AAD";
-    }
-
-    return std::move(ctx);
-}
-
-}  // namespace
-
-ErrMsgOr<bytevec> generateCoseMac0Mac(const bytevec& macKey, const bytevec& externalAad,
-                                      const bytevec& payload) {
-    auto macStructure = cppbor::Array()
-                                .add("MAC0")
-                                .add(cppbor::Map().add(ALGORITHM, HMAC_256).canonicalize().encode())
-                                .add(externalAad)
-                                .add(payload)
-                                .encode();
-
-    bytevec macTag(SHA256_DIGEST_LENGTH);
-    uint8_t* out = macTag.data();
-    unsigned int outLen;
-    out = HMAC(EVP_sha256(),                              //
-               macKey.data(), macKey.size(),              //
-               macStructure.data(), macStructure.size(),  //
-               out, &outLen);
-
-    assert(out != nullptr && outLen == macTag.size());
-    if (out == nullptr || outLen != macTag.size()) {
-        return "Error computing public key MAC";
-    }
-
-    return macTag;
-}
-
-ErrMsgOr<cppbor::Array> constructCoseMac0(const bytevec& macKey, const bytevec& externalAad,
-                                          const bytevec& payload) {
-    auto tag = generateCoseMac0Mac(macKey, externalAad, payload);
-    if (!tag) return tag.moveMessage();
-
-    return cppbor::Array()
-            .add(cppbor::Map().add(ALGORITHM, HMAC_256).canonicalize().encode())
-            .add(cppbor::Map() /* unprotected */)
-            .add(payload)
-            .add(tag.moveValue());
-}
-
-ErrMsgOr<bytevec /* payload */> parseCoseMac0(const cppbor::Item* macItem) {
-    auto mac = macItem ? macItem->asArray() : nullptr;
-    if (!mac || mac->size() != kCoseMac0EntryCount) {
-        return "Invalid COSE_Mac0";
-    }
-
-    auto protectedParms = mac->get(kCoseMac0ProtectedParams)->asBstr();
-    auto unprotectedParms = mac->get(kCoseMac0UnprotectedParams)->asMap();
-    auto payload = mac->get(kCoseMac0Payload)->asBstr();
-    auto tag = mac->get(kCoseMac0Tag)->asBstr();
-    if (!protectedParms || !unprotectedParms || !payload || !tag) {
-        return "Invalid COSE_Mac0 contents";
-    }
-
-    return payload->value();
-}
-
-ErrMsgOr<bytevec /* payload */> verifyAndParseCoseMac0(const cppbor::Item* macItem,
-                                                       const bytevec& macKey) {
-    auto mac = macItem ? macItem->asArray() : nullptr;
-    if (!mac || mac->size() != kCoseMac0EntryCount) {
-        return "Invalid COSE_Mac0";
-    }
-
-    auto protectedParms = mac->get(kCoseMac0ProtectedParams)->asBstr();
-    auto unprotectedParms = mac->get(kCoseMac0UnprotectedParams)->asMap();
-    auto payload = mac->get(kCoseMac0Payload)->asBstr();
-    auto tag = mac->get(kCoseMac0Tag)->asBstr();
-    if (!protectedParms || !unprotectedParms || !payload || !tag) {
-        return "Invalid COSE_Mac0 contents";
-    }
-
-    auto [protectedMap, _, errMsg] = cppbor::parse(protectedParms);
-    if (!protectedMap || !protectedMap->asMap()) {
-        return "Invalid Mac0 protected: " + errMsg;
-    }
-    auto& algo = protectedMap->asMap()->get(ALGORITHM);
-    if (!algo || !algo->asInt() || algo->asInt()->value() != HMAC_256) {
-        return "Unsupported Mac0 algorithm";
-    }
-
-    auto macTag = generateCoseMac0Mac(macKey, {} /* external_aad */, payload->value());
-    if (!macTag) return macTag.moveMessage();
-
-    if (macTag->size() != tag->value().size() ||
-        CRYPTO_memcmp(macTag->data(), tag->value().data(), macTag->size()) != 0) {
-        return "MAC tag mismatch";
-    }
-
-    return payload->value();
-}
-
-ErrMsgOr<bytevec> createCoseSign1Signature(const bytevec& key, const bytevec& protectedParams,
-                                           const bytevec& payload, const bytevec& aad) {
-    bytevec signatureInput = cppbor::Array()
-                                     .add("Signature1")  //
-                                     .add(protectedParams)
-                                     .add(aad)
-                                     .add(payload)
-                                     .encode();
-
-    if (key.size() != ED25519_PRIVATE_KEY_LEN) return "Invalid signing key";
-    bytevec signature(ED25519_SIGNATURE_LEN);
-    if (!ED25519_sign(signature.data(), signatureInput.data(), signatureInput.size(), key.data())) {
-        return "Signing failed";
-    }
-
-    return signature;
-}
-
-ErrMsgOr<cppbor::Array> constructCoseSign1(const bytevec& key, cppbor::Map protectedParams,
-                                           const bytevec& payload, const bytevec& aad) {
-    bytevec protParms = protectedParams.add(ALGORITHM, EDDSA).canonicalize().encode();
-    auto signature = createCoseSign1Signature(key, protParms, payload, aad);
-    if (!signature) return signature.moveMessage();
-
-    return cppbor::Array()
-            .add(protParms)
-            .add(cppbor::Map() /* unprotected parameters */)
-            .add(payload)
-            .add(*signature);
-}
-
-ErrMsgOr<cppbor::Array> constructCoseSign1(const bytevec& key, const bytevec& payload,
-                                           const bytevec& aad) {
-    return constructCoseSign1(key, {} /* protectedParams */, payload, aad);
-}
-
-ErrMsgOr<bytevec> verifyAndParseCoseSign1(bool ignoreSignature, const cppbor::Array* coseSign1,
-                                          const bytevec& signingCoseKey, const bytevec& aad) {
-    if (!coseSign1 || coseSign1->size() != kCoseSign1EntryCount) {
-        return "Invalid COSE_Sign1";
-    }
-
-    const cppbor::Bstr* protectedParams = coseSign1->get(kCoseSign1ProtectedParams)->asBstr();
-    const cppbor::Map* unprotectedParams = coseSign1->get(kCoseSign1UnprotectedParams)->asMap();
-    const cppbor::Bstr* payload = coseSign1->get(kCoseSign1Payload)->asBstr();
-    const cppbor::Bstr* signature = coseSign1->get(kCoseSign1Signature)->asBstr();
-
-    if (!protectedParams || !unprotectedParams || !payload || !signature) {
-        return "Invalid COSE_Sign1";
-    }
-
-    auto [parsedProtParams, _, errMsg] = cppbor::parse(protectedParams);
-    if (!parsedProtParams) {
-        return errMsg + " when parsing protected params.";
-    }
-    if (!parsedProtParams->asMap()) {
-        return "Protected params must be a map";
-    }
-
-    auto& algorithm = parsedProtParams->asMap()->get(ALGORITHM);
-    if (!algorithm || !algorithm->asInt() || algorithm->asInt()->value() != EDDSA) {
-        return "Unsupported signature algorithm";
-    }
-
-    if (!ignoreSignature) {
-        bool selfSigned = signingCoseKey.empty();
-        auto key = CoseKey::parseEd25519(selfSigned ? payload->value() : signingCoseKey);
-        if (!key) return "Bad signing key: " + key.moveMessage();
-
-        bytevec signatureInput = cppbor::Array()
-                                         .add("Signature1")
-                                         .add(*protectedParams)
-                                         .add(aad)
-                                         .add(*payload)
-                                         .encode();
-
-        if (!ED25519_verify(signatureInput.data(), signatureInput.size(), signature->value().data(),
-                            key->getBstrValue(CoseKey::PUBKEY_X)->data())) {
-            return "Signature verification failed";
-        }
-    }
-
-    return payload->value();
-}
-
-ErrMsgOr<bytevec> createCoseEncryptCiphertext(const bytevec& key, const bytevec& nonce,
-                                              const bytevec& protectedParams,
-                                              const bytevec& plaintextPayload, const bytevec& aad) {
-    auto ciphertext = aesGcmEncrypt(key, nonce,
-                                    cppbor::Array()                // Enc strucure as AAD
-                                            .add("Encrypt")        // Context
-                                            .add(protectedParams)  // Protected
-                                            .add(aad)              // External AAD
-                                            .encode(),
-                                    plaintextPayload);
-
-    if (!ciphertext) return ciphertext.moveMessage();
-    return ciphertext.moveValue();
-}
-
-ErrMsgOr<cppbor::Array> constructCoseEncrypt(const bytevec& key, const bytevec& nonce,
-                                             const bytevec& plaintextPayload, const bytevec& aad,
-                                             cppbor::Array recipients) {
-    auto encryptProtectedHeader = cppbor::Map()  //
-                                          .add(ALGORITHM, AES_GCM_256)
-                                          .canonicalize()
-                                          .encode();
-
-    auto ciphertext =
-            createCoseEncryptCiphertext(key, nonce, encryptProtectedHeader, plaintextPayload, aad);
-    if (!ciphertext) return ciphertext.moveMessage();
-
-    return cppbor::Array()
-            .add(encryptProtectedHeader)                       // Protected
-            .add(cppbor::Map().add(IV, nonce).canonicalize())  // Unprotected
-            .add(*ciphertext)                                  // Payload
-            .add(std::move(recipients));
-}
-
-ErrMsgOr<std::pair<bytevec /* pubkey */, bytevec /* key ID */>> getSenderPubKeyFromCoseEncrypt(
-        const cppbor::Item* coseEncrypt) {
-    if (!coseEncrypt || !coseEncrypt->asArray() ||
-        coseEncrypt->asArray()->size() != kCoseEncryptEntryCount) {
-        return "Invalid COSE_Encrypt";
-    }
-
-    auto& recipients = coseEncrypt->asArray()->get(kCoseEncryptRecipients);
-    if (!recipients || !recipients->asArray() || recipients->asArray()->size() != 1) {
-        return "Invalid recipients list";
-    }
-
-    auto& recipient = recipients->asArray()->get(0);
-    if (!recipient || !recipient->asArray() || recipient->asArray()->size() != 3) {
-        return "Invalid COSE_recipient";
-    }
-
-    auto& ciphertext = recipient->asArray()->get(2);
-    if (!ciphertext->asSimple() || !ciphertext->asSimple()->asNull()) {
-        return "Unexpected value in recipients ciphertext field " +
-               cppbor::prettyPrint(ciphertext.get());
-    }
-
-    auto& protParms = recipient->asArray()->get(0);
-    if (!protParms || !protParms->asBstr()) return "Invalid protected params";
-    auto [parsedProtParms, _, errMsg] = cppbor::parse(protParms->asBstr());
-    if (!parsedProtParms) return "Failed to parse protected params: " + errMsg;
-    if (!parsedProtParms->asMap()) return "Invalid protected params";
-
-    auto& algorithm = parsedProtParms->asMap()->get(ALGORITHM);
-    if (!algorithm || !algorithm->asInt() || algorithm->asInt()->value() != ECDH_ES_HKDF_256) {
-        return "Invalid algorithm";
-    }
-
-    auto& unprotParms = recipient->asArray()->get(1);
-    if (!unprotParms || !unprotParms->asMap()) return "Invalid unprotected params";
-
-    auto& senderCoseKey = unprotParms->asMap()->get(COSE_KEY);
-    if (!senderCoseKey || !senderCoseKey->asMap()) return "Invalid sender COSE_Key";
-
-    auto& keyType = senderCoseKey->asMap()->get(CoseKey::KEY_TYPE);
-    if (!keyType || !keyType->asInt() || keyType->asInt()->value() != OCTET_KEY_PAIR) {
-        return "Invalid key type";
-    }
-
-    auto& curve = senderCoseKey->asMap()->get(CoseKey::CURVE);
-    if (!curve || !curve->asInt() || curve->asInt()->value() != X25519) {
-        return "Unsupported curve";
-    }
-
-    auto& pubkey = senderCoseKey->asMap()->get(CoseKey::PUBKEY_X);
-    if (!pubkey || !pubkey->asBstr() ||
-        pubkey->asBstr()->value().size() != X25519_PUBLIC_VALUE_LEN) {
-        return "Invalid X25519 public key";
-    }
-
-    auto& key_id = unprotParms->asMap()->get(KEY_ID);
-    if (key_id && key_id->asBstr()) {
-        return std::make_pair(pubkey->asBstr()->value(), key_id->asBstr()->value());
-    }
-
-    // If no key ID, just return an empty vector.
-    return std::make_pair(pubkey->asBstr()->value(), bytevec{});
-}
-
-ErrMsgOr<bytevec> decryptCoseEncrypt(const bytevec& key, const cppbor::Item* coseEncrypt,
-                                     const bytevec& external_aad) {
-    if (!coseEncrypt || !coseEncrypt->asArray() ||
-        coseEncrypt->asArray()->size() != kCoseEncryptEntryCount) {
-        return "Invalid COSE_Encrypt";
-    }
-
-    auto& protParms = coseEncrypt->asArray()->get(kCoseEncryptProtectedParams);
-    auto& unprotParms = coseEncrypt->asArray()->get(kCoseEncryptUnprotectedParams);
-    auto& ciphertext = coseEncrypt->asArray()->get(kCoseEncryptPayload);
-    auto& recipients = coseEncrypt->asArray()->get(kCoseEncryptRecipients);
-
-    if (!protParms || !protParms->asBstr() || !unprotParms || !ciphertext || !recipients) {
-        return "Invalid COSE_Encrypt";
-    }
-
-    auto [parsedProtParams, _, errMsg] = cppbor::parse(protParms->asBstr()->value());
-    if (!parsedProtParams) {
-        return errMsg + " when parsing protected params.";
-    }
-    if (!parsedProtParams->asMap()) {
-        return "Protected params must be a map";
-    }
-
-    auto& algorithm = parsedProtParams->asMap()->get(ALGORITHM);
-    if (!algorithm || !algorithm->asInt() || algorithm->asInt()->value() != AES_GCM_256) {
-        return "Unsupported encryption algorithm";
-    }
-
-    if (!unprotParms->asMap() || unprotParms->asMap()->size() != 1) {
-        return "Invalid unprotected params";
-    }
-
-    auto& nonce = unprotParms->asMap()->get(IV);
-    if (!nonce || !nonce->asBstr() || nonce->asBstr()->value().size() != kAesGcmNonceLength) {
-        return "Invalid nonce";
-    }
-
-    if (!ciphertext->asBstr()) return "Invalid ciphertext";
-
-    auto aad = cppbor::Array()                             // Enc strucure as AAD
-                       .add("Encrypt")                     // Context
-                       .add(protParms->asBstr()->value())  // Protected
-                       .add(external_aad)                  // External AAD
-                       .encode();
-
-    return aesGcmDecrypt(key, nonce->asBstr()->value(), aad, ciphertext->asBstr()->value());
-}
-
-ErrMsgOr<bytevec> x25519_HKDF_DeriveKey(const bytevec& pubKeyA, const bytevec& privKeyA,
-                                        const bytevec& pubKeyB, bool senderIsA) {
-    bytevec rawSharedKey(X25519_SHARED_KEY_LEN);
-    if (!::X25519(rawSharedKey.data(), privKeyA.data(), pubKeyB.data())) {
-        return "ECDH operation failed";
-    }
-
-    bytevec kdfContext = cppbor::Array()
-                                 .add(AES_GCM_256)
-                                 .add(cppbor::Array()  // Sender Info
-                                              .add(cppbor::Bstr("client"))
-                                              .add(bytevec{} /* nonce */)
-                                              .add(senderIsA ? pubKeyA : pubKeyB))
-                                 .add(cppbor::Array()  // Recipient Info
-                                              .add(cppbor::Bstr("server"))
-                                              .add(bytevec{} /* nonce */)
-                                              .add(senderIsA ? pubKeyB : pubKeyA))
-                                 .add(cppbor::Array()           // SuppPubInfo
-                                              .add(128)         // output key length
-                                              .add(bytevec{}))  // protected
-                                 .encode();
-
-    bytevec retval(SHA256_DIGEST_LENGTH);
-    bytevec salt{};
-    if (!HKDF(retval.data(), retval.size(),              //
-              EVP_sha256(),                              //
-              rawSharedKey.data(), rawSharedKey.size(),  //
-              salt.data(), salt.size(),                  //
-              kdfContext.data(), kdfContext.size())) {
-        return "ECDH HKDF failed";
-    }
-
-    return retval;
-}
-
-ErrMsgOr<bytevec> aesGcmEncrypt(const bytevec& key, const bytevec& nonce, const bytevec& aad,
-                                const bytevec& plaintext) {
-    auto ctx = aesGcmInitAndProcessAad(key, nonce, aad, true /* encrypt */);
-    if (!ctx) return ctx.moveMessage();
-
-    bytevec ciphertext(plaintext.size() + kAesGcmTagSize);
-    int outlen;
-    if (!EVP_CipherUpdate(ctx->get(), ciphertext.data(), &outlen, plaintext.data(),
-                          plaintext.size())) {
-        return "Failed to encrypt plaintext";
-    }
-    assert(plaintext.size() == outlen);
-
-    if (!EVP_CipherFinal_ex(ctx->get(), ciphertext.data() + outlen, &outlen)) {
-        return "Failed to finalize encryption";
-    }
-    assert(outlen == 0);
-
-    if (!EVP_CIPHER_CTX_ctrl(ctx->get(), EVP_CTRL_GCM_GET_TAG, kAesGcmTagSize,
-                             ciphertext.data() + plaintext.size())) {
-        return "Failed to retrieve tag";
-    }
-
-    return ciphertext;
-}
-
-ErrMsgOr<bytevec> aesGcmDecrypt(const bytevec& key, const bytevec& nonce, const bytevec& aad,
-                                const bytevec& ciphertextWithTag) {
-    auto ctx = aesGcmInitAndProcessAad(key, nonce, aad, false /* encrypt */);
-    if (!ctx) return ctx.moveMessage();
-
-    if (ciphertextWithTag.size() < kAesGcmTagSize) return "Missing tag";
-
-    bytevec plaintext(ciphertextWithTag.size() - kAesGcmTagSize);
-    int outlen;
-    if (!EVP_CipherUpdate(ctx->get(), plaintext.data(), &outlen, ciphertextWithTag.data(),
-                          ciphertextWithTag.size() - kAesGcmTagSize)) {
-        return "Failed to decrypt plaintext";
-    }
-    assert(plaintext.size() == outlen);
-
-    bytevec tag(ciphertextWithTag.end() - kAesGcmTagSize, ciphertextWithTag.end());
-    if (!EVP_CIPHER_CTX_ctrl(ctx->get(), EVP_CTRL_GCM_SET_TAG, kAesGcmTagSize, tag.data())) {
-        return "Failed to set tag: " + std::to_string(ERR_peek_last_error());
-    }
-
-    if (!EVP_CipherFinal_ex(ctx->get(), nullptr, &outlen)) {
-        return "Failed to finalize encryption";
-    }
-    assert(outlen == 0);
-
-    return plaintext;
-}
-
-}  // namespace cppcose
diff --git a/security/keymint/support/include/cppcose/cppcose.h b/security/keymint/support/include/cppcose/cppcose.h
deleted file mode 100644
index a936bfd..0000000
--- a/security/keymint/support/include/cppcose/cppcose.h
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <memory>
-#include <optional>
-#include <string>
-#include <vector>
-
-#include <cppbor.h>
-#include <cppbor_parse.h>
-
-#include <openssl/cipher.h>
-#include <openssl/curve25519.h>
-#include <openssl/digest.h>
-#include <openssl/hkdf.h>
-#include <openssl/hmac.h>
-#include <openssl/mem.h>
-#include <openssl/sha.h>
-
-namespace cppcose {
-
-using bytevec = std::vector<uint8_t>;
-
-constexpr int kCoseSign1EntryCount = 4;
-constexpr int kCoseSign1ProtectedParams = 0;
-constexpr int kCoseSign1UnprotectedParams = 1;
-constexpr int kCoseSign1Payload = 2;
-constexpr int kCoseSign1Signature = 3;
-
-constexpr int kCoseMac0EntryCount = 4;
-constexpr int kCoseMac0ProtectedParams = 0;
-constexpr int kCoseMac0UnprotectedParams = 1;
-constexpr int kCoseMac0Payload = 2;
-constexpr int kCoseMac0Tag = 3;
-
-constexpr int kCoseEncryptEntryCount = 4;
-constexpr int kCoseEncryptProtectedParams = 0;
-constexpr int kCoseEncryptUnprotectedParams = 1;
-constexpr int kCoseEncryptPayload = 2;
-constexpr int kCoseEncryptRecipients = 3;
-
-enum Label : int {
-    ALGORITHM = 1,
-    KEY_ID = 4,
-    IV = 5,
-    COSE_KEY = -1,
-};
-
-enum CoseKeyAlgorithm : int {
-    AES_GCM_256 = 3,
-    HMAC_256 = 5,
-    ES256 = -7,  // ECDSA with SHA-256
-    EDDSA = -8,
-    ECDH_ES_HKDF_256 = -25,
-};
-
-enum CoseKeyCurve : int { P256 = 1, X25519 = 4, ED25519 = 6 };
-enum CoseKeyType : int { OCTET_KEY_PAIR = 1, EC2 = 2, SYMMETRIC_KEY = 4 };
-enum CoseKeyOps : int { SIGN = 1, VERIFY = 2, ENCRYPT = 3, DECRYPT = 4 };
-
-constexpr int kAesGcmNonceLength = 12;
-constexpr int kAesGcmTagSize = 16;
-constexpr int kAesGcmKeySize = 32;
-
-template <typename T>
-class ErrMsgOr {
-  public:
-    ErrMsgOr(std::string errMsg) : errMsg_(std::move(errMsg)) {}
-    ErrMsgOr(const char* errMsg) : errMsg_(errMsg) {}
-    ErrMsgOr(T val) : value_(std::move(val)) {}
-
-    operator bool() const { return value_.has_value(); }
-
-    T* operator->() & {
-        assert(value_);
-        return &value_.value();
-    }
-    T& operator*() & {
-        assert(value_);
-        return value_.value();
-    };
-    T&& operator*() && {
-        assert(value_);
-        return std::move(value_).value();
-    };
-
-    const std::string& message() { return errMsg_; }
-    std::string moveMessage() { return std::move(errMsg_); }
-
-    T moveValue() {
-        assert(value_);
-        return std::move(value_).value();
-    }
-
-  private:
-    std::string errMsg_;
-    std::optional<T> value_;
-};
-
-class CoseKey {
-  public:
-    CoseKey() {}
-    CoseKey(const CoseKey&) = delete;
-    CoseKey(CoseKey&&) = default;
-
-    enum Label : int {
-        KEY_TYPE = 1,
-        KEY_ID = 2,
-        ALGORITHM = 3,
-        KEY_OPS = 4,
-        CURVE = -1,
-        PUBKEY_X = -2,
-        PUBKEY_Y = -3,
-        PRIVATE_KEY = -4,
-        TEST_KEY = -70000  // Application-defined
-    };
-
-    static ErrMsgOr<CoseKey> parse(const bytevec& coseKey) {
-        auto [parsedKey, _, errMsg] = cppbor::parse(coseKey);
-        if (!parsedKey) return errMsg + " when parsing key";
-        if (!parsedKey->asMap()) return "CoseKey must be a map";
-        return CoseKey(static_cast<cppbor::Map*>(parsedKey.release()));
-    }
-
-    static ErrMsgOr<CoseKey> parse(const bytevec& coseKey, CoseKeyType expectedKeyType,
-                                   CoseKeyAlgorithm expectedAlgorithm, CoseKeyCurve expectedCurve) {
-        auto key = parse(coseKey);
-        if (!key) return key;
-
-        if (!key->checkIntValue(CoseKey::KEY_TYPE, expectedKeyType) ||
-            !key->checkIntValue(CoseKey::ALGORITHM, expectedAlgorithm) ||
-            !key->checkIntValue(CoseKey::CURVE, expectedCurve)) {
-            return "Unexpected key type:";
-        }
-
-        return key;
-    }
-
-    static ErrMsgOr<CoseKey> parseEd25519(const bytevec& coseKey) {
-        auto key = parse(coseKey, OCTET_KEY_PAIR, EDDSA, ED25519);
-        if (!key) return key;
-
-        auto& pubkey = key->getMap().get(PUBKEY_X);
-        if (!pubkey || !pubkey->asBstr() ||
-            pubkey->asBstr()->value().size() != ED25519_PUBLIC_KEY_LEN) {
-            return "Invalid Ed25519 public key";
-        }
-
-        return key;
-    }
-
-    static ErrMsgOr<CoseKey> parseX25519(const bytevec& coseKey, bool requireKid) {
-        auto key = parse(coseKey, OCTET_KEY_PAIR, ECDH_ES_HKDF_256, X25519);
-        if (!key) return key;
-
-        auto& pubkey = key->getMap().get(PUBKEY_X);
-        if (!pubkey || !pubkey->asBstr() ||
-            pubkey->asBstr()->value().size() != X25519_PUBLIC_VALUE_LEN) {
-            return "Invalid X25519 public key";
-        }
-
-        auto& kid = key->getMap().get(KEY_ID);
-        if (requireKid && (!kid || !kid->asBstr())) {
-            return "Missing KID";
-        }
-
-        return key;
-    }
-
-    static ErrMsgOr<CoseKey> parseP256(const bytevec& coseKey) {
-        auto key = parse(coseKey, EC2, ES256, P256);
-        if (!key) return key;
-
-        auto& pubkey_x = key->getMap().get(PUBKEY_X);
-        auto& pubkey_y = key->getMap().get(PUBKEY_Y);
-        if (!pubkey_x || !pubkey_y || !pubkey_x->asBstr() || !pubkey_y->asBstr() ||
-            pubkey_x->asBstr()->value().size() != 32 || pubkey_y->asBstr()->value().size() != 32) {
-            return "Invalid P256 public key";
-        }
-
-        return key;
-    }
-
-    std::optional<int> getIntValue(Label label) {
-        const auto& value = key_->get(label);
-        if (!value || !value->asInt()) return {};
-        return value->asInt()->value();
-    }
-
-    std::optional<bytevec> getBstrValue(Label label) {
-        const auto& value = key_->get(label);
-        if (!value || !value->asBstr()) return {};
-        return value->asBstr()->value();
-    }
-
-    const cppbor::Map& getMap() const { return *key_; }
-    cppbor::Map&& moveMap() { return std::move(*key_); }
-
-    bool checkIntValue(Label label, int expectedValue) {
-        const auto& value = key_->get(label);
-        return value && value->asInt() && value->asInt()->value() == expectedValue;
-    }
-
-    void add(Label label, int value) { key_->add(label, value); }
-    void add(Label label, bytevec value) { key_->add(label, std::move(value)); }
-
-    bytevec encode() { return key_->canonicalize().encode(); }
-
-  private:
-    CoseKey(cppbor::Map* parsedKey) : key_(parsedKey) {}
-
-    // This is the full parsed key structure.
-    std::unique_ptr<cppbor::Map> key_;
-};
-
-ErrMsgOr<bytevec> generateCoseMac0Mac(const bytevec& macKey, const bytevec& externalAad,
-                                      const bytevec& payload);
-ErrMsgOr<cppbor::Array> constructCoseMac0(const bytevec& macKey, const bytevec& externalAad,
-                                          const bytevec& payload);
-ErrMsgOr<bytevec /* payload */> parseCoseMac0(const cppbor::Item* macItem);
-ErrMsgOr<bytevec /* payload */> verifyAndParseCoseMac0(const cppbor::Item* macItem,
-                                                       const bytevec& macKey);
-
-ErrMsgOr<bytevec> createCoseSign1Signature(const bytevec& key, const bytevec& protectedParams,
-                                           const bytevec& payload, const bytevec& aad);
-ErrMsgOr<cppbor::Array> constructCoseSign1(const bytevec& key, const bytevec& payload,
-                                           const bytevec& aad);
-ErrMsgOr<cppbor::Array> constructCoseSign1(const bytevec& key, cppbor::Map extraProtectedFields,
-                                           const bytevec& payload, const bytevec& aad);
-/**
- * Verify and parse a COSE_Sign1 message, returning the payload.
- *
- * @param ignoreSignature indicates whether signature verification should be skipped.  If true, no
- *        verification of the signature will be done.
- *
- * @param coseSign1 is the COSE_Sign1 to verify and parse.
- *
- * @param signingCoseKey is a CBOR-encoded COSE_Key to use to verify the signature.  The bytevec may
- *        be empty, in which case the function assumes that coseSign1's payload is the COSE_Key to
- *        use, i.e. that coseSign1 is a self-signed "certificate".
- */
-ErrMsgOr<bytevec /* payload */> verifyAndParseCoseSign1(bool ignoreSignature,
-                                                        const cppbor::Array* coseSign1,
-                                                        const bytevec& signingCoseKey,
-                                                        const bytevec& aad);
-
-ErrMsgOr<bytevec> createCoseEncryptCiphertext(const bytevec& key, const bytevec& nonce,
-                                              const bytevec& protectedParams, const bytevec& aad);
-ErrMsgOr<cppbor::Array> constructCoseEncrypt(const bytevec& key, const bytevec& nonce,
-                                             const bytevec& plaintextPayload, const bytevec& aad,
-                                             cppbor::Array recipients);
-ErrMsgOr<std::pair<bytevec /* pubkey */, bytevec /* key ID */>> getSenderPubKeyFromCoseEncrypt(
-        const cppbor::Item* encryptItem);
-inline ErrMsgOr<std::pair<bytevec /* pubkey */, bytevec /* key ID */>>
-getSenderPubKeyFromCoseEncrypt(const std::unique_ptr<cppbor::Item>& encryptItem) {
-    return getSenderPubKeyFromCoseEncrypt(encryptItem.get());
-}
-
-ErrMsgOr<bytevec /* plaintextPayload */> decryptCoseEncrypt(const bytevec& key,
-                                                            const cppbor::Item* encryptItem,
-                                                            const bytevec& aad);
-
-ErrMsgOr<bytevec> x25519_HKDF_DeriveKey(const bytevec& senderPubKey, const bytevec& senderPrivKey,
-                                        const bytevec& recipientPubKey, bool senderIsA);
-
-ErrMsgOr<bytevec /* ciphertextWithTag */> aesGcmEncrypt(const bytevec& key, const bytevec& nonce,
-                                                        const bytevec& aad,
-                                                        const bytevec& plaintext);
-ErrMsgOr<bytevec /* plaintext */> aesGcmDecrypt(const bytevec& key, const bytevec& nonce,
-                                                const bytevec& aad,
-                                                const bytevec& ciphertextWithTag);
-
-}  // namespace cppcose
diff --git a/security/keymint/support/include/remote_prov/remote_prov_utils.h b/security/keymint/support/include/remote_prov/remote_prov_utils.h
index 5e205a2..e4261f3 100644
--- a/security/keymint/support/include/remote_prov/remote_prov_utils.h
+++ b/security/keymint/support/include/remote_prov/remote_prov_utils.h
@@ -18,7 +18,7 @@
 
 #include <vector>
 
-#include <cppcose/cppcose.h>
+#include <keymaster/cppcose/cppcose.h>
 
 namespace aidl::android::hardware::security::keymint::remote_prov {
 
diff --git a/tetheroffload/control/1.1/Android.bp b/tetheroffload/control/1.1/Android.bp
index e87ff5c..7871c2c 100644
--- a/tetheroffload/control/1.1/Android.bp
+++ b/tetheroffload/control/1.1/Android.bp
@@ -21,5 +21,9 @@
         "android.hardware.tetheroffload.control@1.0",
         "android.hidl.base@1.0",
     ],
+    apex_available: [
+        "//apex_available:platform", // Used by InProcessTethering
+        "com.android.tethering",
+    ],
     gen_java: true,
 }
diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h
index e240604..8358291 100644
--- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h
+++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h
@@ -32,7 +32,8 @@
 namespace {
 
 bool initConfiguration() {
-    if (!TunerTestingConfigReader::checkConfigFileExists()) {
+    TunerTestingConfigReader1_0::setConfigFilePath(configFilePath);
+    if (!TunerTestingConfigReader1_0::checkConfigFileExists()) {
         return false;
     }
     initFrontendConfig();
diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h
index 65f8615..a1597c7 100644
--- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h
+++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TestConfigurations.h
@@ -21,7 +21,7 @@
 #include <hidl/Status.h>
 #include <hidlmemory/FrameworkUtils.h>
 
-#include "../../../config/TunerTestingConfigReader.h"
+#include "../../../config/TunerTestingConfigReaderV1_0.h"
 
 using android::hardware::tv::tuner::V1_0::DemuxFilterMainType;
 using android::hardware::tv::tuner::V1_0::DemuxTsFilterType;
@@ -39,6 +39,8 @@
 const uint32_t FMQ_SIZE_4M = 0x400000;
 const uint32_t FMQ_SIZE_16M = 0x1000000;
 
+const string configFilePath = "/vendor/etc/tuner_vts_config_1_0.xml";
+
 #define FILTER_MAIN_TYPE_BIT_COUNT 5
 
 // Hardware configs
@@ -85,7 +87,7 @@
     frontendMap[defaultFeId].isSoftwareFe = true;
 
     // Read customized config
-    TunerTestingConfigReader::readFrontendConfig1_0(frontendMap);
+    TunerTestingConfigReader1_0::readFrontendConfig1_0(frontendMap);
 };
 
 inline void initFilterConfig() {
@@ -107,44 +109,44 @@
     filterMap[defaultAudioFilterId].settings.ts().filterSettings.av({.isPassthrough = false});
 
     // Read customized config
-    TunerTestingConfigReader::readFilterConfig1_0(filterMap);
+    TunerTestingConfigReader1_0::readFilterConfig1_0(filterMap);
 };
 
 /** Config all the dvrs that would be used in the tests */
 inline void initDvrConfig() {
     // Read customized config
-    TunerTestingConfigReader::readDvrConfig1_0(dvrMap);
+    TunerTestingConfigReader1_0::readDvrConfig1_0(dvrMap);
 };
 
 /** Config all the lnbs that would be used in the tests */
 inline void initLnbConfig() {
     // Read customized config
-    TunerTestingConfigReader::readLnbConfig1_0(lnbMap);
-    TunerTestingConfigReader::readDiseqcMessages(diseqcMsgMap);
+    TunerTestingConfigReader1_0::readLnbConfig1_0(lnbMap);
+    TunerTestingConfigReader1_0::readDiseqcMessages(diseqcMsgMap);
 };
 
 /** Config all the time filters that would be used in the tests */
 inline void initTimeFilterConfig() {
     // Read customized config
-    TunerTestingConfigReader::readTimeFilterConfig1_0(timeFilterMap);
+    TunerTestingConfigReader1_0::readTimeFilterConfig1_0(timeFilterMap);
 };
 
 /** Config all the descramblers that would be used in the tests */
 inline void initDescramblerConfig() {
     // Read customized config
-    TunerTestingConfigReader::readDescramblerConfig1_0(descramblerMap);
+    TunerTestingConfigReader1_0::readDescramblerConfig1_0(descramblerMap);
 };
 
 /** Read the vendor configurations of which hardware to use for each test cases/data flows */
 inline void connectHardwaresToTestCases() {
-    TunerTestingConfigReader::connectLiveBroadcast(live);
-    TunerTestingConfigReader::connectScan(scan);
-    TunerTestingConfigReader::connectDvrPlayback(playback);
-    TunerTestingConfigReader::connectDvrRecord(record);
-    TunerTestingConfigReader::connectDescrambling(descrambling);
-    TunerTestingConfigReader::connectLnbLive(lnbLive);
-    TunerTestingConfigReader::connectLnbRecord(lnbRecord);
-    TunerTestingConfigReader::connectTimeFilter(timeFilter);
+    TunerTestingConfigReader1_0::connectLiveBroadcast(live);
+    TunerTestingConfigReader1_0::connectScan(scan);
+    TunerTestingConfigReader1_0::connectDvrPlayback(playback);
+    TunerTestingConfigReader1_0::connectDvrRecord(record);
+    TunerTestingConfigReader1_0::connectDescrambling(descrambling);
+    TunerTestingConfigReader1_0::connectLnbLive(lnbLive);
+    TunerTestingConfigReader1_0::connectLnbRecord(lnbRecord);
+    TunerTestingConfigReader1_0::connectTimeFilter(timeFilter);
 };
 
 inline bool validateConnections() {
diff --git a/tv/tuner/1.1/vts/functional/Android.bp b/tv/tuner/1.1/vts/functional/Android.bp
index 92e587b..ac835a4 100644
--- a/tv/tuner/1.1/vts/functional/Android.bp
+++ b/tv/tuner/1.1/vts/functional/Android.bp
@@ -33,6 +33,15 @@
         "FrontendTests.cpp",
         "VtsHalTvTunerV1_1TargetTest.cpp",
     ],
+    generated_headers: [
+        "tuner_testing_dynamic_configuration_V1_0_enums",
+        "tuner_testing_dynamic_configuration_V1_0_parser",
+    ],
+    generated_sources: [
+        "tuner_testing_dynamic_configuration_V1_0_enums",
+        "tuner_testing_dynamic_configuration_V1_0_parser",
+    ],
+    header_libs: ["libxsdc-utils"],
     static_libs: [
         "android.hardware.cas@1.0",
         "android.hardware.cas@1.1",
@@ -48,9 +57,12 @@
     ],
     shared_libs: [
         "libbinder",
+        "libxml2",
     ],
     data: [
+        ":tuner_frontend_input_ts",
         ":tuner_frontend_input_es",
+        ":tuner_testing_dynamic_configuration_V1_0",
     ],
     test_suites: [
         "general-tests",
diff --git a/tv/tuner/1.1/vts/functional/FrontendTests.cpp b/tv/tuner/1.1/vts/functional/FrontendTests.cpp
index 0fd5be0..9c575ff 100644
--- a/tv/tuner/1.1/vts/functional/FrontendTests.cpp
+++ b/tv/tuner/1.1/vts/functional/FrontendTests.cpp
@@ -121,7 +121,7 @@
     mLockMsgReceived = false;
 }
 
-void FrontendCallback::scanTest(sp<IFrontend>& frontend, FrontendConfig config,
+void FrontendCallback::scanTest(sp<IFrontend>& frontend, FrontendConfig1_1 config,
                                 FrontendScanType type) {
     sp<android::hardware::tv::tuner::V1_1::IFrontend> frontend_1_1;
     frontend_1_1 = android::hardware::tv::tuner::V1_1::IFrontend::castFrom(frontend);
@@ -130,7 +130,7 @@
         return;
     }
 
-    uint32_t targetFrequency = getTargetFrequency(config.settings);
+    uint32_t targetFrequency = getTargetFrequency(config.config1_0.settings);
     if (type == FrontendScanType::SCAN_BLIND) {
         // reset the frequency in the scan configuration to test blind scan. The settings param of
         // passed in means the real input config on the transponder connected to the DUT.
@@ -139,7 +139,7 @@
         resetBlindScanStartingFrequency(config, targetFrequency - 100);
     }
 
-    Result result = frontend_1_1->scan_1_1(config.settings, type, config.settingsExt1_1);
+    Result result = frontend_1_1->scan_1_1(config.config1_0.settings, type, config.settingsExt1_1);
     EXPECT_TRUE(result == Result::SUCCESS);
 
     bool scanMsgLockedReceived = false;
@@ -159,7 +159,8 @@
     if (mScanMessageType != FrontendScanMessageType::END) {
         if (mScanMessageType == FrontendScanMessageType::LOCKED) {
             scanMsgLockedReceived = true;
-            Result result = frontend_1_1->scan_1_1(config.settings, type, config.settingsExt1_1);
+            Result result =
+                    frontend_1_1->scan_1_1(config.config1_0.settings, type, config.settingsExt1_1);
             EXPECT_TRUE(result == Result::SUCCESS);
         }
 
@@ -207,35 +208,35 @@
     }
 }
 
-void FrontendCallback::resetBlindScanStartingFrequency(FrontendConfig& config,
+void FrontendCallback::resetBlindScanStartingFrequency(FrontendConfig1_1& config,
                                                        uint32_t resetingFreq) {
-    switch (config.settings.getDiscriminator()) {
+    switch (config.config1_0.settings.getDiscriminator()) {
         case FrontendSettings::hidl_discriminator::analog:
-            config.settings.analog().frequency = resetingFreq;
+            config.config1_0.settings.analog().frequency = resetingFreq;
             break;
         case FrontendSettings::hidl_discriminator::atsc:
-            config.settings.atsc().frequency = resetingFreq;
+            config.config1_0.settings.atsc().frequency = resetingFreq;
             break;
         case FrontendSettings::hidl_discriminator::atsc3:
-            config.settings.atsc3().frequency = resetingFreq;
+            config.config1_0.settings.atsc3().frequency = resetingFreq;
             break;
         case FrontendSettings::hidl_discriminator::dvbc:
-            config.settings.dvbc().frequency = resetingFreq;
+            config.config1_0.settings.dvbc().frequency = resetingFreq;
             break;
         case FrontendSettings::hidl_discriminator::dvbs:
-            config.settings.dvbs().frequency = resetingFreq;
+            config.config1_0.settings.dvbs().frequency = resetingFreq;
             break;
         case FrontendSettings::hidl_discriminator::dvbt:
-            config.settings.dvbt().frequency = resetingFreq;
+            config.config1_0.settings.dvbt().frequency = resetingFreq;
             break;
         case FrontendSettings::hidl_discriminator::isdbs:
-            config.settings.isdbs().frequency = resetingFreq;
+            config.config1_0.settings.isdbs().frequency = resetingFreq;
             break;
         case FrontendSettings::hidl_discriminator::isdbs3:
-            config.settings.isdbs3().frequency = resetingFreq;
+            config.config1_0.settings.isdbs3().frequency = resetingFreq;
             break;
         case FrontendSettings::hidl_discriminator::isdbt:
-            config.settings.isdbt().frequency = resetingFreq;
+            config.config1_0.settings.isdbt().frequency = resetingFreq;
             break;
     }
 }
@@ -274,11 +275,11 @@
     return AssertionResult(callbackStatus.isOk());
 }
 
-AssertionResult FrontendTests::scanFrontend(FrontendConfig config, FrontendScanType type) {
+AssertionResult FrontendTests::scanFrontend(FrontendConfig1_1 config, FrontendScanType type) {
     EXPECT_TRUE(mFrontendCallback)
             << "test with openFrontendById/setFrontendCallback/getFrontendInfo first.";
 
-    EXPECT_TRUE(mFrontendInfo.type == config.type)
+    EXPECT_TRUE(mFrontendInfo.type == config.config1_0.type)
             << "FrontendConfig does not match the frontend info of the given id.";
 
     mFrontendCallback->scanTest(mFrontend, config, type);
@@ -426,14 +427,14 @@
     ASSERT_TRUE(status == Result::SUCCESS);
 }
 
-AssertionResult FrontendTests::tuneFrontend(FrontendConfig config, bool testWithDemux) {
+AssertionResult FrontendTests::tuneFrontend(FrontendConfig1_1 config, bool testWithDemux) {
     EXPECT_TRUE(mFrontendCallback)
             << "test with openFrontendById/setFrontendCallback/getFrontendInfo first.";
 
-    EXPECT_TRUE(mFrontendInfo.type == config.type)
+    EXPECT_TRUE(mFrontendInfo.type == config.config1_0.type)
             << "FrontendConfig does not match the frontend info of the given id.";
 
-    mIsSoftwareFe = config.isSoftwareFe;
+    mIsSoftwareFe = config.config1_0.isSoftwareFe;
     bool result = true;
     if (mIsSoftwareFe && testWithDemux) {
         result &= mDvrTests.openDvrInDemux(mDvrConfig.type, mDvrConfig.bufferSize) == success();
@@ -446,7 +447,7 @@
             return failure();
         }
     }
-    mFrontendCallback->tuneTestOnLock(mFrontend, config.settings, config.settingsExt1_1);
+    mFrontendCallback->tuneTestOnLock(mFrontend, config.config1_0.settings, config.settingsExt1_1);
     return AssertionResult(true);
 }
 
@@ -484,12 +485,9 @@
     feId = INVALID_ID;
 }
 
-void FrontendTests::tuneTest(FrontendConfig frontendConf) {
-    if (!frontendConf.enable) {
-        return;
-    }
+void FrontendTests::tuneTest(FrontendConfig1_1 frontendConf) {
     uint32_t feId;
-    getFrontendIdByType(frontendConf.type, feId);
+    getFrontendIdByType(frontendConf.config1_0.type, feId);
     ASSERT_TRUE(feId != INVALID_ID);
     ASSERT_TRUE(openFrontendById(feId));
     ASSERT_TRUE(setFrontendCallback());
@@ -503,12 +501,9 @@
     ASSERT_TRUE(closeFrontend());
 }
 
-void FrontendTests::scanTest(FrontendConfig frontendConf, FrontendScanType scanType) {
-    if (!frontendConf.enable) {
-        return;
-    }
+void FrontendTests::scanTest(FrontendConfig1_1 frontendConf, FrontendScanType scanType) {
     uint32_t feId;
-    getFrontendIdByType(frontendConf.type, feId);
+    getFrontendIdByType(frontendConf.config1_0.type, feId);
     ASSERT_TRUE(feId != INVALID_ID);
     ASSERT_TRUE(openFrontendById(feId));
     ASSERT_TRUE(setFrontendCallback());
diff --git a/tv/tuner/1.1/vts/functional/FrontendTests.h b/tv/tuner/1.1/vts/functional/FrontendTests.h
index 01d2007..3687389 100644
--- a/tv/tuner/1.1/vts/functional/FrontendTests.h
+++ b/tv/tuner/1.1/vts/functional/FrontendTests.h
@@ -79,11 +79,11 @@
 
     void tuneTestOnLock(sp<IFrontend>& frontend, FrontendSettings settings,
                         FrontendSettingsExt1_1 settingsExt1_1);
-    void scanTest(sp<IFrontend>& frontend, FrontendConfig config, FrontendScanType type);
+    void scanTest(sp<IFrontend>& frontend, FrontendConfig1_1 config, FrontendScanType type);
 
     // Helper methods
     uint32_t getTargetFrequency(FrontendSettings settings);
-    void resetBlindScanStartingFrequency(FrontendConfig& config, uint32_t resetingFreq);
+    void resetBlindScanStartingFrequency(FrontendConfig1_1& config, uint32_t resetingFreq);
 
   private:
     void readFrontendScanMessageExt1_1Modulation(FrontendModulation modulation);
@@ -114,9 +114,9 @@
     AssertionResult getFrontendInfo(uint32_t frontendId);
     AssertionResult openFrontendById(uint32_t frontendId);
     AssertionResult setFrontendCallback();
-    AssertionResult scanFrontend(FrontendConfig config, FrontendScanType type);
+    AssertionResult scanFrontend(FrontendConfig1_1 config, FrontendScanType type);
     AssertionResult stopScanFrontend();
-    AssertionResult tuneFrontend(FrontendConfig config, bool testWithDemux);
+    AssertionResult tuneFrontend(FrontendConfig1_1 config, bool testWithDemux);
     void verifyFrontendStatusExt1_1(vector<FrontendStatusTypeExt1_1> statusTypes,
                                     vector<FrontendStatusExt1_1> expectStatuses);
     AssertionResult stopTuneFrontend(bool testWithDemux);
@@ -127,8 +127,8 @@
     AssertionResult unlinkCiCam(uint32_t ciCamId);
 
     void getFrontendIdByType(FrontendType feType, uint32_t& feId);
-    void tuneTest(FrontendConfig frontendConf);
-    void scanTest(FrontendConfig frontend, FrontendScanType type);
+    void tuneTest(FrontendConfig1_1 frontendConf);
+    void scanTest(FrontendConfig1_1 frontend, FrontendScanType type);
     void getFrontendDtmbCapsTest();
 
     void setDvrTests(DvrTests dvrTests) { mDvrTests = dvrTests; }
diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp
index 97fb90d..1080861 100644
--- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp
+++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp
@@ -26,34 +26,31 @@
     return filterDataOutputTestBase(mFilterTests);
 }
 
-void TunerFilterHidlTest::configSingleFilterInDemuxTest(FilterConfig filterConf,
-                                                        FrontendConfig frontendConf) {
-    if (!frontendConf.enable) {
-        return;
-    }
-
+void TunerFilterHidlTest::configSingleFilterInDemuxTest(FilterConfig1_1 filterConf,
+                                                        FrontendConfig1_1 frontendConf) {
     uint32_t feId;
     uint32_t demuxId;
     sp<IDemux> demux;
     uint64_t filterId;
 
-    mFrontendTests.getFrontendIdByType(frontendConf.type, feId);
+    mFrontendTests.getFrontendIdByType(frontendConf.config1_0.type, feId);
     ASSERT_TRUE(feId != INVALID_ID);
     ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
     ASSERT_TRUE(mFrontendTests.setFrontendCallback());
     ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
     ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
     mFilterTests.setDemux(demux);
-    ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize));
+    ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.config1_0.type,
+                                               filterConf.config1_0.bufferSize));
     ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(filterId));
-    ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId));
-    if (filterConf.type.mainType == DemuxFilterMainType::IP) {
+    ASSERT_TRUE(mFilterTests.configFilter(filterConf.config1_0.settings, filterId));
+    if (filterConf.config1_0.type.mainType == DemuxFilterMainType::IP) {
         ASSERT_TRUE(mFilterTests.configIpFilterCid(filterConf.ipCid, filterId));
     }
     if (filterConf.monitorEventTypes > 0) {
         ASSERT_TRUE(mFilterTests.configureMonitorEvent(filterId, filterConf.monitorEventTypes));
     }
-    ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterConf.getMqDesc));
+    ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterConf.config1_0.getMqDesc));
     ASSERT_TRUE(mFilterTests.startFilter(filterId));
     ASSERT_TRUE(mFilterTests.stopFilter(filterId));
     ASSERT_TRUE(mFilterTests.closeFilter(filterId));
@@ -61,19 +58,15 @@
     ASSERT_TRUE(mFrontendTests.closeFrontend());
 }
 
-void TunerFilterHidlTest::reconfigSingleFilterInDemuxTest(FilterConfig filterConf,
-                                                          FilterConfig filterReconf,
-                                                          FrontendConfig frontendConf) {
-    if (!frontendConf.enable) {
-        return;
-    }
-
+void TunerFilterHidlTest::reconfigSingleFilterInDemuxTest(FilterConfig1_1 filterConf,
+                                                          FilterConfig1_1 filterReconf,
+                                                          FrontendConfig1_1 frontendConf) {
     uint32_t feId;
     uint32_t demuxId;
     sp<IDemux> demux;
     uint64_t filterId;
 
-    mFrontendTests.getFrontendIdByType(frontendConf.type, feId);
+    mFrontendTests.getFrontendIdByType(frontendConf.config1_0.type, feId);
     ASSERT_TRUE(feId != INVALID_ID);
     ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
     ASSERT_TRUE(mFrontendTests.setFrontendCallback());
@@ -81,13 +74,14 @@
     ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
     mFrontendTests.setDemux(demux);
     mFilterTests.setDemux(demux);
-    ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize));
+    ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.config1_0.type,
+                                               filterConf.config1_0.bufferSize));
     ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(filterId));
-    ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId));
-    ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterConf.getMqDesc));
+    ASSERT_TRUE(mFilterTests.configFilter(filterConf.config1_0.settings, filterId));
+    ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterConf.config1_0.getMqDesc));
     ASSERT_TRUE(mFilterTests.startFilter(filterId));
     ASSERT_TRUE(mFilterTests.stopFilter(filterId));
-    ASSERT_TRUE(mFilterTests.configFilter(filterReconf.settings, filterId));
+    ASSERT_TRUE(mFilterTests.configFilter(filterReconf.config1_0.settings, filterId));
     ASSERT_TRUE(mFilterTests.startFilter(filterId));
     ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/));
     ASSERT_TRUE(mFilterTests.startIdTest(filterId));
@@ -98,18 +92,14 @@
     ASSERT_TRUE(mFrontendTests.closeFrontend());
 }
 
-void TunerBroadcastHidlTest::mediaFilterUsingSharedMemoryTest(FilterConfig filterConf,
-                                                              FrontendConfig frontendConf) {
-    if (!frontendConf.enable) {
-        return;
-    }
-
+void TunerBroadcastHidlTest::mediaFilterUsingSharedMemoryTest(FilterConfig1_1 filterConf,
+                                                              FrontendConfig1_1 frontendConf) {
     uint32_t feId;
     uint32_t demuxId;
     sp<IDemux> demux;
     uint64_t filterId;
 
-    mFrontendTests.getFrontendIdByType(frontendConf.type, feId);
+    mFrontendTests.getFrontendIdByType(frontendConf.config1_0.type, feId);
     ASSERT_TRUE(feId != INVALID_ID);
     ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
     ASSERT_TRUE(mFrontendTests.setFrontendCallback());
@@ -117,12 +107,13 @@
     ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
     mFrontendTests.setDemux(demux);
     mFilterTests.setDemux(demux);
-    ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize));
+    ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.config1_0.type,
+                                               filterConf.config1_0.bufferSize));
     ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(filterId));
     ASSERT_TRUE(mFilterTests.getSharedAvMemoryHandle(filterId));
-    ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId));
+    ASSERT_TRUE(mFilterTests.configFilter(filterConf.config1_0.settings, filterId));
     ASSERT_TRUE(mFilterTests.configAvFilterStreamType(filterConf.streamType, filterId));
-    ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterConf.getMqDesc));
+    ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterConf.config1_0.getMqDesc));
     ASSERT_TRUE(mFilterTests.startFilter(filterId));
     // tune test
     ASSERT_TRUE(mFrontendTests.tuneFrontend(frontendConf, true /*testWithDemux*/));
@@ -135,19 +126,16 @@
     ASSERT_TRUE(mFrontendTests.closeFrontend());
 }
 
-void TunerRecordHidlTest::recordSingleFilterTest(FilterConfig filterConf,
-                                                 FrontendConfig frontendConf, DvrConfig dvrConf) {
-    if (!frontendConf.enable) {
-        return;
-    }
-
+void TunerRecordHidlTest::recordSingleFilterTest(FilterConfig1_1 filterConf,
+                                                 FrontendConfig1_1 frontendConf,
+                                                 DvrConfig dvrConf) {
     uint32_t feId;
     uint32_t demuxId;
     sp<IDemux> demux;
     uint64_t filterId;
     sp<IFilter> filter;
 
-    mFrontendTests.getFrontendIdByType(frontendConf.type, feId);
+    mFrontendTests.getFrontendIdByType(frontendConf.config1_0.type, feId);
     ASSERT_TRUE(feId != INVALID_ID);
     ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
     ASSERT_TRUE(mFrontendTests.setFrontendCallback());
@@ -159,10 +147,11 @@
     ASSERT_TRUE(mDvrTests.openDvrInDemux(dvrConf.type, dvrConf.bufferSize));
     ASSERT_TRUE(mDvrTests.configDvrRecord(dvrConf.settings));
     ASSERT_TRUE(mDvrTests.getDvrRecordMQDescriptor());
-    ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize));
+    ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.config1_0.type,
+                                               filterConf.config1_0.bufferSize));
     ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(filterId));
-    ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId));
-    ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterConf.getMqDesc));
+    ASSERT_TRUE(mFilterTests.configFilter(filterConf.config1_0.settings, filterId));
+    ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterConf.config1_0.getMqDesc));
     filter = mFilterTests.getFilterById(filterId);
     ASSERT_TRUE(filter != nullptr);
     mDvrTests.startRecordOutputThread(dvrConf.settings.record());
@@ -186,41 +175,47 @@
 TEST_P(TunerFilterHidlTest, StartFilterInDemux) {
     description("Open and start a filter in Demux.");
     // TODO use parameterized tests
-    configSingleFilterInDemuxTest(filterArray[TS_VIDEO0], frontendArray[defaultFrontend]);
+    configSingleFilterInDemuxTest(filterMap[live.videoFilterId], frontendMap[live.frontendId]);
 }
 
 TEST_P(TunerFilterHidlTest, ConfigIpFilterInDemuxWithCid) {
     description("Open and configure an ip filter in Demux.");
     // TODO use parameterized tests
-    configSingleFilterInDemuxTest(filterArray[IP_IP0], frontendArray[defaultFrontend]);
+    if (live.ipFilterId.compare(emptyHardwareId) == 0) {
+        return;
+    }
+    configSingleFilterInDemuxTest(filterMap[live.ipFilterId], frontendMap[live.frontendId]);
 }
 
 TEST_P(TunerFilterHidlTest, ReconfigFilterToReceiveStartId) {
     description("Recofigure and restart a filter to test start id.");
     // TODO use parameterized tests
-    reconfigSingleFilterInDemuxTest(filterArray[TS_VIDEO0], filterArray[TS_VIDEO1],
-                                    frontendArray[defaultFrontend]);
+    reconfigSingleFilterInDemuxTest(filterMap[live.videoFilterId], filterMap[live.videoFilterId],
+                                    frontendMap[live.frontendId]);
 }
 
 TEST_P(TunerRecordHidlTest, RecordDataFlowWithTsRecordFilterTest) {
     description("Feed ts data from frontend to recording and test with ts record filter");
-    recordSingleFilterTest(filterArray[TS_RECORD0], frontendArray[defaultFrontend],
-                           dvrArray[DVR_RECORD0]);
+    if (!record.support) {
+        return;
+    }
+    recordSingleFilterTest(filterMap[record.recordFilterId], frontendMap[record.frontendId],
+                           dvrMap[record.dvrRecordId]);
 }
 
 TEST_P(TunerFrontendHidlTest, TuneFrontendWithFrontendSettingsExt1_1) {
     description("Tune one Frontend with v1_1 extended setting and check Lock event");
-    mFrontendTests.tuneTest(frontendArray[defaultFrontend]);
+    mFrontendTests.tuneTest(frontendMap[live.frontendId]);
 }
 
 TEST_P(TunerFrontendHidlTest, BlindScanFrontendWithEndFrequency) {
     description("Run an blind frontend scan with v1_1 extended setting and check lock scanMessage");
-    mFrontendTests.scanTest(frontendScanArray[defaultScanFrontend], FrontendScanType::SCAN_BLIND);
+    mFrontendTests.scanTest(frontendMap[scan.frontendId], FrontendScanType::SCAN_BLIND);
 }
 
 TEST_P(TunerBroadcastHidlTest, MediaFilterWithSharedMemoryHandle) {
     description("Test the Media Filter with shared memory handle");
-    mediaFilterUsingSharedMemoryTest(filterArray[TS_VIDEO0], frontendArray[defaultFrontend]);
+    mediaFilterUsingSharedMemoryTest(filterMap[live.videoFilterId], frontendMap[live.frontendId]);
 }
 
 TEST_P(TunerFrontendHidlTest, GetFrontendDtmbCaps) {
@@ -230,7 +225,10 @@
 
 TEST_P(TunerFrontendHidlTest, LinkToCiCam) {
     description("Test Frontend link to CiCam");
-    mFrontendTests.tuneTest(frontendArray[defaultFrontend]);
+    if (!frontendMap[live.frontendId].canConnectToCiCam) {
+        return;
+    }
+    mFrontendTests.tuneTest(frontendMap[live.frontendId]);
 }
 
 INSTANTIATE_TEST_SUITE_P(
diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h
index d14a2e8..863f649 100644
--- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h
+++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.h
@@ -19,11 +19,20 @@
 
 namespace {
 
-void initConfiguration() {
+bool initConfiguration() {
+    TunerTestingConfigReader1_0::setConfigFilePath(configFilePath);
+    if (!TunerTestingConfigReader1_0::checkConfigFileExists()) {
+        return false;
+    }
     initFrontendConfig();
-    initFrontendScanConfig();
     initFilterConfig();
     initDvrConfig();
+    connectHardwaresToTestCases();
+    if (!validateConnections()) {
+        ALOGW("[vts] failed to validate connections.");
+        return false;
+    }
+    return true;
 }
 
 static AssertionResult success() {
@@ -57,9 +66,9 @@
         RecordProperty("description", description);
     }
 
-    void configSingleFilterInDemuxTest(FilterConfig filterConf, FrontendConfig frontendConf);
-    void reconfigSingleFilterInDemuxTest(FilterConfig filterConf, FilterConfig filterReconf,
-                                         FrontendConfig frontendConf);
+    void configSingleFilterInDemuxTest(FilterConfig1_1 filterConf, FrontendConfig1_1 frontendConf);
+    void reconfigSingleFilterInDemuxTest(FilterConfig1_1 filterConf, FilterConfig1_1 filterReconf,
+                                         FrontendConfig1_1 frontendConf);
     sp<ITuner> mService;
     FrontendTests mFrontendTests;
     DemuxTests mDemuxTests;
@@ -86,7 +95,7 @@
         RecordProperty("description", description);
     }
 
-    void recordSingleFilterTest(FilterConfig filterConf, FrontendConfig frontendConf,
+    void recordSingleFilterTest(FilterConfig1_1 filterConf, FrontendConfig1_1 frontendConf,
                                 DvrConfig dvrConf);
     AssertionResult filterDataOutputTest();
 
@@ -144,7 +153,8 @@
 
     AssertionResult filterDataOutputTest();
 
-    void mediaFilterUsingSharedMemoryTest(FilterConfig filterConf, FrontendConfig frontendConf);
+    void mediaFilterUsingSharedMemoryTest(FilterConfig1_1 filterConf,
+                                          FrontendConfig1_1 frontendConf);
 };
 
 // TODO remove from the allow list once the cf tv target is enabled for testing
diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h
index ad57849..390bd4c 100644
--- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h
+++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TestConfigurations.h
@@ -21,6 +21,8 @@
 #include <hidl/Status.h>
 #include <hidlmemory/FrameworkUtils.h>
 
+#include "../../../config/TunerTestingConfigReaderV1_1.h"
+
 using android::hardware::tv::tuner::V1_0::DataFormat;
 using android::hardware::tv::tuner::V1_0::DemuxAlpFilterType;
 using android::hardware::tv::tuner::V1_0::DemuxFilterMainType;
@@ -46,104 +48,39 @@
 using android::hardware::tv::tuner::V1_0::FrontendType;
 using android::hardware::tv::tuner::V1_0::PlaybackSettings;
 using android::hardware::tv::tuner::V1_0::RecordSettings;
-using android::hardware::tv::tuner::V1_1::AudioStreamType;
-using android::hardware::tv::tuner::V1_1::AvStreamType;
-using android::hardware::tv::tuner::V1_1::FrontendSettingsExt1_1;
-using android::hardware::tv::tuner::V1_1::FrontendStatusExt1_1;
-using android::hardware::tv::tuner::V1_1::FrontendStatusTypeExt1_1;
-using android::hardware::tv::tuner::V1_1::VideoStreamType;
 
 using namespace std;
+using namespace android::media::tuner::testing::configuration::V1_0;
 
-const uint32_t FMQ_SIZE_512K = 0x80000;
-const uint32_t FMQ_SIZE_1M = 0x100000;
 const uint32_t FMQ_SIZE_4M = 0x400000;
 const uint32_t FMQ_SIZE_16M = 0x1000000;
 
-typedef enum {
-    TS_VIDEO0,
-    TS_VIDEO1,
-    TS_AUDIO0,
-    TS_AUDIO1,
-    TS_PES0,
-    TS_PCR0,
-    TS_SECTION0,
-    TS_TS0,
-    TS_RECORD0,
-    IP_IP0,
-    FILTER_MAX,
-} Filter;
+const string configFilePath = "/vendor/etc/tuner_vts_config_1_1.xml";
 
-typedef enum {
-    DVBT,
-    DVBS,
-    FRONTEND_MAX,
-} Frontend;
+// Hardware configs
+static map<string, FrontendConfig1_1> frontendMap;
+static map<string, FilterConfig1_1> filterMap;
+static map<string, DvrConfig> dvrMap;
 
-typedef enum {
-    SCAN_DVBT,
-    SCAN_MAX,
-} FrontendScan;
+// Hardware and test cases connections
+static LiveBroadcastHardwareConnections live;
+static ScanHardwareConnections scan;
+static DvrRecordHardwareConnections record;
 
-typedef enum {
-    DVR_RECORD0,
-    DVR_PLAYBACK0,
-    DVR_MAX,
-} Dvr;
-
-struct FilterConfig {
-    uint32_t bufferSize;
-    DemuxFilterType type;
-    DemuxFilterSettings settings;
-    bool getMqDesc;
-    AvStreamType streamType;
-    uint32_t ipCid;
-    uint32_t monitorEventTypes;
-
-    bool operator<(const FilterConfig& /*c*/) const { return false; }
-};
-
-struct FrontendConfig {
-    bool enable;
-    bool isSoftwareFe;
-    bool canConnectToCiCam;
-    uint32_t ciCamId;
-    FrontendType type;
-    FrontendSettings settings;
-    FrontendSettingsExt1_1 settingsExt1_1;
-    vector<FrontendStatusTypeExt1_1> tuneStatusTypes;
-    vector<FrontendStatusExt1_1> expectTuneStatuses;
-};
-
-struct DvrConfig {
-    DvrType type;
-    uint32_t bufferSize;
-    DvrSettings settings;
-    string playbackInputFile;
-};
-
-static FrontendConfig frontendArray[FILTER_MAX];
-static FrontendConfig frontendScanArray[SCAN_MAX];
-static FilterConfig filterArray[FILTER_MAX];
-static DvrConfig dvrArray[DVR_MAX];
-static int defaultFrontend = DVBT;
-static int defaultScanFrontend = SCAN_DVBT;
-
-/** Configuration array for the frontend tune test */
+/** Config all the frontends that would be used in the tests */
 inline void initFrontendConfig() {
+    // The test will use the internal default fe when default fe is connected to any data flow
+    // without overriding in the xml config.
+    string defaultFeId = "FE_DEFAULT";
     FrontendDvbtSettings dvbtSettings{
             .frequency = 578000,
             .transmissionMode = FrontendDvbtTransmissionMode::AUTO,
             .bandwidth = FrontendDvbtBandwidth::BANDWIDTH_8MHZ,
-            .constellation = FrontendDvbtConstellation::AUTO,
-            .hierarchy = FrontendDvbtHierarchy::AUTO,
-            .hpCoderate = FrontendDvbtCoderate::AUTO,
-            .lpCoderate = FrontendDvbtCoderate::AUTO,
-            .guardInterval = FrontendDvbtGuardInterval::AUTO,
             .isHighPriority = true,
-            .standard = FrontendDvbtStandard::T,
     };
-    frontendArray[DVBT].type = FrontendType::DVBT, frontendArray[DVBT].settings.dvbt(dvbtSettings);
+    frontendMap[defaultFeId].config1_0.type = FrontendType::DVBT;
+    frontendMap[defaultFeId].config1_0.settings.dvbt(dvbtSettings);
+
     vector<FrontendStatusTypeExt1_1> types;
     types.push_back(FrontendStatusTypeExt1_1::UEC);
     types.push_back(FrontendStatusTypeExt1_1::IS_MISO);
@@ -153,147 +90,97 @@
     statuses.push_back(status);
     status.isMiso(true);
     statuses.push_back(status);
-
-    frontendArray[DVBT].tuneStatusTypes = types;
-    frontendArray[DVBT].expectTuneStatuses = statuses;
-    frontendArray[DVBT].isSoftwareFe = true;
-    frontendArray[DVBT].canConnectToCiCam = true;
-    frontendArray[DVBT].ciCamId = 0;
-    frontendArray[DVBT].settingsExt1_1.settingExt.dvbt({
+    frontendMap[defaultFeId].tuneStatusTypes = types;
+    frontendMap[defaultFeId].expectTuneStatuses = statuses;
+    frontendMap[defaultFeId].config1_0.isSoftwareFe = true;
+    frontendMap[defaultFeId].canConnectToCiCam = true;
+    frontendMap[defaultFeId].ciCamId = 0;
+    frontendMap[defaultFeId].settingsExt1_1.settingExt.dvbt({
             .transmissionMode =
                     android::hardware::tv::tuner::V1_1::FrontendDvbtTransmissionMode::MODE_8K_E,
     });
-    frontendArray[DVBT].enable = true;
-    frontendArray[DVBS].type = FrontendType::DVBS;
-    frontendArray[DVBS].isSoftwareFe = true;
-    frontendArray[DVBS].enable = true;
+    // Read customized config
+    TunerTestingConfigReader1_1::readFrontendConfig1_1(frontendMap);
 };
 
-/** Configuration array for the frontend scan test */
-inline void initFrontendScanConfig() {
-    frontendScanArray[SCAN_DVBT].type = FrontendType::DVBT;
-    frontendScanArray[SCAN_DVBT].settings.dvbt({
-            .frequency = 578000,
-            .transmissionMode = FrontendDvbtTransmissionMode::MODE_8K,
-            .bandwidth = FrontendDvbtBandwidth::BANDWIDTH_8MHZ,
-            .constellation = FrontendDvbtConstellation::AUTO,
-            .hierarchy = FrontendDvbtHierarchy::AUTO,
-            .hpCoderate = FrontendDvbtCoderate::AUTO,
-            .lpCoderate = FrontendDvbtCoderate::AUTO,
-            .guardInterval = FrontendDvbtGuardInterval::AUTO,
-            .isHighPriority = true,
-            .standard = FrontendDvbtStandard::T,
-    });
-    frontendScanArray[SCAN_DVBT].settingsExt1_1.endFrequency = 800000;
-    frontendScanArray[SCAN_DVBT].settingsExt1_1.settingExt.dvbt({
-            .transmissionMode =
-                    android::hardware::tv::tuner::V1_1::FrontendDvbtTransmissionMode::MODE_8K_E,
-    });
-};
-
-/** Configuration array for the filter test */
 inline void initFilterConfig() {
-    // TS VIDEO filter setting for default implementation testing
-    filterArray[TS_VIDEO0].type.mainType = DemuxFilterMainType::TS;
-    filterArray[TS_VIDEO0].type.subType.tsFilterType(DemuxTsFilterType::VIDEO);
-    filterArray[TS_VIDEO0].bufferSize = FMQ_SIZE_16M;
-    filterArray[TS_VIDEO0].settings.ts().tpid = 256;
-    filterArray[TS_VIDEO0].settings.ts().filterSettings.av({.isPassthrough = false});
-    filterArray[TS_VIDEO0].monitorEventTypes =
+    // The test will use the internal default filter when default filter is connected to any
+    // data flow without overriding in the xml config.
+    string defaultAudioFilterId = "FILTER_AUDIO_DEFAULT";
+    string defaultVideoFilterId = "FILTER_VIDEO_DEFAULT";
+
+    filterMap[defaultVideoFilterId].config1_0.type.mainType = DemuxFilterMainType::TS;
+    filterMap[defaultVideoFilterId].config1_0.type.subType.tsFilterType(DemuxTsFilterType::VIDEO);
+    filterMap[defaultVideoFilterId].config1_0.bufferSize = FMQ_SIZE_16M;
+    filterMap[defaultVideoFilterId].config1_0.settings.ts().tpid = 256;
+    filterMap[defaultVideoFilterId].config1_0.settings.ts().filterSettings.av(
+            {.isPassthrough = false});
+    filterMap[defaultVideoFilterId].monitorEventTypes =
             android::hardware::tv::tuner::V1_1::DemuxFilterMonitorEventType::SCRAMBLING_STATUS |
             android::hardware::tv::tuner::V1_1::DemuxFilterMonitorEventType::IP_CID_CHANGE;
-    filterArray[TS_VIDEO1].type.mainType = DemuxFilterMainType::TS;
-    filterArray[TS_VIDEO1].type.subType.tsFilterType(DemuxTsFilterType::VIDEO);
-    filterArray[TS_VIDEO1].bufferSize = FMQ_SIZE_16M;
-    filterArray[TS_VIDEO1].settings.ts().tpid = 256;
-    filterArray[TS_VIDEO1].settings.ts().filterSettings.av({.isPassthrough = false});
-    filterArray[TS_VIDEO1].streamType.video(VideoStreamType::MPEG1);
-    // TS AUDIO filter setting
-    filterArray[TS_AUDIO0].type.mainType = DemuxFilterMainType::TS;
-    filterArray[TS_AUDIO0].type.subType.tsFilterType(DemuxTsFilterType::AUDIO);
-    filterArray[TS_AUDIO0].bufferSize = FMQ_SIZE_16M;
-    filterArray[TS_AUDIO0].settings.ts().tpid = 256;
-    filterArray[TS_AUDIO0].settings.ts().filterSettings.av({.isPassthrough = false});
-    filterArray[TS_AUDIO1].type.mainType = DemuxFilterMainType::TS;
-    filterArray[TS_AUDIO1].type.subType.tsFilterType(DemuxTsFilterType::AUDIO);
-    filterArray[TS_AUDIO1].bufferSize = FMQ_SIZE_16M;
-    filterArray[TS_AUDIO1].settings.ts().tpid = 257;
-    filterArray[TS_AUDIO1].settings.ts().filterSettings.av({.isPassthrough = false});
-    filterArray[TS_VIDEO1].streamType.audio(AudioStreamType::MP3);
-    // TS PES filter setting
-    filterArray[TS_PES0].type.mainType = DemuxFilterMainType::TS;
-    filterArray[TS_PES0].type.subType.tsFilterType(DemuxTsFilterType::PES);
-    filterArray[TS_PES0].bufferSize = FMQ_SIZE_16M;
-    filterArray[TS_PES0].settings.ts().tpid = 256;
-    filterArray[TS_PES0].settings.ts().filterSettings.pesData({
-            .isRaw = false,
-            .streamId = 0xbd,
-    });
-    filterArray[TS_PES0].getMqDesc = true;
-    // TS PCR filter setting
-    filterArray[TS_PCR0].type.mainType = DemuxFilterMainType::TS;
-    filterArray[TS_PCR0].type.subType.tsFilterType(DemuxTsFilterType::PCR);
-    filterArray[TS_PCR0].bufferSize = FMQ_SIZE_16M;
-    filterArray[TS_PCR0].settings.ts().tpid = 256;
-    filterArray[TS_PCR0].settings.ts().filterSettings.noinit();
-    // TS filter setting
-    filterArray[TS_TS0].type.mainType = DemuxFilterMainType::TS;
-    filterArray[TS_TS0].type.subType.tsFilterType(DemuxTsFilterType::TS);
-    filterArray[TS_TS0].bufferSize = FMQ_SIZE_16M;
-    filterArray[TS_TS0].settings.ts().tpid = 256;
-    filterArray[TS_TS0].settings.ts().filterSettings.noinit();
-    // TS SECTION filter setting
-    filterArray[TS_SECTION0].type.mainType = DemuxFilterMainType::TS;
-    filterArray[TS_SECTION0].type.subType.tsFilterType(DemuxTsFilterType::SECTION);
-    filterArray[TS_SECTION0].bufferSize = FMQ_SIZE_16M;
-    filterArray[TS_SECTION0].settings.ts().tpid = 256;
-    filterArray[TS_SECTION0].settings.ts().filterSettings.section({
-            .isRaw = false,
-    });
-    filterArray[TS_SECTION0].getMqDesc = true;
-    // TS RECORD filter setting
-    filterArray[TS_RECORD0].type.mainType = DemuxFilterMainType::TS;
-    filterArray[TS_RECORD0].type.subType.tsFilterType(DemuxTsFilterType::RECORD);
-    filterArray[TS_RECORD0].settings.ts().tpid = 256;
-    filterArray[TS_RECORD0].settings.ts().filterSettings.record({
-            .scIndexType = DemuxRecordScIndexType::NONE,
-    });
-    // IP filter setting
-    filterArray[IP_IP0].type.mainType = DemuxFilterMainType::IP;
-    filterArray[IP_IP0].type.subType.ipFilterType(DemuxIpFilterType::IP);
-    uint8_t src[4] = {192, 168, 1, 1};
-    uint8_t dest[4] = {192, 168, 1, 2};
-    DemuxIpAddress ipAddress;
-    ipAddress.srcIpAddress.v4(src);
-    ipAddress.dstIpAddress.v4(dest);
-    DemuxIpFilterSettings ipSettings{
-            .ipAddr = ipAddress,
-    };
-    filterArray[IP_IP0].settings.ip(ipSettings);
-    filterArray[IP_IP0].ipCid = 1;
+    filterMap[defaultVideoFilterId].streamType.video(VideoStreamType::MPEG1);
+
+    filterMap[defaultAudioFilterId].config1_0.type.mainType = DemuxFilterMainType::TS;
+    filterMap[defaultAudioFilterId].config1_0.type.subType.tsFilterType(DemuxTsFilterType::AUDIO);
+    filterMap[defaultAudioFilterId].config1_0.bufferSize = FMQ_SIZE_16M;
+    filterMap[defaultAudioFilterId].config1_0.settings.ts().tpid = 256;
+    filterMap[defaultAudioFilterId].config1_0.settings.ts().filterSettings.av(
+            {.isPassthrough = false});
+    filterMap[defaultAudioFilterId].monitorEventTypes =
+            android::hardware::tv::tuner::V1_1::DemuxFilterMonitorEventType::SCRAMBLING_STATUS |
+            android::hardware::tv::tuner::V1_1::DemuxFilterMonitorEventType::IP_CID_CHANGE;
+    filterMap[defaultAudioFilterId].streamType.audio(AudioStreamType::MP3);
+    // Read customized config
+    TunerTestingConfigReader1_1::readFilterConfig1_1(filterMap);
 };
 
-/** Configuration array for the dvr test */
+/** Config all the dvrs that would be used in the tests */
 inline void initDvrConfig() {
-    RecordSettings recordSettings{
-            .statusMask = 0xf,
-            .lowThreshold = 0x1000,
-            .highThreshold = 0x07fff,
-            .dataFormat = DataFormat::TS,
-            .packetSize = 188,
-    };
-    dvrArray[DVR_RECORD0].type = DvrType::RECORD;
-    dvrArray[DVR_RECORD0].bufferSize = FMQ_SIZE_4M;
-    dvrArray[DVR_RECORD0].settings.record(recordSettings);
-    PlaybackSettings playbackSettings{
-            .statusMask = 0xf,
-            .lowThreshold = 0x1000,
-            .highThreshold = 0x07fff,
-            .dataFormat = DataFormat::TS,
-            .packetSize = 188,
-    };
-    dvrArray[DVR_PLAYBACK0].type = DvrType::PLAYBACK;
-    dvrArray[DVR_PLAYBACK0].playbackInputFile = "/data/local/tmp/segment000000.ts";
-    dvrArray[DVR_PLAYBACK0].bufferSize = FMQ_SIZE_4M;
-    dvrArray[DVR_PLAYBACK0].settings.playback(playbackSettings);
+    // Read customized config
+    TunerTestingConfigReader1_0::readDvrConfig1_0(dvrMap);
 };
+
+/** Read the vendor configurations of which hardware to use for each test cases/data flows */
+inline void connectHardwaresToTestCases() {
+    TunerTestingConfigReader1_0::connectLiveBroadcast(live);
+    TunerTestingConfigReader1_0::connectScan(scan);
+    TunerTestingConfigReader1_0::connectDvrRecord(record);
+};
+
+inline bool validateConnections() {
+    bool feIsValid = frontendMap.find(live.frontendId) != frontendMap.end() &&
+                     frontendMap.find(scan.frontendId) != frontendMap.end();
+    feIsValid &= record.support ? frontendMap.find(record.frontendId) != frontendMap.end() : true;
+
+    if (!feIsValid) {
+        ALOGW("[vts config] dynamic config fe connection is invalid.");
+        return false;
+    }
+
+    bool dvrIsValid = frontendMap[live.frontendId].config1_0.isSoftwareFe
+                              ? dvrMap.find(live.dvrSoftwareFeId) != dvrMap.end()
+                              : true;
+    if (record.support) {
+        if (frontendMap[record.frontendId].config1_0.isSoftwareFe) {
+            dvrIsValid &= dvrMap.find(record.dvrSoftwareFeId) != dvrMap.end();
+        }
+        dvrIsValid &= dvrMap.find(record.dvrRecordId) != dvrMap.end();
+    }
+
+    if (!dvrIsValid) {
+        ALOGW("[vts config] dynamic config dvr connection is invalid.");
+        return false;
+    }
+
+    bool filterIsValid = filterMap.find(live.audioFilterId) != filterMap.end() &&
+                         filterMap.find(live.videoFilterId) != filterMap.end();
+    filterIsValid &=
+            record.support ? filterMap.find(record.recordFilterId) != filterMap.end() : true;
+
+    if (!filterIsValid) {
+        ALOGW("[vts config] dynamic config filter connection is invalid.");
+        return false;
+    }
+
+    return true;
+}
diff --git a/tv/tuner/config/TunerTestingConfigReader.h b/tv/tuner/config/TunerTestingConfigReaderV1_0.h
similarity index 84%
rename from tv/tuner/config/TunerTestingConfigReader.h
rename to tv/tuner/config/TunerTestingConfigReaderV1_0.h
index 90499c4..cff4af1 100644
--- a/tv/tuner/config/TunerTestingConfigReader.h
+++ b/tv/tuner/config/TunerTestingConfigReaderV1_0.h
@@ -36,6 +36,8 @@
 using android::hardware::tv::tuner::V1_0::DemuxFilterSectionSettings;
 using android::hardware::tv::tuner::V1_0::DemuxFilterSettings;
 using android::hardware::tv::tuner::V1_0::DemuxFilterType;
+using android::hardware::tv::tuner::V1_0::DemuxIpAddress;
+using android::hardware::tv::tuner::V1_0::DemuxIpFilterSettings;
 using android::hardware::tv::tuner::V1_0::DemuxIpFilterType;
 using android::hardware::tv::tuner::V1_0::DemuxMmtpFilterType;
 using android::hardware::tv::tuner::V1_0::DemuxRecordScIndexType;
@@ -63,9 +65,10 @@
 using android::hardware::tv::tuner::V1_0::PlaybackSettings;
 using android::hardware::tv::tuner::V1_0::RecordSettings;
 
-const string configFilePath = "/vendor/etc/tuner_vts_config.xml";
 const string emptyHardwareId = "";
 
+static string mConfigFilePath;
+
 #define PROVISION_STR                                      \
     "{                                                   " \
     "  \"id\": 21140844,                                 " \
@@ -125,6 +128,7 @@
     string audioFilterId;
     string videoFilterId;
     string sectionFilterId;
+    string ipFilterId;
     string pcrFilterId;
     /* list string of extra filters; */
 };
@@ -186,14 +190,17 @@
     string timeFilterId;
 };
 
-struct TunerTestingConfigReader {
+struct TunerTestingConfigReader1_0 {
   public:
+    static void setConfigFilePath(string path) { mConfigFilePath = path; }
+
     static bool checkConfigFileExists() {
-        auto res = read(configFilePath.c_str());
+        auto res = read(mConfigFilePath.c_str());
         if (res == nullopt) {
-            ALOGW("[ConfigReader] Couldn't read /vendor/etc/tuner_vts_config.xml."
+            ALOGW("[ConfigReader] Couldn't read %s."
                   "Please check tuner_testing_dynamic_configuration.xsd"
-                  "and sample_tuner_vts_config.xml for more details on how to config Tune VTS.");
+                  "and sample_tuner_vts_config.xml for more details on how to config Tune VTS.",
+                  mConfigFilePath.c_str());
         }
         return (res != nullopt);
     }
@@ -413,6 +420,11 @@
         if (liveConfig.hasDvrSoftwareFeConnection()) {
             live.dvrSoftwareFeId = liveConfig.getDvrSoftwareFeConnection();
         }
+        if (liveConfig.hasIpFilterConnection()) {
+            live.ipFilterId = liveConfig.getIpFilterConnection();
+        } else {
+            live.ipFilterId = emptyHardwareId;
+        }
     }
 
     static void connectScan(ScanHardwareConnections& scan) {
@@ -520,6 +532,10 @@
         timeFilter.timeFilterId = timeFilterConfig.getTimeFilterConnection();
     }
 
+    static HardwareConfiguration getHardwareConfig() {
+        return *getTunerConfig().getFirstHardwareConfiguration();
+    }
+
   private:
     static FrontendDvbtSettings readDvbtFrontendSettings(Frontend feConfig) {
         ALOGW("[ConfigReader] fe type is dvbt");
@@ -530,12 +546,17 @@
             ALOGW("[ConfigReader] no more dvbt settings");
             return dvbtSettings;
         }
-        dvbtSettings.transmissionMode = static_cast<FrontendDvbtTransmissionMode>(
-                feConfig.getFirstDvbtFrontendSettings_optional()->getTransmissionMode());
-        dvbtSettings.bandwidth = static_cast<FrontendDvbtBandwidth>(
-                feConfig.getFirstDvbtFrontendSettings_optional()->getBandwidth());
-        dvbtSettings.isHighPriority =
-                feConfig.getFirstDvbtFrontendSettings_optional()->getIsHighPriority();
+        auto dvbt = feConfig.getFirstDvbtFrontendSettings_optional();
+        uint32_t trans = static_cast<uint32_t>(dvbt->getTransmissionMode());
+        if (trans <= (uint32_t)FrontendDvbtTransmissionMode::MODE_32K) {
+            dvbtSettings.transmissionMode = static_cast<FrontendDvbtTransmissionMode>(trans);
+        }
+        dvbtSettings.bandwidth = static_cast<FrontendDvbtBandwidth>(dvbt->getBandwidth());
+        dvbtSettings.isHighPriority = dvbt->getIsHighPriority();
+        if (dvbt->hasConstellation()) {
+            dvbtSettings.constellation =
+                    static_cast<FrontendDvbtConstellation>(dvbt->getConstellation());
+        }
         return dvbtSettings;
     }
 
@@ -559,13 +580,13 @@
                                           DemuxFilterSettings& settings) {
         auto mainType = filterConfig.getMainType();
         auto subType = filterConfig.getSubType();
-        uint32_t pid = static_cast<uint32_t>(filterConfig.getPid());
         switch (mainType) {
             case FilterMainTypeEnum::TS: {
                 ALOGW("[ConfigReader] filter main type is ts");
                 type.mainType = DemuxFilterMainType::TS;
                 switch (subType) {
                     case FilterSubTypeEnum::UNDEFINED:
+                        type.subType.tsFilterType(DemuxTsFilterType::UNDEFINED);
                         break;
                     case FilterSubTypeEnum::SECTION:
                         type.subType.tsFilterType(DemuxTsFilterType::SECTION);
@@ -606,7 +627,9 @@
                         ALOGW("[ConfigReader] ts subtype is not supported");
                         return false;
                 }
-                settings.ts().tpid = pid;
+                if (filterConfig.hasPid()) {
+                    settings.ts().tpid = static_cast<uint32_t>(filterConfig.getPid());
+                }
                 break;
             }
             case FilterMainTypeEnum::MMTP: {
@@ -614,6 +637,7 @@
                 type.mainType = DemuxFilterMainType::MMTP;
                 switch (subType) {
                     case FilterSubTypeEnum::UNDEFINED:
+                        type.subType.mmtpFilterType(DemuxMmtpFilterType::UNDEFINED);
                         break;
                     case FilterSubTypeEnum::SECTION:
                         type.subType.mmtpFilterType(DemuxMmtpFilterType::SECTION);
@@ -652,7 +676,47 @@
                         ALOGW("[ConfigReader] mmtp subtype is not supported");
                         return false;
                 }
-                settings.mmtp().mmtpPid = pid;
+                if (filterConfig.hasPid()) {
+                    settings.mmtp().mmtpPid = static_cast<uint32_t>(filterConfig.getPid());
+                }
+                break;
+            }
+            case FilterMainTypeEnum::IP: {
+                ALOGW("[ConfigReader] filter main type is ip");
+                type.mainType = DemuxFilterMainType::IP;
+                switch (subType) {
+                    case FilterSubTypeEnum::UNDEFINED:
+                        type.subType.ipFilterType(DemuxIpFilterType::UNDEFINED);
+                        break;
+                    case FilterSubTypeEnum::SECTION:
+                        type.subType.ipFilterType(DemuxIpFilterType::SECTION);
+                        settings.ip().filterSettings.section(
+                                readSectionFilterSettings(filterConfig));
+                        break;
+                    case FilterSubTypeEnum::NTP:
+                        type.subType.ipFilterType(DemuxIpFilterType::NTP);
+                        settings.ip().filterSettings.noinit();
+                        break;
+                    case FilterSubTypeEnum::IP: {
+                        DemuxIpFilterSettings ip{
+                                .ipAddr = readIpAddress(filterConfig),
+                        };
+                        ip.filterSettings.bPassthrough(readPassthroughSettings(filterConfig));
+                        settings.ip(ip);
+                        break;
+                    }
+                    case FilterSubTypeEnum::IP_PAYLOAD:
+                        type.subType.ipFilterType(DemuxIpFilterType::IP_PAYLOAD);
+                        settings.ip().filterSettings.noinit();
+                        break;
+                    case FilterSubTypeEnum::PAYLOAD_THROUGH:
+                        type.subType.ipFilterType(DemuxIpFilterType::PAYLOAD_THROUGH);
+                        settings.ip().filterSettings.noinit();
+                        break;
+                    default:
+                        ALOGW("[ConfigReader] mmtp subtype is not supported");
+                        return false;
+                }
                 break;
             }
             default:
@@ -663,6 +727,46 @@
         return true;
     }
 
+    static DemuxIpAddress readIpAddress(Filter filterConfig) {
+        DemuxIpAddress ipAddress;
+        if (!filterConfig.hasIpFilterConfig_optional()) {
+            return ipAddress;
+        }
+        auto ipFilterConfig = filterConfig.getFirstIpFilterConfig_optional();
+        if (ipFilterConfig->hasSrcPort()) {
+            ipAddress.srcPort = ipFilterConfig->getSrcPort();
+        }
+        if (ipFilterConfig->hasDestPort()) {
+            ipAddress.dstPort = ipFilterConfig->getDestPort();
+        }
+        if (ipFilterConfig->getFirstSrcIpAddress()->getIsIpV4()) {
+            memcpy(ipAddress.srcIpAddress.v4().data(),
+                   ipFilterConfig->getFirstSrcIpAddress()->getIp().data(), 4);
+        } else {
+            memcpy(ipAddress.srcIpAddress.v6().data(),
+                   ipFilterConfig->getFirstSrcIpAddress()->getIp().data(), 6);
+        }
+        if (ipFilterConfig->getFirstDestIpAddress()->getIsIpV4()) {
+            memcpy(ipAddress.dstIpAddress.v4().data(),
+                   ipFilterConfig->getFirstDestIpAddress()->getIp().data(), 4);
+        } else {
+            memcpy(ipAddress.dstIpAddress.v6().data(),
+                   ipFilterConfig->getFirstDestIpAddress()->getIp().data(), 6);
+        }
+        return ipAddress;
+    }
+
+    static bool readPassthroughSettings(Filter filterConfig) {
+        if (!filterConfig.hasIpFilterConfig_optional()) {
+            return false;
+        }
+        auto ipFilterConfig = filterConfig.getFirstIpFilterConfig_optional();
+        if (ipFilterConfig->hasDataPassthrough()) {
+            return ipFilterConfig->getDataPassthrough();
+        }
+        return false;
+    }
+
     static DemuxFilterSectionSettings readSectionFilterSettings(Filter filterConfig) {
         DemuxFilterSectionSettings settings;
         if (!filterConfig.hasSectionFilterSettings_optional()) {
@@ -720,11 +824,7 @@
         return recordSettings;
     }
 
-    static TunerConfiguration getTunerConfig() { return *read(configFilePath.c_str()); }
-
-    static HardwareConfiguration getHardwareConfig() {
-        return *getTunerConfig().getFirstHardwareConfiguration();
-    }
+    static TunerConfiguration getTunerConfig() { return *read(mConfigFilePath.c_str()); }
 
     static DataFlowConfiguration getDataFlowConfiguration() {
         return *getTunerConfig().getFirstDataFlowConfiguration();
diff --git a/tv/tuner/config/TunerTestingConfigReaderV1_1.h b/tv/tuner/config/TunerTestingConfigReaderV1_1.h
new file mode 100644
index 0000000..13d5303
--- /dev/null
+++ b/tv/tuner/config/TunerTestingConfigReaderV1_1.h
@@ -0,0 +1,185 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+#include "TunerTestingConfigReaderV1_0.h"
+
+using android::hardware::tv::tuner::V1_1::AudioStreamType;
+using android::hardware::tv::tuner::V1_1::AvStreamType;
+using android::hardware::tv::tuner::V1_1::FrontendDvbsScanType;
+using android::hardware::tv::tuner::V1_1::FrontendDvbsSettingsExt1_1;
+using android::hardware::tv::tuner::V1_1::FrontendDvbtSettingsExt1_1;
+using android::hardware::tv::tuner::V1_1::FrontendSettingsExt1_1;
+using android::hardware::tv::tuner::V1_1::FrontendStatusExt1_1;
+using android::hardware::tv::tuner::V1_1::FrontendStatusTypeExt1_1;
+using android::hardware::tv::tuner::V1_1::VideoStreamType;
+
+struct FrontendConfig1_1 {
+    FrontendConfig config1_0;
+    bool canConnectToCiCam;
+    uint32_t ciCamId;
+    FrontendSettingsExt1_1 settingsExt1_1;
+    vector<FrontendStatusTypeExt1_1> tuneStatusTypes;
+    vector<FrontendStatusExt1_1> expectTuneStatuses;
+};
+
+struct FilterConfig1_1 {
+    FilterConfig config1_0;
+    AvStreamType streamType;
+    uint32_t ipCid;
+    uint32_t monitorEventTypes;
+
+    bool operator<(const FilterConfig& /*c*/) const { return false; }
+};
+
+struct TunerTestingConfigReader1_1 {
+  public:
+    static void readFrontendConfig1_1(map<string, FrontendConfig1_1>& frontendMap) {
+        map<string, FrontendConfig> frontendMap1_0;
+        TunerTestingConfigReader1_0::readFrontendConfig1_0(frontendMap1_0);
+        for (auto it = frontendMap1_0.begin(); it != frontendMap1_0.end(); it++) {
+            frontendMap[it->first].config1_0 = it->second;
+        }
+
+        auto hardwareConfig = TunerTestingConfigReader1_0::getHardwareConfig();
+        if (hardwareConfig.hasFrontends()) {
+            // TODO: b/182519645 complete the tune status config
+            vector<FrontendStatusTypeExt1_1> types;
+            types.push_back(FrontendStatusTypeExt1_1::UEC);
+            types.push_back(FrontendStatusTypeExt1_1::IS_MISO);
+            vector<FrontendStatusExt1_1> statuses;
+            FrontendStatusExt1_1 status;
+            status.uec(4);
+            statuses.push_back(status);
+            status.isMiso(true);
+            statuses.push_back(status);
+
+            auto frontends = *hardwareConfig.getFirstFrontends();
+
+            for (auto feConfig : frontends.getFrontend()) {
+                string id = feConfig.getId();
+                switch (feConfig.getType()) {
+                    case FrontendTypeEnum::DVBS:
+                        frontendMap[id].settingsExt1_1.settingExt.dvbs(
+                                readDvbsFrontendSettings1_1(feConfig));
+                        break;
+                    case FrontendTypeEnum::DVBT: {
+                        frontendMap[id].settingsExt1_1.settingExt.dvbt(
+                                readDvbtFrontendSettings1_1(feConfig));
+                        break;
+                    }
+                    case FrontendTypeEnum::DTMB:
+                        frontendMap[id].config1_0.type = static_cast<FrontendType>(
+                                android::hardware::tv::tuner::V1_1::FrontendType::DTMB);
+                        break;
+                    case FrontendTypeEnum::UNKNOWN:
+                        ALOGW("[ConfigReader] invalid frontend type");
+                        return;
+                    default:
+                        ALOGW("[ConfigReader] fe already handled in 1_0 reader.");
+                        break;
+                }
+                if (feConfig.hasEndFrequency()) {
+                    frontendMap[id].settingsExt1_1.endFrequency =
+                            (uint32_t)feConfig.getEndFrequency();
+                }
+                // TODO: b/182519645 complete the tune status config
+                frontendMap[id].tuneStatusTypes = types;
+                frontendMap[id].expectTuneStatuses = statuses;
+                getCiCamInfo(feConfig, frontendMap[id].canConnectToCiCam, frontendMap[id].ciCamId);
+            }
+        }
+    }
+
+    static void readFilterConfig1_1(map<string, FilterConfig1_1>& filterMap) {
+        map<string, FilterConfig> filterMap1_0;
+        TunerTestingConfigReader1_0::readFilterConfig1_0(filterMap1_0);
+        for (auto it = filterMap1_0.begin(); it != filterMap1_0.end(); it++) {
+            filterMap[it->first].config1_0 = it->second;
+        }
+        auto hardwareConfig = TunerTestingConfigReader1_0::getHardwareConfig();
+        if (hardwareConfig.hasFilters()) {
+            auto filters = *hardwareConfig.getFirstFilters();
+            for (auto filterConfig : filters.getFilter()) {
+                string id = filterConfig.getId();
+                if (filterConfig.hasMonitorEventTypes()) {
+                    filterMap[id].monitorEventTypes = (uint32_t)filterConfig.getMonitorEventTypes();
+                }
+                if (filterConfig.hasAvFilterSettings_optional()) {
+                    AvStreamType type;
+                    auto av = filterConfig.getFirstAvFilterSettings_optional();
+                    if (av->hasAudioStreamType_optional()) {
+                        type.audio(static_cast<AudioStreamType>(av->getAudioStreamType_optional()));
+                        filterMap[id].streamType = type;
+                    }
+                    if (av->hasVideoStreamType_optional()) {
+                        type.video(static_cast<VideoStreamType>(av->getVideoStreamType_optional()));
+                        filterMap[id].streamType = type;
+                    }
+                }
+                if (filterConfig.hasIpFilterConfig_optional()) {
+                    auto ip = filterConfig.getFirstIpFilterConfig_optional();
+                    if (ip->hasIpCid()) {
+                        filterMap[id].ipCid = ip->getIpCid();
+                    }
+                }
+            }
+        }
+    }
+
+  private:
+    static void getCiCamInfo(Frontend feConfig, bool& canConnectToCiCam, uint32_t& ciCamId) {
+        if (!feConfig.hasConnectToCicamId()) {
+            canConnectToCiCam = false;
+            ciCamId = -1;
+        }
+        canConnectToCiCam = true;
+        ciCamId = static_cast<uint32_t>(feConfig.getConnectToCicamId());
+    }
+
+    static FrontendDvbsSettingsExt1_1 readDvbsFrontendSettings1_1(Frontend feConfig) {
+        FrontendDvbsSettingsExt1_1 dvbsSettings;
+        if (!feConfig.hasDvbsFrontendSettings_optional()) {
+            return dvbsSettings;
+        }
+        auto dvbs = feConfig.getFirstDvbsFrontendSettings_optional();
+        if (dvbs->hasScanType()) {
+            dvbsSettings.scanType = static_cast<FrontendDvbsScanType>(dvbs->getScanType());
+        }
+        if (dvbs->hasIsDiseqcRxMessage()) {
+            dvbsSettings.isDiseqcRxMessage = dvbs->getIsDiseqcRxMessage();
+        }
+        return dvbsSettings;
+    }
+
+    static FrontendDvbtSettingsExt1_1 readDvbtFrontendSettings1_1(Frontend feConfig) {
+        FrontendDvbtSettingsExt1_1 dvbtSettings;
+        if (!feConfig.hasDvbtFrontendSettings_optional()) {
+            return dvbtSettings;
+        }
+        auto dvbt = feConfig.getFirstDvbtFrontendSettings_optional();
+        auto trans = dvbt->getTransmissionMode();
+        dvbtSettings.transmissionMode =
+                static_cast<android::hardware::tv::tuner::V1_1::FrontendDvbtTransmissionMode>(
+                        trans);
+        if (dvbt->hasConstellation()) {
+            dvbtSettings.constellation =
+                    static_cast<android::hardware::tv::tuner::V1_1::FrontendDvbtConstellation>(
+                            dvbt->getConstellation());
+        }
+        return dvbtSettings;
+    }
+};
\ No newline at end of file
diff --git a/tv/tuner/config/api/current.txt b/tv/tuner/config/api/current.txt
index 4255a60..a9602e7 100644
--- a/tv/tuner/config/api/current.txt
+++ b/tv/tuner/config/api/current.txt
@@ -3,8 +3,12 @@
 
   public class AvFilterSettings {
     ctor public AvFilterSettings();
+    method @Nullable public short getAudioStreamType_optional();
     method @Nullable public boolean getIsPassthrough();
+    method @Nullable public short getVideoStreamType_optional();
+    method public void setAudioStreamType_optional(@Nullable short);
     method public void setIsPassthrough(@Nullable boolean);
+    method public void setVideoStreamType_optional(@Nullable short);
   }
 
   public class DataFlowConfiguration {
@@ -32,12 +36,14 @@
     method @Nullable public String getAudioFilterConnection();
     method @Nullable public String getDvrSoftwareFeConnection();
     method @Nullable public String getFrontendConnection();
+    method @Nullable public String getIpFilterConnection();
     method @Nullable public String getPcrFilterConnection();
     method @Nullable public String getSectionFilterConnection();
     method @Nullable public String getVideoFilterConnection();
     method public void setAudioFilterConnection(@Nullable String);
     method public void setDvrSoftwareFeConnection(@Nullable String);
     method public void setFrontendConnection(@Nullable String);
+    method public void setIpFilterConnection(@Nullable String);
     method public void setPcrFilterConnection(@Nullable String);
     method public void setSectionFilterConnection(@Nullable String);
     method public void setVideoFilterConnection(@Nullable String);
@@ -144,17 +150,32 @@
   public class DvbsFrontendSettings {
     ctor public DvbsFrontendSettings();
     method @Nullable public java.math.BigInteger getInputStreamId();
+    method @Nullable public boolean getIsDiseqcRxMessage();
+    method @Nullable public android.media.tuner.testing.configuration.V1_0.DvbsScanType getScanType();
     method @Nullable public java.math.BigInteger getSymbolRate();
     method public void setInputStreamId(@Nullable java.math.BigInteger);
+    method public void setIsDiseqcRxMessage(@Nullable boolean);
+    method public void setScanType(@Nullable android.media.tuner.testing.configuration.V1_0.DvbsScanType);
     method public void setSymbolRate(@Nullable java.math.BigInteger);
   }
 
+  public enum DvbsScanType {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.media.tuner.testing.configuration.V1_0.DvbsScanType DIRECT;
+    enum_constant public static final android.media.tuner.testing.configuration.V1_0.DvbsScanType DISEQC;
+    enum_constant public static final android.media.tuner.testing.configuration.V1_0.DvbsScanType JESS;
+    enum_constant public static final android.media.tuner.testing.configuration.V1_0.DvbsScanType UNDEFINED;
+    enum_constant public static final android.media.tuner.testing.configuration.V1_0.DvbsScanType UNICABLE;
+  }
+
   public class DvbtFrontendSettings {
     ctor public DvbtFrontendSettings();
     method @Nullable public java.math.BigInteger getBandwidth();
+    method @Nullable public java.math.BigInteger getConstellation();
     method @Nullable public java.math.BigInteger getIsHighPriority();
     method @Nullable public java.math.BigInteger getTransmissionMode();
     method public void setBandwidth(@Nullable java.math.BigInteger);
+    method public void setConstellation(@Nullable java.math.BigInteger);
     method public void setIsHighPriority(@Nullable java.math.BigInteger);
     method public void setTransmissionMode(@Nullable java.math.BigInteger);
   }
@@ -208,7 +229,9 @@
     method @Nullable public android.media.tuner.testing.configuration.V1_0.AvFilterSettings getAvFilterSettings_optional();
     method @Nullable public java.math.BigInteger getBufferSize();
     method @Nullable public String getId();
+    method @Nullable public android.media.tuner.testing.configuration.V1_0.IpFilterConfig getIpFilterConfig_optional();
     method @Nullable public android.media.tuner.testing.configuration.V1_0.FilterMainTypeEnum getMainType();
+    method @Nullable public java.math.BigInteger getMonitorEventTypes();
     method @Nullable public java.math.BigInteger getPid();
     method @Nullable public android.media.tuner.testing.configuration.V1_0.RecordFilterSettings getRecordFilterSettings_optional();
     method @Nullable public android.media.tuner.testing.configuration.V1_0.SectionFilterSettings getSectionFilterSettings_optional();
@@ -217,7 +240,9 @@
     method public void setAvFilterSettings_optional(@Nullable android.media.tuner.testing.configuration.V1_0.AvFilterSettings);
     method public void setBufferSize(@Nullable java.math.BigInteger);
     method public void setId(@Nullable String);
+    method public void setIpFilterConfig_optional(@Nullable android.media.tuner.testing.configuration.V1_0.IpFilterConfig);
     method public void setMainType(@Nullable android.media.tuner.testing.configuration.V1_0.FilterMainTypeEnum);
+    method public void setMonitorEventTypes(@Nullable java.math.BigInteger);
     method public void setPid(@Nullable java.math.BigInteger);
     method public void setRecordFilterSettings_optional(@Nullable android.media.tuner.testing.configuration.V1_0.RecordFilterSettings);
     method public void setSectionFilterSettings_optional(@Nullable android.media.tuner.testing.configuration.V1_0.SectionFilterSettings);
@@ -227,6 +252,7 @@
 
   public enum FilterMainTypeEnum {
     method @NonNull public String getRawName();
+    enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterMainTypeEnum IP;
     enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterMainTypeEnum MMTP;
     enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterMainTypeEnum TS;
   }
@@ -235,7 +261,11 @@
     method @NonNull public String getRawName();
     enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum AUDIO;
     enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum DOWNLOAD;
+    enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum IP;
+    enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum IP_PAYLOAD;
     enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum MMTP;
+    enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum NTP;
+    enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum PAYLOAD_THROUGH;
     enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum PCR;
     enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum PES;
     enum_constant public static final android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum RECORD;
@@ -334,6 +364,30 @@
     method @Nullable public java.util.List<android.media.tuner.testing.configuration.V1_0.TimeFilter> getTimeFilter();
   }
 
+  public class IpAddress {
+    ctor public IpAddress();
+    method @Nullable public java.util.List<java.lang.Short> getIp();
+    method @Nullable public boolean getIsIpV4();
+    method public void setIp(@Nullable java.util.List<java.lang.Short>);
+    method public void setIsIpV4(@Nullable boolean);
+  }
+
+  public class IpFilterConfig {
+    ctor public IpFilterConfig();
+    method @Nullable public boolean getDataPassthrough();
+    method @Nullable public android.media.tuner.testing.configuration.V1_0.IpAddress getDestIpAddress();
+    method @Nullable public long getDestPort();
+    method @Nullable public java.math.BigInteger getIpCid();
+    method @Nullable public android.media.tuner.testing.configuration.V1_0.IpAddress getSrcIpAddress();
+    method @Nullable public long getSrcPort();
+    method public void setDataPassthrough(@Nullable boolean);
+    method public void setDestIpAddress(@Nullable android.media.tuner.testing.configuration.V1_0.IpAddress);
+    method public void setDestPort(@Nullable long);
+    method public void setIpCid(@Nullable java.math.BigInteger);
+    method public void setSrcIpAddress(@Nullable android.media.tuner.testing.configuration.V1_0.IpAddress);
+    method public void setSrcPort(@Nullable long);
+  }
+
   public class Lnb {
     ctor public Lnb();
     method @Nullable public String getId();
diff --git a/tv/tuner/config/sample_tuner_vts_config.xml b/tv/tuner/config/sample_tuner_vts_config_1_0.xml
similarity index 100%
rename from tv/tuner/config/sample_tuner_vts_config.xml
rename to tv/tuner/config/sample_tuner_vts_config_1_0.xml
diff --git a/tv/tuner/config/sample_tuner_vts_config_1_1.xml b/tv/tuner/config/sample_tuner_vts_config_1_1.xml
new file mode 100644
index 0000000..191e51c
--- /dev/null
+++ b/tv/tuner/config/sample_tuner_vts_config_1_1.xml
@@ -0,0 +1,158 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!-- Copyright (C) 2021 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.
+-->
+
+<!-- The Sample Tuner Testing Configuration.
+    Name the customized xml with "tuner_vts_config.xml" and push into the device
+    "/vendor/etc" path. Please use "tuner_testing_dynamic_configuration.xsd" to verify the xml.
+    The version section contains a “version” tag in the form “major.minor” e.g version=”1.0”
+    This shows the tuner dynamic configuration version. -->
+<TunerConfiguration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
+    <!-- Hardware Configuration section contains the configurations of all the hardwares
+        that would be used in the tests. In the "dataFlowConfiguration" section, each data flow
+        under test has its required/optional hardwares. The ids configured in the
+        "dataFlowConfiguration" would be used to connect the hardware to each data flow test. -->
+    <hardwareConfiguration>
+        <!-- Frontends section:
+            This section contains configurations of all the frontends that would be used
+                in the tests.
+                - This section is optional and can be skipped to use the default fe settings.
+                - The default settings can be found in the sample_tuner_vts_configurations.xml.
+                - The users can also override the default frontend settings using id="FE_DEFAULT".
+                - The users can configure 1 or more frontend elements in the frontends sections.
+
+            Each frontend element contain the following attributes:
+                "id": unique id of the frontend that could be used to connect to the test the
+                    "dataFlowConfiguration"
+                "type": the frontend type. The enums are defined in the xsd.
+                "isSoftwareFrontend": if the test environment is using hardware or software
+                    frontend. If using software, a ts input file path needs to be configured.
+                "softwareFeInputPath": used as the source of the software frontend.
+                "connectToCicamId": if the device supports frontend connecting to cicam, the target
+                    cicam id needs to be configured here. Supported in Tuner 1.1 or higher.
+                "frequency": the frequency used to configure tune and scan.
+                "endFrequency": the end frequency of scan. Supported in Tuner 1.1 or higher.
+
+            Each frontend element also contains one and only one type-related "frontendSettings".
+                - The settings type should match the frontend "type" attribute.
+                - For example, when frontend type="DVBT", dvbtFrontendSettings can be configured.
+                - This is optional and skipping the settings would pass a setting with frequency
+                    config only to the hal.
+        -->
+        <frontends>
+            <frontend id="FE_DEFAULT" type="DVBT" isSoftwareFrontend="true"
+                      connectToCicamId="0" frequency="578000" endFrequency="800000">
+                <dvbtFrontendSettings bandwidth="8" transmissionMode="128" isHighPriority="1"/>
+            </frontend>
+            <frontend id="FE_DVBS_0" type="DVBS" isSoftwareFrontend="true"
+                      connectToCicamId="0" frequency="578000" endFrequency="800000">
+            </frontend>
+        </frontends>
+        <!-- Filter section:
+            This section contains configurations of all the filters that would be used in the tests.
+                - This section is optional and can be skipped to use the default filter settings.
+                - The default settings can be found in the sample_tuner_vts_configurations.xml.
+                - The users can also override the default filter settings using
+                - id="FILTER_AUDIO_DEFAULT" or "FILTER_VIDEO_DEFAULT".
+                - The users can configure 1 or more filter elements in the filters sections.
+
+            Each filter element contain the following attributes:
+                "id": unique id of the filter that could be used to connect to the test the
+                    "dataFlowConfiguration"
+                "mainType": the main filter type. The enums are defined in the xsd.
+                "subType": the sub filter type. The enums are defined in the xsd.
+                "bufferSize": the buffer size of the filter in hex.
+                "pid": the pid that would be used to configure the filter.
+                "useFMQ": if the filter uses FMQ.
+
+            Each filter element also contains at most one type-related "filterSettings".
+                - The settings type should match the filter "subType" attribute.
+                - For example, when filter subType is audio or video, the avFilterSettings can be
+                    configured.
+                - This is optional and skipping the settings would pass a setting with tpid config
+                    only to the hal.
+        -->
+        <filters>
+            <filter id="FILTER_AUDIO_DEFAULT" mainType="TS" subType="AUDIO"
+                    bufferSize="16777216" pid="257" useFMQ="false" monitorEventTypes="3">
+                <avFilterSettings isPassthrough="false">
+                    <audioStreamType>2</audioStreamType>
+                </avFilterSettings>
+            </filter>
+            <filter id="FILTER_VIDEO_DEFAULT" mainType="TS" subType="VIDEO"
+                    bufferSize="16777216" pid="256" useFMQ="false" monitorEventTypes="3">
+                <avFilterSettings isPassthrough="false">
+                    <videoStreamType>2</videoStreamType>
+                </avFilterSettings>
+            </filter>
+            <filter id="FILTER_TS_RECORD_0" mainType="TS" subType="RECORD"
+                    bufferSize="16777216" pid="257" useFMQ="false">
+                <recordFilterSettings tsIndexMask="1" scIndexType="NONE"/>
+            </filter>
+            <filter id="FILTER_IP_IP_0" mainType="IP" subType="IP" bufferSize="16777216" useFMQ="false">
+                <ipFilterConfig ipCid="1">
+                    <srcIpAddress isIpV4="true" ip="192 168 1 1"/>
+                    <destIpAddress isIpV4="true" ip="192 168 1 1"/>
+                </ipFilterConfig>
+            </filter>
+        </filters>
+        <!-- Dvr section:
+            This section contains configurations of all the dvrs that would be used in the tests.
+                - This section is optional and can be skipped if DVR is not supported.
+                - The users can configure 1 or more dvr elements in the dvrs sections.
+
+            Each dvr element contain the following attributes:
+                "id": unique id of the dvr that could be used to connect to the test the
+                    "dataFlowConfiguration"
+                "type": the dvr type.
+                "bufferSize": the dvr buffer size.
+                "statusMask": register callbacks of specific status.
+                "lowThreshold": the dvr status low threshold.
+                "highThreshold": the dvr status high threshold.
+                "dataFormat": the dvr data format.
+                "packetSize": the dvr packet size.
+                "inputFilePath": the dvr playback input file path. Only required in playback dvr.
+        -->
+        <dvrs>
+            <dvr id="DVR_PLAYBACK_0" type="PLAYBACK" bufferSize="4194304"
+                 statusMask="15" lowThreshold="4096" highThreshold="32767"
+                 dataFormat="TS" packetSize="188" inputFilePath="/data/local/tmp/segment000000.ts"/>
+            <dvr id="DVR_RECORD_0" type="RECORD" bufferSize="4194304"
+                 statusMask="15" lowThreshold="4096" highThreshold="32767"
+                 dataFormat="TS" packetSize="188"/>
+            <dvr id="DVR_PLAYBACK_1" type="PLAYBACK" bufferSize="4194304"
+                 statusMask="15" lowThreshold="4096" highThreshold="32767"
+                 dataFormat="ES" packetSize="188" inputFilePath="/data/local/tmp/test.es"/>
+        </dvrs>
+    </hardwareConfiguration>
+
+    <!-- Data flow configuration section connects each data flow under test to the ids of the
+        hardwares that would be used during the tests. -->
+    <dataFlowConfiguration>
+        <clearLiveBroadcast frontendConnection="FE_DEFAULT"
+                            audioFilterConnection="FILTER_AUDIO_DEFAULT"
+                            videoFilterConnection="FILTER_VIDEO_DEFAULT"
+                            ipFilterConnection="FILTER_IP_IP_0"
+                            dvrSoftwareFeConnection="DVR_PLAYBACK_0"/>
+        <scan frontendConnection="FE_DEFAULT"/>
+        <dvrPlayback dvrConnection="DVR_PLAYBACK_0"
+                     audioFilterConnection="FILTER_AUDIO_DEFAULT"
+                     videoFilterConnection="FILTER_VIDEO_DEFAULT"/>
+        <dvrRecord frontendConnection="FE_DEFAULT"
+                   recordFilterConnection="FILTER_TS_RECORD_0"
+                   dvrRecordConnection="DVR_RECORD_0"
+                   dvrSoftwareFeConnection="DVR_PLAYBACK_0"/>
+    </dataFlowConfiguration>
+</TunerConfiguration>
diff --git a/tv/tuner/config/tuner_testing_dynamic_configuration.xsd b/tv/tuner/config/tuner_testing_dynamic_configuration.xsd
index 3fe93ff..3303657 100644
--- a/tv/tuner/config/tuner_testing_dynamic_configuration.xsd
+++ b/tv/tuner/config/tuner_testing_dynamic_configuration.xsd
@@ -49,15 +49,27 @@
             <xs:enumeration value="DTMB"/>
         </xs:restriction>
     </xs:simpleType>
+    <xs:simpleType name="dvbsScanType">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="UNDEFINED" />
+            <xs:enumeration value="DIRECT" />
+            <xs:enumeration value="DISEQC" />
+            <xs:enumeration value="UNICABLE"/>
+            <xs:enumeration value="JESS"/>
+        </xs:restriction>
+    </xs:simpleType>
 
     <xs:complexType name="dvbtFrontendSettings">
         <xs:attribute name="bandwidth" type="xs:nonNegativeInteger" use="required"/>
         <xs:attribute name="transmissionMode" type="xs:nonNegativeInteger" use="required"/>
         <xs:attribute name="isHighPriority" type="xs:nonNegativeInteger" use="required"/>
+        <xs:attribute name="constellation" type="xs:nonNegativeInteger" use="optional"/>
     </xs:complexType>
     <xs:complexType name="dvbsFrontendSettings">
         <xs:attribute name="inputStreamId" type="xs:nonNegativeInteger" use="required"/>
         <xs:attribute name="symbolRate" type="xs:nonNegativeInteger" use="required"/>
+        <xs:attribute name="scanType" type="dvbsScanType" use="optional"/>
+        <xs:attribute name="isDiseqcRxMessage" type="xs:boolean" use="optional"/>
     </xs:complexType>
 
     <xs:complexType name="frontend">
@@ -137,13 +149,19 @@
             <xs:enumeration value="SC_HEVC"/>
         </xs:restriction>
     </xs:simpleType>
+    <xs:simpleType name="monitoEvents">
+        <xs:restriction base="xs:integer">
+            <xs:minInclusive value="0"/>
+            <xs:maxInclusive value="3"/>
+        </xs:restriction>
+    </xs:simpleType>
 
     <xs:simpleType name="filterMainTypeEnum">
         <xs:restriction base="xs:string">
             <xs:enumeration value="TS" />
             <xs:enumeration value="MMTP" />
-            <!-- TODO: b/182519645 Support IP/TLV/ALP filter config
             <xs:enumeration value="IP"/>
+            <!-- TODO: b/182519645 Support TLV/ALP filter config
             <xs:enumeration value="TLV"/>
             <xs:enumeration value="ALP"/-->
         </xs:restriction>
@@ -161,10 +179,37 @@
             <xs:enumeration value="TEMI"/>
             <xs:enumeration value="MMTP"/>
             <xs:enumeration value="DOWNLOAD"/>
+            <xs:enumeration value="IP"/>
+            <xs:enumeration value="NTP"/>
+            <xs:enumeration value="IP_PAYLOAD"/>
+            <xs:enumeration value="PAYLOAD_THROUGH"/>            
         </xs:restriction>
     </xs:simpleType>
 
+    <xs:simpleType name="ip">
+        <xs:list itemType="xs:unsignedByte"/>
+    </xs:simpleType>
+    <xs:complexType name="ipAddress">
+        <xs:attribute name="isIpV4" type="xs:boolean" use="required"/>
+        <xs:attribute name="ip" type="ip" use="required"/>
+    </xs:complexType>
+    <xs:complexType name="ipFilterConfig">
+        <xs:sequence>
+            <xs:element name="srcIpAddress" type="ipAddress" minOccurs="1" maxOccurs="1"/>
+            <xs:element name="destIpAddress" type="ipAddress" minOccurs="1" maxOccurs="1"/>
+        </xs:sequence>
+        <xs:attribute name="srcPort" type="xs:unsignedInt" use="optional"/>
+        <xs:attribute name="destPort" type="xs:unsignedInt" use="optional"/>
+        <!-- True if the ip filter data goes to the next filter directly -->
+        <xs:attribute name="dataPassthrough" type="xs:boolean" use="optional"/>
+        <xs:attribute name="ipCid" type="xs:nonNegativeInteger" use="optional"/>
+    </xs:complexType>
+
     <xs:complexType name="avFilterSettings">
+        <xs:choice minOccurs="0" maxOccurs="1">
+            <xs:element name="audioStreamType" type="xs:unsignedByte"/>
+            <xs:element name="videoStreamType" type="xs:unsignedByte"/>
+        </xs:choice>
         <xs:attribute name="isPassthrough" type="xs:boolean" use="required"/>
     </xs:complexType>
     <xs:complexType name="sectionFilterSettings">
@@ -197,20 +242,28 @@
                         config only to the hal.
             </xs:documentation>
         </xs:annotation>
-        <xs:choice minOccurs="0" maxOccurs="1">
-            <!-- TODO: b/182519645 finish all the filter settings structures. -->
-            <xs:element name="sectionFilterSettings" type="sectionFilterSettings"/>
-            <xs:element name="avFilterSettings" type="avFilterSettings"/>
-            <xs:element name="recordFilterSettings" type="recordFilterSettings"/>
-            <!--xs:element name="pes" type="pesFilterSettings"/>
-            <xs:element name="download" type="downloadFilterSettings"/-->
-        </xs:choice>
+        <xs:sequence>
+            <!-- Main filter type related config -->
+            <xs:choice minOccurs="0" maxOccurs="1">
+                <xs:element name="ipFilterConfig" type="ipFilterConfig"/>
+            </xs:choice>
+            <!-- Sub filter type related config -->
+            <xs:choice minOccurs="0" maxOccurs="1">
+                <!-- TODO: b/182519645 finish all the filter settings structures. -->
+                <xs:element name="sectionFilterSettings" type="sectionFilterSettings"/>
+                <xs:element name="avFilterSettings" type="avFilterSettings"/>
+                <xs:element name="recordFilterSettings" type="recordFilterSettings"/>
+                <!--xs:element name="pes" type="pesFilterSettings"/>
+                <xs:element name="download" type="downloadFilterSettings"/-->
+            </xs:choice>
+        </xs:sequence>
         <xs:attribute name="id" type="filterId" use="required"/>
         <xs:attribute name="mainType" type="filterMainTypeEnum" use="required"/>
         <xs:attribute name="subType" type="filterSubTypeEnum" use="required"/>
         <xs:attribute name="bufferSize" type="xs:nonNegativeInteger" use="required"/>
         <xs:attribute name="pid" type="xs:nonNegativeInteger" use="optional"/>
         <xs:attribute name="useFMQ" type="xs:boolean" use="required"/>
+        <xs:attribute name="monitorEventTypes" type="monitoEvents" use="optional"/>
     </xs:complexType>
 
     <!-- DVR SESSION -->
@@ -396,7 +449,7 @@
         </xs:annotation>
         <xs:attribute name="id" type="descramblerId" use="required"/>
         <xs:attribute name="casSystemId" type="xs:nonNegativeInteger" use="required"/>
-        <xs:attribute name="provisionStr" type="xs:string" use="required"/>
+        <xs:attribute name="provisionStr" type="xs:string" use="optional"/>
         <xs:attribute name="sesstionPrivatData" type="sessionPrivateData" use="optional"/>
     </xs:complexType>
 
@@ -541,6 +594,7 @@
                     <xs:attribute name="videoFilterConnection" type="filterId" use="required"/>
                     <xs:attribute name="pcrFilterConnection" type="filterId" use="optional"/>
                     <xs:attribute name="sectionFilterConnection" type="filterId" use="optional"/>
+                    <xs:attribute name="ipFilterConnection" type="filterId" use="optional"/>
                     <!-- TODO: b/182519645 allow the users to insert extra filters -->
                     <!-- DVR is only required when the frontend is using the software input -->
                     <xs:attribute name="dvrSoftwareFeConnection" type="dvrId" use="optional"/>
diff --git a/wifi/1.5/default/wifi_legacy_hal.cpp b/wifi/1.5/default/wifi_legacy_hal.cpp
index 848fbd6..5074252 100644
--- a/wifi/1.5/default/wifi_legacy_hal.cpp
+++ b/wifi/1.5/default/wifi_legacy_hal.cpp
@@ -1677,7 +1677,7 @@
 }
 
 wifi_error WifiLegacyHal::triggerSubsystemRestart() {
-    return global_func_table_.wifi_trigger_subsystem_restart();
+    return global_func_table_.wifi_trigger_subsystem_restart(global_handle_);
 }
 
 void WifiLegacyHal::invalidate() {
diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.0/vts/functional/supplicant_sta_iface_hidl_test.cpp
index b9c7b30..bd0e8cf 100644
--- a/wifi/supplicant/1.0/vts/functional/supplicant_sta_iface_hidl_test.cpp
+++ b/wifi/supplicant/1.0/vts/functional/supplicant_sta_iface_hidl_test.cpp
@@ -26,6 +26,7 @@
 
 #include "supplicant_hidl_call_util.h"
 #include "supplicant_hidl_test_utils.h"
+#include <cutils/properties.h>
 
 using ::android::sp;
 using ::android::hardware::hidl_array;
@@ -62,7 +63,7 @@
 constexpr uint32_t kTestRadioWorkFrequency = 2412;
 constexpr uint32_t kTestRadioWorkTimeout = 8;
 constexpr uint32_t kTestRadioWorkId = 16;
-constexpr int8_t kTestCountryCode[] = {'U', 'S'};
+int8_t kTestCountryCode[] = {'U', 'S'};
 constexpr uint8_t kTestWpsDeviceType[] = {[0 ... 7] = 0x01};
 constexpr uint16_t kTestWpsConfigMethods = 0xffff;
 }  // namespace
@@ -444,6 +445,10 @@
  * SetCountryCode.
  */
 TEST_P(SupplicantStaIfaceHidlTest, SetCountryCode) {
+    std::array<char, PROPERTY_VALUE_MAX> buffer;
+    property_get("ro.boot.wificountrycode", buffer.data(), "US");
+    kTestCountryCode[0] = buffer.data()[0];
+    kTestCountryCode[1] = buffer.data()[1];
     sta_iface_->setCountryCode(
         kTestCountryCode, [](const SupplicantStatus& status) {
             EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
diff --git a/wifi/supplicant/1.4/ISupplicantStaNetwork.hal b/wifi/supplicant/1.4/ISupplicantStaNetwork.hal
index 4f95213..4dfe8e6 100644
--- a/wifi/supplicant/1.4/ISupplicantStaNetwork.hal
+++ b/wifi/supplicant/1.4/ISupplicantStaNetwork.hal
@@ -41,7 +41,7 @@
         /**
          * GCMP-128 Pairwise Cipher
          */
-        GCMP_128 = 1 << 9,
+        GCMP_128 = 1 << 6,
     };
 
     /**
@@ -51,7 +51,7 @@
         /**
          * GCMP-128 Group Cipher
          */
-        GCMP_128 = 1 << 9,
+        GCMP_128 = 1 << 6,
     };
 
     /**