Merge "Update the OWNERS file of VTS module VtsHalHealthV2_0TargetTest"
diff --git a/atrace/1.0/vts/functional/OWNERS b/atrace/1.0/vts/functional/OWNERS
new file mode 100644
index 0000000..31043aa
--- /dev/null
+++ b/atrace/1.0/vts/functional/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 837454
+wvw@google.com
diff --git a/audio/common/all-versions/test/utility/Android.bp b/audio/common/all-versions/test/utility/Android.bp
index 1602d25..757f8a8 100644
--- a/audio/common/all-versions/test/utility/Android.bp
+++ b/audio/common/all-versions/test/utility/Android.bp
@@ -25,7 +25,7 @@
 
 cc_library_static {
     name: "android.hardware.audio.common.test.utility",
-    defaults : ["hidl_defaults"],
+    defaults: ["hidl_defaults"],
     srcs: ["src/ValidateXml.cpp"],
     cflags: [
         "-O0",
@@ -34,7 +34,34 @@
     ],
     local_include_dirs: ["include/utility"],
     export_include_dirs: ["include"],
-    shared_libs: ["libxml2", "liblog"],
+    shared_libs: [
+        "libxml2",
+        "liblog",
+    ],
     static_libs: ["libgtest"],
     export_static_lib_headers: ["libgtest"],
 }
+
+// Note: this isn't a VTS test, but rather a unit test
+// to verify correctness of test utilities.
+cc_test {
+    name: "android.hardware.audio.common.test.utility_tests",
+    host_supported: true,
+    local_include_dirs: ["include/utility"],
+    srcs: [
+        "src/ValidateXml.cpp",
+        "tests/utility_tests.cpp",
+    ],
+    cflags: [
+        "-Werror",
+        "-Wall",
+        "-g",
+    ],
+    shared_libs: [
+        "libbase",
+        "libxml2",
+        "liblog",
+    ],
+    static_libs: ["libgtest"],
+    test_suites: ["general-tests"],
+}
diff --git a/audio/common/all-versions/test/utility/TEST_MAPPING b/audio/common/all-versions/test/utility/TEST_MAPPING
new file mode 100644
index 0000000..0bc1871
--- /dev/null
+++ b/audio/common/all-versions/test/utility/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "presubmit": [
+    {
+      "name": "android.hardware.audio.common.test.utility_tests"
+    }
+  ]
+}
diff --git a/audio/common/all-versions/test/utility/src/ValidateXml.cpp b/audio/common/all-versions/test/utility/src/ValidateXml.cpp
index a866104..f111c01 100644
--- a/audio/common/all-versions/test/utility/src/ValidateXml.cpp
+++ b/audio/common/all-versions/test/utility/src/ValidateXml.cpp
@@ -112,7 +112,8 @@
         return ::testing::AssertionFailure() << "Failed to parse xml\n" << context();
     }
 
-    if (xmlXIncludeProcess(doc.get()) == -1) {
+    // Process 'include' directives w/o modifying elements loaded from included files.
+    if (xmlXIncludeProcessFlags(doc.get(), XML_PARSE_NOBASEFIX) == -1) {
         return ::testing::AssertionFailure() << "Failed to resolve xincludes in xml\n" << context();
     }
 
diff --git a/audio/common/all-versions/test/utility/tests/utility_tests.cpp b/audio/common/all-versions/test/utility/tests/utility_tests.cpp
new file mode 100644
index 0000000..c523066
--- /dev/null
+++ b/audio/common/all-versions/test/utility/tests/utility_tests.cpp
@@ -0,0 +1,176 @@
+/*
+ * 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 <android-base/file.h>
+#include <gtest/gtest.h>
+
+#include <ValidateXml.h>
+
+using ::android::hardware::audio::common::test::utility::validateXml;
+
+const char* XSD_SOURCE =
+        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+        "<xs:schema version=\"2.0\""
+        "           elementFormDefault=\"qualified\""
+        "           attributeFormDefault=\"unqualified\""
+        "           xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">"
+        "  <xs:element name=\"audioPolicyConfiguration\">"
+        "    <xs:complexType>"
+        "      <xs:sequence>"
+        "        <xs:element name=\"modules\">"
+        "          <xs:complexType>"
+        "            <xs:sequence>"
+        "              <xs:element name=\"module\" maxOccurs=\"unbounded\">"
+        "                <xs:complexType>"
+        "                  <xs:attribute name=\"name\" type=\"xs:string\" use=\"required\"/>"
+        "                </xs:complexType>"
+        "              </xs:element>"
+        "            </xs:sequence>"
+        "          </xs:complexType>"
+        "        </xs:element>"
+        "      </xs:sequence>"
+        "    </xs:complexType>"
+        "  </xs:element>"
+        "</xs:schema>";
+
+const char* INVALID_XML_SOURCE =
+        "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"
+        "<audioPolicyKonfiguration />";
+
+const char* VALID_XML_SOURCE =
+        "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"
+        "<audioPolicyConfiguration>"
+        "  <modules>"
+        "    <module name=\"aaa\" />"
+        "    %s"
+        "  </modules>"
+        "</audioPolicyConfiguration>";
+
+const char* MODULE_SOURCE = "<module name=\"bbb\" />";
+
+const char* XI_INCLUDE = "<xi:include xmlns:xi=\"http://www.w3.org/2001/XInclude\" href=\"%s\" />";
+
+const char* XML_INCLUDED_SOURCE = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>%s";
+
+namespace {
+
+std::string substitute(const char* fmt, const char* param) {
+    std::string buffer(static_cast<size_t>(strlen(fmt) + strlen(param)), '\0');
+    snprintf(buffer.data(), buffer.size(), fmt, param);
+    return buffer;
+}
+
+std::string substitute(const char* fmt, const std::string& s) {
+    return substitute(fmt, s.c_str());
+}
+
+}  // namespace
+
+TEST(ValidateXml, InvalidXml) {
+    TemporaryFile xml;
+    ASSERT_TRUE(android::base::WriteStringToFile(INVALID_XML_SOURCE, xml.path)) << strerror(errno);
+    TemporaryFile xsd;
+    ASSERT_TRUE(android::base::WriteStringToFile(XSD_SOURCE, xsd.path)) << strerror(errno);
+    EXPECT_FALSE(validateXml("xml", "xsd", xml.path, xsd.path));
+}
+
+TEST(ValidateXml, ValidXml) {
+    TemporaryFile xml;
+    ASSERT_TRUE(
+            android::base::WriteStringToFile(substitute(VALID_XML_SOURCE, MODULE_SOURCE), xml.path))
+            << strerror(errno);
+    TemporaryFile xsd;
+    ASSERT_TRUE(android::base::WriteStringToFile(XSD_SOURCE, xsd.path)) << strerror(errno);
+    EXPECT_TRUE(validateXml("xml", "xsd", xml.path, xsd.path));
+}
+
+TEST(ValidateXml, IncludeAbsolutePath) {
+    TemporaryFile xmlInclude;
+    ASSERT_TRUE(android::base::WriteStringToFile(substitute(XML_INCLUDED_SOURCE, MODULE_SOURCE),
+                                                 xmlInclude.path))
+            << strerror(errno);
+    TemporaryFile xml;
+    ASSERT_TRUE(android::base::WriteStringToFile(
+            substitute(VALID_XML_SOURCE, substitute(XI_INCLUDE, xmlInclude.path)), xml.path))
+            << strerror(errno);
+    TemporaryFile xsd;
+    ASSERT_TRUE(android::base::WriteStringToFile(XSD_SOURCE, xsd.path)) << strerror(errno);
+    EXPECT_TRUE(validateXml("xml", "xsd", xml.path, xsd.path));
+}
+
+TEST(ValidateXml, IncludeSameDirRelativePath) {
+    TemporaryFile xmlInclude;
+    ASSERT_TRUE(android::base::WriteStringToFile(substitute(XML_INCLUDED_SOURCE, MODULE_SOURCE),
+                                                 xmlInclude.path))
+            << strerror(errno);
+    TemporaryFile xml;
+    ASSERT_EQ(android::base::Dirname(xml.path), android::base::Dirname(xmlInclude.path));
+    ASSERT_TRUE(android::base::WriteStringToFile(
+            substitute(VALID_XML_SOURCE,
+                       substitute(XI_INCLUDE, android::base::Basename(xmlInclude.path))),
+            xml.path))
+            << strerror(errno);
+    TemporaryFile xsd;
+    ASSERT_TRUE(android::base::WriteStringToFile(XSD_SOURCE, xsd.path)) << strerror(errno);
+    EXPECT_TRUE(validateXml("xml", "xsd", xml.path, xsd.path));
+}
+
+TEST(ValidateXml, IncludeSubdirRelativePath) {
+    TemporaryDir xmlIncludeDir;
+    TemporaryFile xmlInclude(xmlIncludeDir.path);
+    ASSERT_TRUE(android::base::WriteStringToFile(substitute(XML_INCLUDED_SOURCE, MODULE_SOURCE),
+                                                 xmlInclude.path))
+            << strerror(errno);
+    TemporaryFile xml;
+    ASSERT_EQ(android::base::Dirname(xml.path), android::base::Dirname(xmlIncludeDir.path));
+    ASSERT_TRUE(android::base::WriteStringToFile(
+            substitute(VALID_XML_SOURCE,
+                       substitute(XI_INCLUDE, android::base::Basename(xmlIncludeDir.path) + "/" +
+                                                      android::base::Basename(xmlInclude.path))),
+            xml.path))
+            << strerror(errno);
+    TemporaryFile xsd;
+    ASSERT_TRUE(android::base::WriteStringToFile(XSD_SOURCE, xsd.path)) << strerror(errno);
+    EXPECT_TRUE(validateXml("xml", "xsd", xml.path, xsd.path));
+}
+
+TEST(ValidateXml, IncludeParentDirRelativePath) {
+    // An XML file from a subdirectory includes a file from the parent directory using '..' syntax.
+    TemporaryFile xmlInclude;
+    ASSERT_TRUE(android::base::WriteStringToFile(substitute(XML_INCLUDED_SOURCE, MODULE_SOURCE),
+                                                 xmlInclude.path))
+            << strerror(errno);
+    TemporaryDir xmlIncludeDir;
+    TemporaryFile xmlParentInclude(xmlIncludeDir.path);
+    ASSERT_TRUE(android::base::WriteStringToFile(
+            substitute(XML_INCLUDED_SOURCE,
+                       substitute(XI_INCLUDE, "../" + android::base::Basename(xmlInclude.path))),
+            xmlParentInclude.path))
+            << strerror(errno);
+    TemporaryFile xml;
+    ASSERT_EQ(android::base::Dirname(xml.path), android::base::Dirname(xmlInclude.path));
+    ASSERT_EQ(android::base::Dirname(xml.path), android::base::Dirname(xmlIncludeDir.path));
+    ASSERT_TRUE(android::base::WriteStringToFile(
+            substitute(
+                    VALID_XML_SOURCE,
+                    substitute(XI_INCLUDE, android::base::Basename(xmlIncludeDir.path) + "/" +
+                                                   android::base::Basename(xmlParentInclude.path))),
+            xml.path))
+            << strerror(errno);
+    TemporaryFile xsd;
+    ASSERT_TRUE(android::base::WriteStringToFile(XSD_SOURCE, xsd.path)) << strerror(errno);
+    EXPECT_TRUE(validateXml("xml", "xsd", xml.path, xsd.path));
+}
diff --git a/audio/core/all-versions/default/StreamIn.cpp b/audio/core/all-versions/default/StreamIn.cpp
index 599f3c3..17621a9 100644
--- a/audio/core/all-versions/default/StreamIn.cpp
+++ b/audio/core/all-versions/default/StreamIn.cpp
@@ -412,9 +412,9 @@
     }
 
     // Create and launch the thread.
-    auto tempReadThread =
-        std::make_unique<ReadThread>(&mStopReadThread, mStream, tempCommandMQ.get(),
-                                     tempDataMQ.get(), tempStatusMQ.get(), tempElfGroup.get());
+    sp<ReadThread> tempReadThread =
+            new ReadThread(&mStopReadThread, mStream, tempCommandMQ.get(), tempDataMQ.get(),
+                           tempStatusMQ.get(), tempElfGroup.get());
     if (!tempReadThread->init()) {
         ALOGW("failed to start reader thread: %s", strerror(-status));
         sendError(Result::INVALID_ARGUMENTS);
@@ -430,7 +430,7 @@
     mCommandMQ = std::move(tempCommandMQ);
     mDataMQ = std::move(tempDataMQ);
     mStatusMQ = std::move(tempStatusMQ);
-    mReadThread = tempReadThread.release();
+    mReadThread = tempReadThread;
     mEfGroup = tempElfGroup.release();
 #if MAJOR_VERSION <= 6
     threadInfo.pid = getpid();
diff --git a/audio/core/all-versions/default/StreamOut.cpp b/audio/core/all-versions/default/StreamOut.cpp
index 4fe6601..c23922d 100644
--- a/audio/core/all-versions/default/StreamOut.cpp
+++ b/audio/core/all-versions/default/StreamOut.cpp
@@ -398,9 +398,9 @@
     }
 
     // Create and launch the thread.
-    auto tempWriteThread =
-        std::make_unique<WriteThread>(&mStopWriteThread, mStream, tempCommandMQ.get(),
-                                      tempDataMQ.get(), tempStatusMQ.get(), tempElfGroup.get());
+    sp<WriteThread> tempWriteThread =
+            new WriteThread(&mStopWriteThread, mStream, tempCommandMQ.get(), tempDataMQ.get(),
+                            tempStatusMQ.get(), tempElfGroup.get());
     if (!tempWriteThread->init()) {
         ALOGW("failed to start writer thread: %s", strerror(-status));
         sendError(Result::INVALID_ARGUMENTS);
@@ -416,7 +416,7 @@
     mCommandMQ = std::move(tempCommandMQ);
     mDataMQ = std::move(tempDataMQ);
     mStatusMQ = std::move(tempStatusMQ);
-    mWriteThread = tempWriteThread.release();
+    mWriteThread = tempWriteThread;
     mEfGroup = tempElfGroup.release();
 #if MAJOR_VERSION <= 6
     threadInfo.pid = getpid();
diff --git a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp
index b96cc83..28bcd0b 100644
--- a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp
@@ -53,6 +53,11 @@
         GTEST_SKIP() << "getMicrophones is not supported";  // returns
     }
     ASSERT_OK(res);
+
+#if MAJOR_VERSION <= 6
+    // In V7, 'getActiveMicrophones' is tested by the 'MicrophoneInfoInputStream'
+    // test which uses the actual configuration of the device.
+
     if (microphones.size() > 0) {
         // When there is microphone on the phone, try to open an input stream
         // and query for the active microphones.
@@ -60,30 +65,13 @@
             "Make sure getMicrophones always succeeds"
             "and getActiveMicrophones always succeeds when recording from these microphones.");
         AudioConfig config{};
-#if MAJOR_VERSION <= 6
         config.channelMask = mkEnumBitfield(AudioChannelMask::IN_MONO);
         config.sampleRateHz = 8000;
         config.format = AudioFormat::PCM_16_BIT;
         auto flags = hidl_bitfield<AudioInputFlag>(AudioInputFlag::NONE);
         const SinkMetadata initMetadata = {{{.source = AudioSource::MIC, .gain = 1}}};
-#elif MAJOR_VERSION >= 7
-        config.base.channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_IN_MONO);
-        config.base.sampleRateHz = 8000;
-        config.base.format = toString(xsd::AudioFormat::AUDIO_FORMAT_PCM_16_BIT);
-        hidl_vec<hidl_string> flags;
-        const SinkMetadata initMetadata = {
-                {{.source = toString(xsd::AudioSource::AUDIO_SOURCE_MIC),
-                  .gain = 1,
-                  .tags = {},
-                  .channelMask = toString(xsd::AudioChannelMask::AUDIO_CHANNEL_IN_MONO)}}};
-#endif
         for (auto microphone : microphones) {
-#if MAJOR_VERSION <= 6
             if (microphone.deviceAddress.device != AudioDevice::IN_BUILTIN_MIC) {
-#elif MAJOR_VERSION >= 7
-            if (xsd::stringToAudioDevice(microphone.deviceAddress.deviceType) !=
-                xsd::AudioDevice::AUDIO_DEVICE_IN_BUILTIN_MIC) {
-#endif
                 continue;
             }
             sp<IStreamIn> stream;
@@ -106,6 +94,7 @@
             EXPECT_NE(0U, activeMicrophones.size());
         }
     }
+#endif  // MAJOR_VERSION <= 6
 }
 
 TEST_P(AudioHidlDeviceTest, SetConnectedState) {
diff --git a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
index 0b3098b..0cc6a5b 100644
--- a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
@@ -839,3 +839,64 @@
                         ::testing::ValuesIn(getInputDevicePcmOnlyConfigParameters()),
                         &DeviceConfigParameterToString);
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(PcmOnlyConfigInputStreamTest);
+
+static const std::vector<DeviceConfigParameter>& getBuiltinMicConfigParameters() {
+    static const std::vector<DeviceConfigParameter> parameters = [] {
+        auto allParams = getInputDeviceConfigParameters();
+        std::vector<DeviceConfigParameter> builtinMicParams;
+        std::copy_if(allParams.begin(), allParams.end(), std::back_inserter(builtinMicParams),
+                     [](auto cfg) {
+                         // The built in mic may participate in various scenarios:
+                         // FAST, HW_HOTWORD, MMAP NOIRQ, which are indicated by flags.
+                         // We are only interested in testing the simplest scenario w/o any flags.
+                         if (!std::get<PARAM_FLAGS>(cfg).empty()) return false;
+                         auto maybeSourceDevice = getCachedPolicyConfig().getSourceDeviceForMixPort(
+                                 std::get<PARAM_DEVICE_NAME>(std::get<PARAM_DEVICE>(cfg)),
+                                 std::get<PARAM_PORT_NAME>(cfg));
+                         return maybeSourceDevice.has_value() &&
+                                xsd::stringToAudioDevice(maybeSourceDevice.value().deviceType) ==
+                                        xsd::AudioDevice::AUDIO_DEVICE_IN_BUILTIN_MIC;
+                     });
+        return builtinMicParams;
+    }();
+    return parameters;
+}
+
+class MicrophoneInfoInputStreamTest : public InputStreamTest {};
+
+TEST_P(MicrophoneInfoInputStreamTest, GetActiveMicrophones) {
+    doc::test(
+            "Make sure getActiveMicrophones always succeeds when recording "
+            "from the built-in microphone.");
+    hidl_vec<MicrophoneInfo> microphones;
+    ASSERT_OK(getDevice()->getMicrophones(returnIn(res, microphones)));
+    if (res == Result::NOT_SUPPORTED) {
+        GTEST_SKIP() << "getMicrophones is not supported";  // returns
+    }
+    ASSERT_OK(res);
+
+    auto maybeSourceAddress =
+            getCachedPolicyConfig().getSourceDeviceForMixPort(getDeviceName(), getMixPortName());
+    ASSERT_TRUE(maybeSourceAddress.has_value())
+            << "No source device found for mix port " << getMixPortName() << " (module "
+            << getDeviceName() << ")";
+
+    for (auto microphone : microphones) {
+        if (microphone.deviceAddress == maybeSourceAddress.value()) {
+            StreamReader reader(stream.get(), stream->getBufferSize());
+            ASSERT_TRUE(reader.start());
+            reader.pause();  // This ensures that at least one read has happened.
+            EXPECT_FALSE(reader.hasError());
+
+            hidl_vec<MicrophoneInfo> activeMicrophones;
+            ASSERT_OK(stream->getActiveMicrophones(returnIn(res, activeMicrophones)));
+            ASSERT_OK(res);
+            EXPECT_NE(0U, activeMicrophones.size());
+        }
+    }
+}
+
+INSTANTIATE_TEST_CASE_P(MicrophoneInfoInputStream, MicrophoneInfoInputStreamTest,
+                        ::testing::ValuesIn(getBuiltinMicConfigParameters()),
+                        &DeviceConfigParameterToString);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MicrophoneInfoInputStreamTest);
diff --git a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
index aa7fd8e..340903a 100644
--- a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
+++ b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
@@ -1390,6 +1390,9 @@
                 config.channelMask.value(channelMask);
                 auto ret = stream->setAudioProperties(config);
                 EXPECT_TRUE(ret.isOk());
+                if (ret == Result::NOT_SUPPORTED) {
+                    GTEST_SKIP() << "setAudioProperties is not supported";
+                }
                 EXPECT_EQ(Result::OK, ret)
                         << profile.format << "; " << sampleRate << "; " << channelMask;
             }
diff --git a/audio/effect/all-versions/OWNERS b/audio/effect/all-versions/OWNERS
index 24071af..f9a2d6b 100644
--- a/audio/effect/all-versions/OWNERS
+++ b/audio/effect/all-versions/OWNERS
@@ -1,2 +1,3 @@
+# Bug component: 48436
 elaurent@google.com
 mnaganov@google.com
diff --git a/authsecret/aidl/default/Android.bp b/authsecret/aidl/default/Android.bp
index a6c0bc4..7ce83fd 100644
--- a/authsecret/aidl/default/Android.bp
+++ b/authsecret/aidl/default/Android.bp
@@ -34,7 +34,7 @@
         "AuthSecret.cpp",
     ],
     shared_libs: [
-        "android.hardware.authsecret-V1-ndk_platform",
+        "android.hardware.authsecret-V1-ndk",
         "libbase",
         "libbinder_ndk",
     ],
diff --git a/authsecret/aidl/vts/Android.bp b/authsecret/aidl/vts/Android.bp
index dca7046..5ec9947 100644
--- a/authsecret/aidl/vts/Android.bp
+++ b/authsecret/aidl/vts/Android.bp
@@ -30,7 +30,7 @@
         "use_libaidlvintf_gtest_helper_static",
     ],
     srcs: ["VtsHalAuthSecretTargetTest.cpp"],
-    static_libs: ["android.hardware.authsecret-V1-ndk_platform"],
+    static_libs: ["android.hardware.authsecret-V1-ndk"],
     shared_libs: ["libbinder_ndk"],
     test_suites: [
         "general-tests",
diff --git a/automotive/occupant_awareness/aidl/default/Android.bp b/automotive/occupant_awareness/aidl/default/Android.bp
index 4db43bb..66af9de 100644
--- a/automotive/occupant_awareness/aidl/default/Android.bp
+++ b/automotive/occupant_awareness/aidl/default/Android.bp
@@ -36,6 +36,6 @@
         "libbase",
         "libbinder_ndk",
         "libutils",
-        "android.hardware.automotive.occupant_awareness-V1-ndk_platform",
+        "android.hardware.automotive.occupant_awareness-V1-ndk",
     ],
 }
diff --git a/automotive/occupant_awareness/aidl/mock/Android.bp b/automotive/occupant_awareness/aidl/mock/Android.bp
index 275eb22..b804622 100644
--- a/automotive/occupant_awareness/aidl/mock/Android.bp
+++ b/automotive/occupant_awareness/aidl/mock/Android.bp
@@ -36,6 +36,6 @@
         "libbase",
         "libbinder_ndk",
         "libutils",
-        "android.hardware.automotive.occupant_awareness-V1-ndk_platform",
+        "android.hardware.automotive.occupant_awareness-V1-ndk",
     ],
 }
diff --git a/bluetooth/1.0/default/Android.bp b/bluetooth/1.0/default/Android.bp
index 70a42b7..ee368fd 100644
--- a/bluetooth/1.0/default/Android.bp
+++ b/bluetooth/1.0/default/Android.bp
@@ -22,7 +22,7 @@
     default_applicable_licenses: ["hardware_interfaces_license"],
 }
 
-cc_library_shared {
+cc_library {
     name: "android.hardware.bluetooth@1.0-impl",
     defaults: ["hidl_defaults"],
     vendor: true,
diff --git a/bluetooth/audio/2.0/default/A2dpSoftwareAudioProvider.cpp b/bluetooth/audio/2.0/default/A2dpSoftwareAudioProvider.cpp
index f71a73e..0c0b85f 100644
--- a/bluetooth/audio/2.0/default/A2dpSoftwareAudioProvider.cpp
+++ b/bluetooth/audio/2.0/default/A2dpSoftwareAudioProvider.cpp
@@ -32,10 +32,14 @@
 using ::android::bluetooth::audio::BluetoothAudioSessionReport;
 using ::android::hardware::Void;
 
+// Here the buffer size is based on SBC
 static constexpr uint32_t kPcmFrameSize = 4;  // 16 bits per sample / stereo
-static constexpr uint32_t kPcmFrameCount = 128;
+// SBC is 128, and here choose the LCM of 16, 24, and 32
+static constexpr uint32_t kPcmFrameCount = 96;
 static constexpr uint32_t kRtpFrameSize = kPcmFrameSize * kPcmFrameCount;
-static constexpr uint32_t kRtpFrameCount = 7;  // max counts by 1 tick (20ms)
+// The max counts by 1 tick (20ms) for SBC is about 7. Since using 96 for the
+// PCM counts, here we just choose a greater number
+static constexpr uint32_t kRtpFrameCount = 10;
 static constexpr uint32_t kBufferSize = kRtpFrameSize * kRtpFrameCount;
 static constexpr uint32_t kBufferCount = 2;  // double buffer
 static constexpr uint32_t kDataMqSize = kBufferSize * kBufferCount;
diff --git a/bluetooth/audio/2.1/default/A2dpSoftwareAudioProvider.cpp b/bluetooth/audio/2.1/default/A2dpSoftwareAudioProvider.cpp
index a37176b..4928cea 100644
--- a/bluetooth/audio/2.1/default/A2dpSoftwareAudioProvider.cpp
+++ b/bluetooth/audio/2.1/default/A2dpSoftwareAudioProvider.cpp
@@ -34,10 +34,14 @@
 using ::android::hardware::Void;
 using ::android::hardware::bluetooth::audio::V2_0::AudioConfiguration;
 
+// Here the buffer size is based on SBC
 static constexpr uint32_t kPcmFrameSize = 4;  // 16 bits per sample / stereo
-static constexpr uint32_t kPcmFrameCount = 128;
+// SBC is 128, and here we choose the LCM of 16, 24, and 32
+static constexpr uint32_t kPcmFrameCount = 96;
 static constexpr uint32_t kRtpFrameSize = kPcmFrameSize * kPcmFrameCount;
-static constexpr uint32_t kRtpFrameCount = 7;  // max counts by 1 tick (20ms)
+// The max counts by 1 tick (20ms) for SBC is about 7. Since using 96 for the
+// PCM counts, here we just choose a greater number
+static constexpr uint32_t kRtpFrameCount = 10;
 static constexpr uint32_t kBufferSize = kRtpFrameSize * kRtpFrameCount;
 static constexpr uint32_t kBufferCount = 2;  // double buffer
 static constexpr uint32_t kDataMqSize = kBufferSize * kBufferCount;
diff --git a/camera/provider/2.4/vts/functional/OWNERS b/camera/provider/2.4/vts/functional/OWNERS
new file mode 100644
index 0000000..479f465
--- /dev/null
+++ b/camera/provider/2.4/vts/functional/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 41727
+epeev@google.com
diff --git a/common/fmq/aidl/Android.bp b/common/fmq/aidl/Android.bp
index 1ab724f..cebf1ce 100644
--- a/common/fmq/aidl/Android.bp
+++ b/common/fmq/aidl/Android.bp
@@ -24,7 +24,7 @@
     stability: "vintf",
     backend: {
         java: {
-            enabled: false,
+            sdk_version: "module_current",
         },
         cpp: {
             enabled: false,
diff --git a/common/support/Android.bp b/common/support/Android.bp
index 730798d..b24893b 100644
--- a/common/support/Android.bp
+++ b/common/support/Android.bp
@@ -15,7 +15,7 @@
     srcs: ["NativeHandle.cpp"],
     export_include_dirs: ["include"],
     shared_libs: [
-        "android.hardware.common-V2-ndk_platform",
+        "android.hardware.common-V2-ndk",
         "libcutils",
     ],
     apex_available: [
@@ -31,7 +31,7 @@
     defaults: ["libbinder_ndk_host_user"],
     srcs: ["test.cpp"],
     static_libs: [
-        "android.hardware.common-V2-ndk_platform",
+        "android.hardware.common-V2-ndk",
         "libaidlcommonsupport",
     ],
     shared_libs: [
diff --git a/compatibility_matrices/Android.bp b/compatibility_matrices/Android.bp
index da55347..a59be21 100644
--- a/compatibility_matrices/Android.bp
+++ b/compatibility_matrices/Android.bp
@@ -80,8 +80,6 @@
         "compatibility_matrix.current.xml",
     ],
     kernel_configs: [
-        "kernel_config_current_4.19",
-        "kernel_config_current_5.4",
         "kernel_config_current_5.10",
     ],
 }
diff --git a/gnss/2.0/vts/functional/OWNERS b/gnss/2.0/vts/functional/OWNERS
new file mode 100644
index 0000000..b831eb4
--- /dev/null
+++ b/gnss/2.0/vts/functional/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 393449
+yuhany@google.com
diff --git a/graphics/mapper/4.0/vts/functional/Android.bp b/graphics/mapper/4.0/vts/functional/Android.bp
index 11ebdc5..032bc0f 100644
--- a/graphics/mapper/4.0/vts/functional/Android.bp
+++ b/graphics/mapper/4.0/vts/functional/Android.bp
@@ -28,7 +28,7 @@
     defaults: ["VtsHalTargetTestDefaults"],
     srcs: ["VtsHalGraphicsMapperV4_0TargetTest.cpp"],
     static_libs: [
-        "android.hardware.graphics.common-V2-ndk_platform",
+        "android.hardware.graphics.common-V2-ndk",
         "android.hardware.graphics.mapper@4.0-vts",
         "libgralloctypes",
         "libsync",
diff --git a/health/storage/1.0/vts/functional/OWNERS b/health/storage/1.0/vts/functional/OWNERS
new file mode 100644
index 0000000..8f66979
--- /dev/null
+++ b/health/storage/1.0/vts/functional/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 30545
+elsk@google.com
+jaegeuk@google.com
diff --git a/health/storage/aidl/default/Android.bp b/health/storage/aidl/default/Android.bp
index 819b885..7cfabb0 100644
--- a/health/storage/aidl/default/Android.bp
+++ b/health/storage/aidl/default/Android.bp
@@ -29,7 +29,7 @@
     shared_libs: [
         "libbase",
         "libbinder_ndk",
-        "android.hardware.health.storage-V1-ndk_platform",
+        "android.hardware.health.storage-V1-ndk",
     ],
     static_libs: [
         "libfstab",
diff --git a/health/storage/aidl/vts/functional/Android.bp b/health/storage/aidl/vts/functional/Android.bp
index be3eac7..fe15170 100644
--- a/health/storage/aidl/vts/functional/Android.bp
+++ b/health/storage/aidl/vts/functional/Android.bp
@@ -34,7 +34,7 @@
         "libbinder_ndk",
     ],
     static_libs: [
-        "android.hardware.health.storage-V1-ndk_platform",
+        "android.hardware.health.storage-V1-ndk",
     ],
     header_libs: [
         "libhealth_storage_test_common_headers",
diff --git a/health/utils/libhealth2impl/BinderHealth.cpp b/health/utils/libhealth2impl/BinderHealth.cpp
index 625d0e0..8ec8962 100644
--- a/health/utils/libhealth2impl/BinderHealth.cpp
+++ b/health/utils/libhealth2impl/BinderHealth.cpp
@@ -35,10 +35,9 @@
 namespace V2_1 {
 namespace implementation {
 
-bool IsDeadObjectLogged(const Return<void>& ret) {
+bool IsDeadObject(const Return<void>& ret) {
     if (ret.isOk()) return false;
     if (ret.isDeadObject()) return true;
-    LOG(ERROR) << "Cannot call healthInfoChanged* on callback: " << ret.description();
     return false;
 }
 
@@ -77,7 +76,7 @@
             return;
         }
         auto ret = wrapped->Notify(health_info);
-        if (IsDeadObjectLogged(ret)) {
+        if (IsDeadObject(ret)) {
             // Remove callback reference.
             std::lock_guard<decltype(callbacks_lock_)> lock(callbacks_lock_);
             auto it = std::find_if(callbacks_.begin(), callbacks_.end(),
@@ -133,7 +132,7 @@
     std::unique_lock<decltype(callbacks_lock_)> lock(callbacks_lock_);
     for (auto it = callbacks_.begin(); it != callbacks_.end();) {
         auto ret = (*it)->Notify(health_info);
-        if (IsDeadObjectLogged(ret)) {
+        if (IsDeadObject(ret)) {
             it = callbacks_.erase(it);
         } else {
             ++it;
diff --git a/identity/aidl/default/Android.bp b/identity/aidl/default/Android.bp
index 28c4893..3de8d30 100644
--- a/identity/aidl/default/Android.bp
+++ b/identity/aidl/default/Android.bp
@@ -39,8 +39,8 @@
         "libsoft_attestation_cert",
         "libpuresoftkeymasterdevice",
         "android.hardware.identity-support-lib",
-        "android.hardware.identity-V3-ndk_platform",
-        "android.hardware.keymaster-V3-ndk_platform",
+        "android.hardware.identity-V3-ndk",
+        "android.hardware.keymaster-V3-ndk",
     ],
 }
 
@@ -100,8 +100,8 @@
         "libsoft_attestation_cert",
         "libpuresoftkeymasterdevice",
         "android.hardware.identity-support-lib",
-        "android.hardware.identity-V3-ndk_platform",
-        "android.hardware.keymaster-V3-ndk_platform",
+        "android.hardware.identity-V3-ndk",
+        "android.hardware.keymaster-V3-ndk",
         "android.hardware.identity-libeic-hal-common",
         "android.hardware.identity-libeic-library",
     ],
@@ -127,7 +127,7 @@
         "-DEIC_DEBUG",
     ],
     local_include_dirs: [
-         "common",
+        "common",
     ],
     shared_libs: [
         "liblog",
diff --git a/identity/aidl/vts/Android.bp b/identity/aidl/vts/Android.bp
index 61d15d2..e5de91e 100644
--- a/identity/aidl/vts/Android.bp
+++ b/identity/aidl/vts/Android.bp
@@ -42,7 +42,7 @@
         "android.hardware.identity-support-lib",
         "android.hardware.identity-V3-cpp",
         "android.hardware.keymaster-V3-cpp",
-        "android.hardware.keymaster-V3-ndk_platform",
+        "android.hardware.keymaster-V3-ndk",
         "libkeymaster4support",
         "libkeymaster4_1support",
     ],
diff --git a/light/aidl/default/Android.bp b/light/aidl/default/Android.bp
index 459b8e2..2ccf140 100644
--- a/light/aidl/default/Android.bp
+++ b/light/aidl/default/Android.bp
@@ -16,7 +16,7 @@
     shared_libs: [
         "libbase",
         "libbinder_ndk",
-        "android.hardware.light-V1-ndk_platform",
+        "android.hardware.light-V1-ndk",
     ],
     srcs: [
         "Lights.cpp",
diff --git a/memtrack/aidl/android/hardware/memtrack/IMemtrack.aidl b/memtrack/aidl/android/hardware/memtrack/IMemtrack.aidl
index e78d4d7..88b090b 100644
--- a/memtrack/aidl/android/hardware/memtrack/IMemtrack.aidl
+++ b/memtrack/aidl/android/hardware/memtrack/IMemtrack.aidl
@@ -31,21 +31,36 @@
  * accounting for stride, bit depth, rounding up to page size, etc.
  *
  * The following getMemory() categories are important for memory accounting in
- * `dumpsys meminfo` and should be reported as described below:
+ * Android frameworks (e.g. `dumpsys meminfo`) and should be reported as described
+ * below:
  *
  * - MemtrackType::GRAPHICS and MemtrackRecord::FLAG_SMAPS_UNACCOUNTED
- *     This should report the PSS of all DMA buffers mapped by the process
- *     with the specified PID. This PSS can be calculated using ReadDmaBufPss()
- *     form libdmabufinfo.
+ *     This should report the PSS of all CPU-Mapped DMA-BUFs (buffers mapped into
+ *     the process address space) and all GPU-Mapped DMA-BUFs (buffers mapped into
+ *     the GPU device address space on behalf of the process), removing any overlap
+ *     between the CPU-mapped and GPU-mapped sets.
  *
  * - MemtrackType::GL and MemtrackRecord::FLAG_SMAPS_UNACCOUNTED
  *     This category should report all GPU private allocations for the specified
  *     PID that are not accounted in /proc/<pid>/smaps.
  *
+ *     getMemory() called with PID 0 should report the global total GPU-private
+ *     memory, for MemtrackType::GL and MemtrackRecord::FLAG_SMAPS_UNACCOUNTED.
+ *
+ *     getMemory() called with PID 0 for a MemtrackType other than GL should
+ *     report 0.
+ *
  * - MemtrackType::OTHER and MemtrackRecord::FLAG_SMAPS_UNACCOUNTED
  *     Any other memory not accounted for in /proc/<pid>/smaps if any, otherwise
  *     this should return 0.
  *
+ * SMAPS_UNACCOUNTED memory should also include memory that is mapped with
+ * VM_PFNMAP flag set. For these mappings PSS and RSS are reported as 0 in smaps.
+ * Such mappings have no backing page structs from which PSS/RSS can be calculated.
+ *
+ * Any memtrack operation that is not supported should return a binder status with
+ * exception code EX_UNSUPPORTED_OPERATION.
+ *
  * Constructor for the interface should be used to perform memtrack management
  * setup actions and must be called once before any calls to getMemory().
  */
diff --git a/memtrack/aidl/default/Android.bp b/memtrack/aidl/default/Android.bp
index 7a7feea..6c77177 100644
--- a/memtrack/aidl/default/Android.bp
+++ b/memtrack/aidl/default/Android.bp
@@ -30,7 +30,7 @@
     shared_libs: [
         "libbase",
         "libbinder_ndk",
-        "android.hardware.memtrack-V1-ndk_platform",
+        "android.hardware.memtrack-V1-ndk",
     ],
     srcs: [
         "main.cpp",
diff --git a/memtrack/aidl/vts/Android.bp b/memtrack/aidl/vts/Android.bp
index 8614b47..f54388a 100644
--- a/memtrack/aidl/vts/Android.bp
+++ b/memtrack/aidl/vts/Android.bp
@@ -19,7 +19,7 @@
         "libvintf",
     ],
     static_libs: [
-        "android.hardware.memtrack-V1-ndk_platform",
+        "android.hardware.memtrack-V1-ndk",
     ],
     test_suites: [
         "vts",
diff --git a/neuralnetworks/1.3/vts/functional/Android.bp b/neuralnetworks/1.3/vts/functional/Android.bp
index f975250..1382bdb 100644
--- a/neuralnetworks/1.3/vts/functional/Android.bp
+++ b/neuralnetworks/1.3/vts/functional/Android.bp
@@ -66,7 +66,7 @@
         "VtsHalNeuralNetworksV1_0_utils",
         "VtsHalNeuralNetworksV1_2_utils",
         "VtsHalNeuralNetworksV1_3_utils",
-        "android.hardware.neuralnetworks-V1-ndk_platform",
+        "android.hardware.neuralnetworks-V1-ndk",
         "android.hardware.neuralnetworks@1.0",
         "android.hardware.neuralnetworks@1.1",
         "android.hardware.neuralnetworks@1.2",
diff --git a/neuralnetworks/aidl/utils/Android.bp b/neuralnetworks/aidl/utils/Android.bp
index 0ccc711..57d047b 100644
--- a/neuralnetworks/aidl/utils/Android.bp
+++ b/neuralnetworks/aidl/utils/Android.bp
@@ -31,14 +31,14 @@
     export_include_dirs: ["include"],
     cflags: ["-Wthread-safety"],
     static_libs: [
-        "android.hardware.graphics.common-V2-ndk_platform",
+        "android.hardware.graphics.common-V2-ndk",
         "libaidlcommonsupport",
         "libarect",
         "neuralnetworks_types",
         "neuralnetworks_utils_hal_common",
     ],
     shared_libs: [
-        "android.hardware.neuralnetworks-V1-ndk_platform",
+        "android.hardware.neuralnetworks-V1-ndk",
         "libbinder_ndk",
         "libhidlbase",
         "libnativewindow",
@@ -52,9 +52,9 @@
         "test/*.cpp",
     ],
     static_libs: [
-        "android.hardware.common-V2-ndk_platform",
-        "android.hardware.graphics.common-V2-ndk_platform",
-        "android.hardware.neuralnetworks-V1-ndk_platform",
+        "android.hardware.common-V2-ndk",
+        "android.hardware.graphics.common-V2-ndk",
+        "android.hardware.neuralnetworks-V1-ndk",
         "libaidlcommonsupport",
         "libgmock",
         "libneuralnetworks_common",
diff --git a/neuralnetworks/aidl/utils/src/Device.cpp b/neuralnetworks/aidl/utils/src/Device.cpp
index 0fd453b..e80de0b 100644
--- a/neuralnetworks/aidl/utils/src/Device.cpp
+++ b/neuralnetworks/aidl/utils/src/Device.cpp
@@ -119,7 +119,7 @@
                           << numberOfCacheFiles.numDataCache << " vs " << nn::kMaxNumberOfCacheFiles
                           << ")";
     }
-    return std::make_pair(numberOfCacheFiles.numDataCache, numberOfCacheFiles.numModelCache);
+    return std::make_pair(numberOfCacheFiles.numModelCache, numberOfCacheFiles.numDataCache);
 }
 
 }  // namespace
diff --git a/neuralnetworks/aidl/utils/test/DeviceTest.cpp b/neuralnetworks/aidl/utils/test/DeviceTest.cpp
index e53b0a8..f121aca 100644
--- a/neuralnetworks/aidl/utils/test/DeviceTest.cpp
+++ b/neuralnetworks/aidl/utils/test/DeviceTest.cpp
@@ -58,7 +58,7 @@
 const std::shared_ptr<BnDevice> kInvalidDevice;
 constexpr PerformanceInfo kNoPerformanceInfo = {.execTime = std::numeric_limits<float>::max(),
                                                 .powerUsage = std::numeric_limits<float>::max()};
-constexpr NumberOfCacheFiles kNumberOfCacheFiles = {.numModelCache = nn::kMaxNumberOfCacheFiles,
+constexpr NumberOfCacheFiles kNumberOfCacheFiles = {.numModelCache = nn::kMaxNumberOfCacheFiles - 1,
                                                     .numDataCache = nn::kMaxNumberOfCacheFiles};
 
 constexpr auto makeStatusOk = [] { return ndk::ScopedAStatus::ok(); };
@@ -300,6 +300,21 @@
     EXPECT_EQ(result.error().code, nn::ErrorStatus::DEAD_OBJECT);
 }
 
+TEST(DeviceTest, getNumberOfCacheFilesNeeded) {
+    // setup call
+    const auto mockDevice = createMockDevice();
+    EXPECT_CALL(*mockDevice, getNumberOfCacheFilesNeeded(_)).Times(1);
+
+    // run test
+    const auto result = Device::create(kName, mockDevice);
+
+    // verify result
+    ASSERT_TRUE(result.has_value());
+    constexpr auto kNumberOfCacheFilesPair = std::make_pair<uint32_t, uint32_t>(
+            kNumberOfCacheFiles.numModelCache, kNumberOfCacheFiles.numDataCache);
+    EXPECT_EQ(result.value()->getNumberOfCacheFilesNeeded(), kNumberOfCacheFilesPair);
+}
+
 TEST(DeviceTest, getNumberOfCacheFilesNeededError) {
     // setup call
     const auto mockDevice = createMockDevice();
diff --git a/neuralnetworks/aidl/vts/functional/Android.bp b/neuralnetworks/aidl/vts/functional/Android.bp
index d5b150a..8fa9756 100644
--- a/neuralnetworks/aidl/vts/functional/Android.bp
+++ b/neuralnetworks/aidl/vts/functional/Android.bp
@@ -49,9 +49,9 @@
         "libvndksupport",
     ],
     static_libs: [
-        "android.hardware.common-V2-ndk_platform",
-        "android.hardware.graphics.common-V2-ndk_platform",
-        "android.hardware.neuralnetworks-V1-ndk_platform",
+        "android.hardware.common-V2-ndk",
+        "android.hardware.graphics.common-V2-ndk",
+        "android.hardware.neuralnetworks-V1-ndk",
         "android.hidl.allocator@1.0",
         "android.hidl.memory@1.0",
         "libaidlcommonsupport",
diff --git a/neuralnetworks/utils/common/Android.bp b/neuralnetworks/utils/common/Android.bp
index 2ed1e40..a08e770 100644
--- a/neuralnetworks/utils/common/Android.bp
+++ b/neuralnetworks/utils/common/Android.bp
@@ -35,7 +35,7 @@
         "neuralnetworks_types",
     ],
     shared_libs: [
-        "android.hardware.neuralnetworks-V1-ndk_platform",
+        "android.hardware.neuralnetworks-V1-ndk",
         "libhidlbase",
         "libnativewindow",
         "libbinder_ndk",
diff --git a/neuralnetworks/utils/service/Android.bp b/neuralnetworks/utils/service/Android.bp
index 5f36dff..653e51a 100644
--- a/neuralnetworks/utils/service/Android.bp
+++ b/neuralnetworks/utils/service/Android.bp
@@ -39,7 +39,7 @@
         "neuralnetworks_utils_hal_common",
     ],
     shared_libs: [
-        "android.hardware.neuralnetworks-V1-ndk_platform",
+        "android.hardware.neuralnetworks-V1-ndk",
         "android.hardware.neuralnetworks@1.0",
         "android.hardware.neuralnetworks@1.1",
         "android.hardware.neuralnetworks@1.2",
diff --git a/oemlock/aidl/default/Android.bp b/oemlock/aidl/default/Android.bp
index 84136fe..063199a 100644
--- a/oemlock/aidl/default/Android.bp
+++ b/oemlock/aidl/default/Android.bp
@@ -34,7 +34,7 @@
         "OemLock.cpp",
     ],
     shared_libs: [
-        "android.hardware.oemlock-V1-ndk_platform",
+        "android.hardware.oemlock-V1-ndk",
         "libbase",
         "libbinder_ndk",
     ],
diff --git a/oemlock/aidl/vts/Android.bp b/oemlock/aidl/vts/Android.bp
index 840d20a..eb999a9 100644
--- a/oemlock/aidl/vts/Android.bp
+++ b/oemlock/aidl/vts/Android.bp
@@ -34,7 +34,7 @@
         "libbinder_ndk",
         "libbase",
     ],
-    static_libs: ["android.hardware.oemlock-V1-ndk_platform"],
+    static_libs: ["android.hardware.oemlock-V1-ndk"],
     test_suites: [
         "general-tests",
         "vts",
diff --git a/power/stats/aidl/default/Android.bp b/power/stats/aidl/default/Android.bp
index 417dc97..7c0caf3 100644
--- a/power/stats/aidl/default/Android.bp
+++ b/power/stats/aidl/default/Android.bp
@@ -30,7 +30,7 @@
     shared_libs: [
         "libbase",
         "libbinder_ndk",
-        "android.hardware.power.stats-V1-ndk_platform",
+        "android.hardware.power.stats-V1-ndk",
     ],
     srcs: [
         "main.cpp",
diff --git a/power/stats/aidl/vts/Android.bp b/power/stats/aidl/vts/Android.bp
index b556548..b9a395b 100644
--- a/power/stats/aidl/vts/Android.bp
+++ b/power/stats/aidl/vts/Android.bp
@@ -32,7 +32,7 @@
         "libbinder_ndk",
     ],
     static_libs: [
-        "android.hardware.power.stats-V1-ndk_platform",
+        "android.hardware.power.stats-V1-ndk",
     ],
     test_suites: [
         "general-tests",
diff --git a/radio/1.5/vts/functional/radio_hidl_hal_api.cpp b/radio/1.5/vts/functional/radio_hidl_hal_api.cpp
index 0b49b36..d108951 100644
--- a/radio/1.5/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.5/vts/functional/radio_hidl_hal_api.cpp
@@ -1251,8 +1251,20 @@
  * Test IRadio.getBarringInfo() for the response returned.
  */
 TEST_P(RadioHidlTest_v1_5, getBarringInfo) {
+    // If the previous setRadioPower_1_5_emergencyCall_cancelled test has just finished.
+    // Due to radio restarting, modem may need a little more time to acquire network service
+    // and barring infos. If voice status is in-service, waiting 3s to get barring infos ready.
+    // Or waiting 10s if voice status is not in-service.
     serial = GetRandomSerialNumber();
+    radio_v1_5->getVoiceRegistrationState_1_5(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    if (isVoiceInService(radioRsp_v1_5->voiceRegResp.regState)) {
+        sleep(BARRING_INFO_MAX_WAIT_TIME_SECONDS);
+    } else {
+        sleep(VOICE_SERVICE_MAX_WAIT_TIME_SECONDS);
+    }
 
+    serial = GetRandomSerialNumber();
     Return<void> res = radio_v1_5->getBarringInfo(serial);
     EXPECT_EQ(std::cv_status::no_timeout, wait());
     EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
diff --git a/radio/1.5/vts/functional/radio_hidl_hal_utils_v1_5.h b/radio/1.5/vts/functional/radio_hidl_hal_utils_v1_5.h
index 87ce675..65442ca 100644
--- a/radio/1.5/vts/functional/radio_hidl_hal_utils_v1_5.h
+++ b/radio/1.5/vts/functional/radio_hidl_hal_utils_v1_5.h
@@ -51,6 +51,8 @@
 #define TIMEOUT_PERIOD 75
 #define MODEM_EMERGENCY_CALL_ESTABLISH_TIME 3
 #define MODEM_EMERGENCY_CALL_DISCONNECT_TIME 3
+#define VOICE_SERVICE_MAX_WAIT_TIME_SECONDS 10
+#define BARRING_INFO_MAX_WAIT_TIME_SECONDS 3
 
 #define RADIO_SERVICE_NAME "slot1"
 
@@ -69,6 +71,7 @@
 
     // Call
     hidl_vec<::android::hardware::radio::V1_2::Call> currentCalls;
+    ::android::hardware::radio::V1_2::VoiceRegStateResult voiceRegResp;
 
     // Modem
     bool isModemEnabled;
diff --git a/radio/1.5/vts/functional/radio_response.cpp b/radio/1.5/vts/functional/radio_response.cpp
index 9b6d450..3d6fc17 100644
--- a/radio/1.5/vts/functional/radio_response.cpp
+++ b/radio/1.5/vts/functional/radio_response.cpp
@@ -763,8 +763,9 @@
 
 Return<void> RadioResponse_v1_5::getVoiceRegistrationStateResponse_1_2(
         const RadioResponseInfo& info,
-        const ::android::hardware::radio::V1_2::VoiceRegStateResult& /*voiceRegResponse*/) {
+        const ::android::hardware::radio::V1_2::VoiceRegStateResult& voiceRegResponse) {
     rspInfo = info;
+    voiceRegResp = voiceRegResponse;
     parent_v1_5.notify(info.serial);
     return Void();
 }
@@ -989,8 +990,9 @@
 
 Return<void> RadioResponse_v1_5::getVoiceRegistrationStateResponse_1_5(
         const RadioResponseInfo& info,
-        const ::android::hardware::radio::V1_5::RegStateResult& /*regResponse*/) {
+        const ::android::hardware::radio::V1_5::RegStateResult& regResponse) {
     rspInfo = info;
+    voiceRegResp.regState = regResponse.regState;
     parent_v1_5.notify(info.serial);
     return Void();
 }
diff --git a/rebootescrow/aidl/default/Android.bp b/rebootescrow/aidl/default/Android.bp
index 1f67a3e..4409314 100644
--- a/rebootescrow/aidl/default/Android.bp
+++ b/rebootescrow/aidl/default/Android.bp
@@ -29,7 +29,7 @@
     shared_libs: [
         "libbase",
         "libbinder_ndk",
-        "android.hardware.rebootescrow-V1-ndk_platform",
+        "android.hardware.rebootescrow-V1-ndk",
     ],
     export_include_dirs: ["include"],
     srcs: [
@@ -56,7 +56,7 @@
     shared_libs: [
         "libbase",
         "libbinder_ndk",
-        "android.hardware.rebootescrow-V1-ndk_platform",
+        "android.hardware.rebootescrow-V1-ndk",
     ],
     static_libs: [
         "libhadamardutils",
diff --git a/security/keymint/aidl/android/hardware/security/keymint/DeviceInfo.aidl b/security/keymint/aidl/android/hardware/security/keymint/DeviceInfo.aidl
index 32d69cd..b0761bf 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/DeviceInfo.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/DeviceInfo.aidl
@@ -44,6 +44,12 @@
      *         ? "vendor_patch_level" : uint,                   // YYYYMMDD
      *         "version" : 1,                      // The CDDL schema version.
      *         "security_level" : "tee" / "strongbox"
+     *         "att_id_state": "locked" / "open",  // Attestation IDs State. If "locked", this
+     *                                             // indicates a device's attestable IDs are
+     *                                             // factory-locked and immutable. If "open",
+     *                                             // this indicates the device is still in a
+     *                                             // provisionable state and the attestable IDs
+     *                                             // are not yet frozen.
      *     }
      */
     byte[] deviceInfo;
diff --git a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
index 88b2a26..1849723 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
@@ -275,6 +275,10 @@
      *   must return ErrorCode::INVALID_ARGUMENT.  The values 3 and 65537 must be supported.  It is
      *   recommended to support all prime values up to 2^64.
      *
+     * o Tag::CERTIFICATE_NOT_BEFORE and Tag::CERTIFICATE_NOT_AFTER specify the valid date range for
+     *   the returned X.509 certificate holding the public key. If omitted, generateKey must return
+     *   ErrorCode::MISSING_NOT_BEFORE or ErrorCode::MISSING_NOT_AFTER.
+     *
      * The following parameters are not necessary to generate a usable RSA key, but generateKey must
      * not return an error if they are omitted:
      *
@@ -295,6 +299,10 @@
      * Tag::EC_CURVE must be provided to generate an ECDSA key.  If it is not provided, generateKey
      * must return ErrorCode::UNSUPPORTED_KEY_SIZE. TEE IKeyMintDevice implementations must support
      * all curves.  StrongBox implementations must support P_256.
+
+     * Tag::CERTIFICATE_NOT_BEFORE and Tag::CERTIFICATE_NOT_AFTER must be provided to specify the
+     * valid date range for the returned X.509 certificate holding the public key. If omitted,
+     * generateKey must return ErrorCode::MISSING_NOT_BEFORE or ErrorCode::MISSING_NOT_AFTER.
      *
      * == AES Keys ==
      *
diff --git a/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl b/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl
index 31dbb28..24cdbc1 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl
@@ -158,20 +158,7 @@
      *         payload: bstr .cbor BccPayload
      *     ]
      *
-     *     VerifiedDeviceInfo = {
-     *         ? "brand" : tstr,
-     *         ? "manufacturer" : tstr,
-     *         ? "product" : tstr,
-     *         ? "model" : tstr,
-     *         ? "board" : tstr,
-     *         ? "device" : tstr,
-     *         ? "vb_state" : "green" / "yellow" / "orange",
-     *         ? "bootloader_state" : "locked" / "unlocked",
-     *         ? "os_version" : tstr,
-     *         ? "system_patch_level" : uint,        // YYYYMMDD
-     *         ? "boot_patch_level" : uint,          // YYYYMMDD
-     *         ? "vendor_patch_level" : uint,        // YYYYMMDD
-     *     }
+     *     VerifiedDeviceInfo = DeviceInfo  // See DeviceInfo.aidl
      *
      *     PubKeyX25519 = {                 // COSE_Key
      *          1 : 1,                      // Key type : Octet Key Pair
diff --git a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl
index 972ce2e..b28ebcb 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl
@@ -286,7 +286,7 @@
      *
      * Must be hardware-enforced.
      *
-     * TODO(b/191458710): find out if this tag is still supported.
+     * TODO(b/191738660): Remove in KeyMint V2. Currently only used for FDE.
      */
     MIN_SECONDS_BETWEEN_OPS = TagType.UINT | 403,
 
@@ -477,12 +477,12 @@
 
     /**
      * Tag::TRUSTED_CONFIRMATION_REQUIRED is only applicable to keys with KeyPurpose SIGN, and
-     *  specifies that this key must not be usable unless the user provides confirmation of the data
-     *  to be signed.  Confirmation is proven to keyMint via an approval token.  See
-     *  CONFIRMATION_TOKEN, as well as the ConfirmationUI HAL.
+     * specifies that this key must not be usable unless the user provides confirmation of the data
+     * to be signed.  Confirmation is proven to keyMint via an approval token.  See the authToken
+     * parameter of begin(), as well as the ConfirmationUI HAL.
      *
      * If an attempt to use a key with this tag does not have a cryptographically valid
-     * CONFIRMATION_TOKEN provided to finish() or if the data provided to update()/finish() does not
+     * token provided to finish() or if the data provided to update()/finish() does not
      * match the data described in the token, keyMint must return NO_USER_CONFIRMATION.
      *
      * Must be hardware-enforced.
@@ -491,9 +491,11 @@
 
     /**
      * Tag::UNLOCKED_DEVICE_REQUIRED specifies that the key may only be used when the device is
-     * unlocked.
+     * unlocked, as reported to KeyMint via authToken operation parameter and the
+     * IKeyMintDevice::deviceLocked() method
      *
-     * Must be software-enforced.
+     * Must be hardware-enforced (but is also keystore-enforced on a per-user basis: see the
+     * deviceLocked() documentation).
      */
     UNLOCKED_DEVICE_REQUIRED = TagType.BOOL | 509,
 
@@ -825,11 +827,22 @@
     /**
      * DEVICE_UNIQUE_ATTESTATION is an argument to IKeyMintDevice::attested key generation/import
      * operations.  It indicates that attestation using a device-unique key is requested, rather
-     * than a batch key.  When a device-unique key is used, the returned chain should contain two
-     * certificates:
+     * than a batch key. When a device-unique key is used, the returned chain should contain two or
+     * three certificates.
+     *
+     * In case the chain contains two certificates, they should be:
      *    * The attestation certificate, containing the attestation extension, as described in
-            KeyCreationResult.aidl.
+     *      KeyCreationResult.aidl.
      *    * A self-signed root certificate, signed by the device-unique key.
+     *
+     * In case the chain contains three certificates, they should be:
+     *    * The attestation certificate, containing the attestation extension, as described in
+     *      KeyCreationResult.aidl, signed by the device-unique key.
+     *    * An intermediate certificate, containing the public portion of the device-unique key.
+     *    * A self-signed root certificate, signed by a dedicated key, certifying the
+     *      intermediate. Ideally, the dedicated key would be the same for all StrongBox
+     *      instances of the same manufacturer to ease validation.
+     *
      * No additional chained certificates are provided. Only SecurityLevel::STRONGBOX
      * IKeyMintDevices may support device-unique attestations.  SecurityLevel::TRUSTED_ENVIRONMENT
      * IKeyMintDevices must return ErrorCode::INVALID_ARGUMENT if they receive
@@ -864,8 +877,9 @@
      *
      * STORAGE_KEY is used to denote that a key generated or imported is a key used for storage
      * encryption. Keys of this type can either be generated or imported or secure imported using
-     * keyMint. exportKey() can be used to re-wrap storage key with a per-boot ephemeral key
-     * wrapped key once the key characteristics are enforced.
+     * keyMint. The convertStorageKeyToEphemeral() method of IKeyMintDevice can be used to re-wrap
+     * storage key with a per-boot ephemeral key wrapped key once the key characteristics are
+     * enforced.
      *
      * Keys with this tag cannot be used for any operation within keyMint.
      * ErrorCode::INVALID_OPERATION is returned when a key with Tag::STORAGE_KEY is provided to
@@ -875,7 +889,7 @@
 
     /**
      * OBSOLETE: Do not use. See IKeyMintOperation.updateAad instead.
-     * TODO: Delete when keystore1 is deleted.
+     * TODO(b/191738660): Remove in KeyMint v2.
      */
     ASSOCIATED_DATA = TagType.BYTES | 1000,
 
@@ -914,11 +928,10 @@
     RESET_SINCE_ID_ROTATION = TagType.BOOL | 1004,
 
     /**
-     * Tag::CONFIRMATION_TOKEN is used to deliver a cryptographic token proving that the user
-     * confirmed a signing request.  The content is a full-length HMAC-SHA256 value.  See the
-     * ConfirmationUI HAL for details of token computation.
+     * OBSOLETE: Do not use. See the authToken parameter for IKeyMintDevice::begin and for
+     * IKeyMintOperation methods instead.
      *
-     * Must never appear in KeyCharacteristics.
+     * TODO(b/191738660): Delete when keystore1 is deleted.
      */
     CONFIRMATION_TOKEN = TagType.BYTES | 1005,
 
diff --git a/security/keymint/aidl/default/Android.bp b/security/keymint/aidl/default/Android.bp
index 230534c..c2918ef 100644
--- a/security/keymint/aidl/default/Android.bp
+++ b/security/keymint/aidl/default/Android.bp
@@ -22,9 +22,9 @@
         "-Wextra",
     ],
     shared_libs: [
-        "android.hardware.security.keymint-V1-ndk_platform",
-        "android.hardware.security.sharedsecret-V1-ndk_platform",
-        "android.hardware.security.secureclock-V1-ndk_platform",
+        "android.hardware.security.keymint-V1-ndk",
+        "android.hardware.security.sharedsecret-V1-ndk",
+        "android.hardware.security.secureclock-V1-ndk",
         "libbase",
         "libbinder_ndk",
         "libcppbor_external",
diff --git a/security/keymint/aidl/vts/functional/Android.bp b/security/keymint/aidl/vts/functional/Android.bp
index ff08ce6..ff6a6f8 100644
--- a/security/keymint/aidl/vts/functional/Android.bp
+++ b/security/keymint/aidl/vts/functional/Android.bp
@@ -23,29 +23,39 @@
     default_applicable_licenses: ["hardware_interfaces_license"],
 }
 
-cc_test {
-    name: "VtsAidlKeyMintTargetTest",
+cc_defaults {
+    name: "keymint_vts_defaults",
     defaults: [
-        "VtsHalTargetTestDefaults",
         "use_libaidlvintf_gtest_helper_static",
-    ],
-    srcs: [
-        "AttestKeyTest.cpp",
-        "DeviceUniqueAttestationTest.cpp",
-        "KeyMintTest.cpp",
+        "VtsHalTargetTestDefaults",
     ],
     shared_libs: [
         "libbinder_ndk",
         "libcrypto",
     ],
     static_libs: [
-        "android.hardware.security.keymint-V1-ndk_platform",
-        "android.hardware.security.secureclock-V1-ndk_platform",
+        "android.hardware.security.keymint-V1-ndk",
+        "android.hardware.security.secureclock-V1-ndk",
         "libcppbor_external",
         "libcppcose_rkp",
+        "libjsoncpp",
         "libkeymint",
         "libkeymint_remote_prov_support",
         "libkeymint_support",
+    ],
+}
+
+cc_test {
+    name: "VtsAidlKeyMintTargetTest",
+    defaults: [
+        "keymint_vts_defaults",
+    ],
+    srcs: [
+        "AttestKeyTest.cpp",
+        "DeviceUniqueAttestationTest.cpp",
+        "KeyMintTest.cpp",
+    ],
+    static_libs: [
         "libkeymint_vts_test_utils",
     ],
     test_suites: [
@@ -57,8 +67,7 @@
 cc_test_library {
     name: "libkeymint_vts_test_utils",
     defaults: [
-        "VtsHalTargetTestDefaults",
-        "use_libaidlvintf_gtest_helper_static",
+        "keymint_vts_defaults",
     ],
     srcs: [
         "KeyMintAidlTestBase.cpp",
@@ -66,48 +75,26 @@
     export_include_dirs: [
         ".",
     ],
-    shared_libs: [
-        "libbinder_ndk",
-        "libcrypto",
-    ],
     static_libs: [
-        "android.hardware.security.keymint-V1-ndk_platform",
-        "android.hardware.security.secureclock-V1-ndk_platform",
-        "libcppbor_external",
-        "libcppcose_rkp",
         "libgmock_ndk",
-        "libkeymint",
-        "libkeymint_remote_prov_support",
-        "libkeymint_support",
     ],
 }
 
 cc_test {
     name: "VtsHalRemotelyProvisionedComponentTargetTest",
     defaults: [
-        "VtsHalTargetTestDefaults",
-        "use_libaidlvintf_gtest_helper_static",
+        "keymint_vts_defaults",
     ],
     srcs: [
         "VtsRemotelyProvisionedComponentTests.cpp",
     ],
-    shared_libs: [
-        "libbinder_ndk",
-        "libcrypto",
-    ],
     static_libs: [
-        "android.hardware.security.keymint-V1-ndk_platform",
-        "android.hardware.security.secureclock-V1-ndk_platform",
-        "libcppbor_external",
-        "libcppcose_rkp",
         "libgmock_ndk",
         "libkeymaster_portable",
-        "libkeymint",
-        "libkeymint_support",
-        "libkeymint_remote_prov_support",
         "libkeymint_vts_test_utils",
         "libpuresoftkeymasterdevice",
     ],
+    test_config: "VtsRemotelyProvisionedComponentTests.xml",
     test_suites: [
         "general-tests",
         "vts",
diff --git a/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp b/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp
index a3ed3ad..d7abf07 100644
--- a/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp
+++ b/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp
@@ -40,11 +40,16 @@
 
         AuthorizationSet crypto_params = SecLevelAuthorizations(key_characteristics);
 
-        // The device-unique attestation chain should contain exactly two certificates:
+        // The device-unique attestation chain should contain exactly three certificates:
         // * The leaf with the attestation extension.
-        // * A self-signed root, signed using the device-unique key.
-        ASSERT_EQ(cert_chain_.size(), 2);
-        EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
+        // * An intermediate, signing the leaf using the device-unique key.
+        // * A self-signed root, signed using some authority's key, certifying
+        //   the device-unique key.
+        const size_t chain_length = cert_chain_.size();
+        ASSERT_TRUE(chain_length == 2 || chain_length == 3);
+        // TODO(b/191361618): Once StrongBox implementations use a correctly-issued
+        // certificate chain, do not skip issuers matching.
+        EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_, /* strict_issuer_check= */ false));
 
         AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics);
         EXPECT_TRUE(verify_attestation_record("challenge", "foo", sw_enforced, hw_enforced,
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
index 5359b3b..2032411 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
@@ -1493,7 +1493,8 @@
     return authList;
 }
 
-AssertionResult ChainSignaturesAreValid(const vector<Certificate>& chain) {
+AssertionResult ChainSignaturesAreValid(const vector<Certificate>& chain,
+                                        bool strict_issuer_check) {
     std::stringstream cert_data;
 
     for (size_t i = 0; i < chain.size(); ++i) {
@@ -1520,7 +1521,7 @@
 
         string cert_issuer = x509NameToStr(X509_get_issuer_name(key_cert.get()));
         string signer_subj = x509NameToStr(X509_get_subject_name(signing_cert.get()));
-        if (cert_issuer != signer_subj) {
+        if (cert_issuer != signer_subj && strict_issuer_check) {
             return AssertionFailure() << "Cert " << i << " has wrong issuer.\n"
                                       << " Signer subject is " << signer_subj
                                       << " Issuer subject is " << cert_issuer << endl
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
index d592d36..ec3fcf6 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
@@ -349,7 +349,8 @@
 
 AuthorizationSet HwEnforcedAuthorizations(const vector<KeyCharacteristics>& key_characteristics);
 AuthorizationSet SwEnforcedAuthorizations(const vector<KeyCharacteristics>& key_characteristics);
-::testing::AssertionResult ChainSignaturesAreValid(const vector<Certificate>& chain);
+::testing::AssertionResult ChainSignaturesAreValid(const vector<Certificate>& chain,
+                                                   bool strict_issuer_check = true);
 
 #define INSTANTIATE_KEYMINT_AIDL_TEST(name)                                          \
     INSTANTIATE_TEST_SUITE_P(PerInstance, name,                                      \
diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
index caac346..b695dee 100644
--- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
@@ -1493,9 +1493,8 @@
             tag.tag == TAG_ROLLBACK_RESISTANCE) {
             continue;
         }
-        if (result == ErrorCode::UNSUPPORTED_TAG &&
-            (tag.tag == TAG_ALLOW_WHILE_ON_BODY || tag.tag == TAG_TRUSTED_USER_PRESENCE_REQUIRED)) {
-            // Optional tag not supported by this KeyMint implementation.
+        if (result == ErrorCode::UNSUPPORTED_TAG && tag.tag == TAG_TRUSTED_USER_PRESENCE_REQUIRED) {
+            // Tag not required to be supported by all KeyMint implementations.
             continue;
         }
         ASSERT_EQ(result, ErrorCode::OK);
@@ -1507,9 +1506,8 @@
 
         AuthorizationSet hw_enforced = HwEnforcedAuthorizations(key_characteristics);
         AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics);
-        if (tag.tag != TAG_ATTESTATION_APPLICATION_ID) {
-            // Expect to find most of the extra tags in the key characteristics
-            // of the generated key (but not for ATTESTATION_APPLICATION_ID).
+        // Some tags are optional, so don't require them to be in the enforcements.
+        if (tag.tag != TAG_ATTESTATION_APPLICATION_ID && tag.tag != TAG_ALLOW_WHILE_ON_BODY) {
             EXPECT_TRUE(hw_enforced.Contains(tag.tag) || sw_enforced.Contains(tag.tag))
                     << tag << " not in hw:" << hw_enforced << " nor sw:" << sw_enforced;
         }
diff --git a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp b/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
index 78f8f08..38f3586 100644
--- a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
+++ b/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
@@ -29,6 +29,7 @@
 #include <openssl/ec_key.h>
 #include <openssl/x509.h>
 #include <remote_prov/remote_prov_utils.h>
+#include <vector>
 
 #include "KeyMintAidlTestBase.h"
 
@@ -40,6 +41,7 @@
 namespace {
 
 #define INSTANTIATE_REM_PROV_AIDL_TEST(name)                                         \
+    GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(name);                             \
     INSTANTIATE_TEST_SUITE_P(                                                        \
             PerInstance, name,                                                       \
             testing::ValuesIn(VtsRemotelyProvisionedComponentTests::build_params()), \
@@ -102,8 +104,8 @@
     return std::move(corruptSig);
 }
 
-ErrMsgOr<EekChain> corrupt_sig_chain(const EekChain& eek, int which) {
-    auto [chain, _, parseErr] = cppbor::parse(eek.chain);
+ErrMsgOr<bytevec> corrupt_sig_chain(const bytevec& encodedEekChain, int which) {
+    auto [chain, _, parseErr] = cppbor::parse(encodedEekChain);
     if (!chain || !chain->asArray()) {
         return "EekChain parse failed";
     }
@@ -125,7 +127,7 @@
             corruptChain.add(eekChain->get(ii)->clone());
         }
     }
-    return EekChain{corruptChain.encode(), eek.last_pubkey, eek.last_privkey};
+    return corruptChain.encode();
 }
 
 string device_suffix(const string& name) {
@@ -271,14 +273,14 @@
 class CertificateRequestTest : public VtsRemotelyProvisionedComponentTests {
   protected:
     CertificateRequestTest() : eekId_(string_to_bytevec("eekid")), challenge_(randomBytes(32)) {
-        generateEek(3);
+        generateTestEekChain(3);
     }
 
-    void generateEek(size_t eekLength) {
+    void generateTestEekChain(size_t eekLength) {
         auto chain = generateEekChain(eekLength, eekId_);
         EXPECT_TRUE(chain) << chain.message();
-        if (chain) eekChain_ = chain.moveValue();
-        eekLength_ = eekLength;
+        if (chain) testEekChain_ = chain.moveValue();
+        testEekLength_ = eekLength;
     }
 
     void generateKeys(bool testMode, size_t numKeys) {
@@ -297,7 +299,8 @@
     }
 
     void checkProtectedData(const DeviceInfo& deviceInfo, const cppbor::Array& keysToSign,
-                            const bytevec& keysToSignMac, const ProtectedData& protectedData) {
+                            const bytevec& keysToSignMac, const ProtectedData& protectedData,
+                            std::vector<BccEntryData>* bccOutput = nullptr) {
         auto [parsedProtectedData, _, protDataErrMsg] = cppbor::parse(protectedData.protectedData);
         ASSERT_TRUE(parsedProtectedData) << protDataErrMsg;
         ASSERT_TRUE(parsedProtectedData->asArray());
@@ -307,8 +310,9 @@
         ASSERT_TRUE(senderPubkey) << senderPubkey.message();
         EXPECT_EQ(senderPubkey->second, eekId_);
 
-        auto sessionKey = x25519_HKDF_DeriveKey(eekChain_.last_pubkey, eekChain_.last_privkey,
-                                                senderPubkey->first, false /* senderIsA */);
+        auto sessionKey =
+                x25519_HKDF_DeriveKey(testEekChain_.last_pubkey, testEekChain_.last_privkey,
+                                      senderPubkey->first, false /* senderIsA */);
         ASSERT_TRUE(sessionKey) << sessionKey.message();
 
         auto protectedDataPayload =
@@ -354,11 +358,15 @@
 
         auto macPayload = verifyAndParseCoseMac0(&coseMac0, *macKey);
         ASSERT_TRUE(macPayload) << macPayload.message();
+
+        if (bccOutput) {
+            *bccOutput = std::move(*bccContents);
+        }
     }
 
     bytevec eekId_;
-    size_t eekLength_;
-    EekChain eekChain_;
+    size_t testEekLength_;
+    EekChain testEekChain_;
     bytevec challenge_;
     std::vector<MacedPublicKey> keysToSign_;
     cppbor::Array cborKeysToSign_;
@@ -372,13 +380,13 @@
     bool testMode = true;
     for (size_t eekLength : {2, 3, 7}) {
         SCOPED_TRACE(testing::Message() << "EEK of length " << eekLength);
-        generateEek(eekLength);
+        generateTestEekChain(eekLength);
 
         bytevec keysToSignMac;
         DeviceInfo deviceInfo;
         ProtectedData protectedData;
         auto status = provisionable_->generateCertificateRequest(
-                testMode, {} /* keysToSign */, eekChain_.chain, challenge_, &deviceInfo,
+                testMode, {} /* keysToSign */, testEekChain_.chain, challenge_, &deviceInfo,
                 &protectedData, &keysToSignMac);
         ASSERT_TRUE(status.isOk()) << status.getMessage();
 
@@ -387,31 +395,62 @@
 }
 
 /**
- * Generate an empty certificate request in prod mode.  Generation will fail because we don't have a
- * valid GEEK.
- *
- * TODO(swillden): Get a valid GEEK and use it so the generation can succeed, though we won't be
- * able to decrypt.
+ * Ensure that test mode outputs a unique BCC root key every time we request a
+ * certificate request. Else, it's possible that the test mode API could be used
+ * to fingerprint devices. Only the GEEK should be allowed to decrypt the same
+ * device public key multiple times.
  */
-TEST_P(CertificateRequestTest, EmptyRequest_prodMode) {
-    bool testMode = false;
-    for (size_t eekLength : {2, 3, 7}) {
-        SCOPED_TRACE(testing::Message() << "EEK of length " << eekLength);
-        generateEek(eekLength);
+TEST_P(CertificateRequestTest, NewKeyPerCallInTestMode) {
+    constexpr bool testMode = true;
 
-        bytevec keysToSignMac;
-        DeviceInfo deviceInfo;
-        ProtectedData protectedData;
-        auto status = provisionable_->generateCertificateRequest(
-                testMode, {} /* keysToSign */, eekChain_.chain, challenge_, &deviceInfo,
-                &protectedData, &keysToSignMac);
-        EXPECT_FALSE(status.isOk());
-        EXPECT_EQ(status.getServiceSpecificError(),
-                  BnRemotelyProvisionedComponent::STATUS_INVALID_EEK);
+    bytevec keysToSignMac;
+    DeviceInfo deviceInfo;
+    ProtectedData protectedData;
+    auto status = provisionable_->generateCertificateRequest(
+            testMode, {} /* keysToSign */, testEekChain_.chain, challenge_, &deviceInfo,
+            &protectedData, &keysToSignMac);
+    ASSERT_TRUE(status.isOk()) << status.getMessage();
+
+    std::vector<BccEntryData> firstBcc;
+    checkProtectedData(deviceInfo, /*keysToSign=*/cppbor::Array(), keysToSignMac, protectedData,
+                       &firstBcc);
+
+    status = provisionable_->generateCertificateRequest(
+            testMode, {} /* keysToSign */, testEekChain_.chain, challenge_, &deviceInfo,
+            &protectedData, &keysToSignMac);
+    ASSERT_TRUE(status.isOk()) << status.getMessage();
+
+    std::vector<BccEntryData> secondBcc;
+    checkProtectedData(deviceInfo, /*keysToSign=*/cppbor::Array(), keysToSignMac, protectedData,
+                       &secondBcc);
+
+    // Verify that none of the keys in the first BCC are repeated in the second one.
+    for (const auto& i : firstBcc) {
+        for (auto& j : secondBcc) {
+            ASSERT_THAT(i.pubKey, testing::Not(testing::ElementsAreArray(j.pubKey)))
+                    << "Found a repeated pubkey in two generateCertificateRequest test mode calls";
+        }
     }
 }
 
 /**
+ * Generate an empty certificate request in prod mode. This test must be run explicitly, and
+ * is not run by default. Not all devices are GMS devices, and therefore they do not all
+ * trust the Google EEK root.
+ */
+TEST_P(CertificateRequestTest, DISABLED_EmptyRequest_prodMode) {
+    bool testMode = false;
+
+    bytevec keysToSignMac;
+    DeviceInfo deviceInfo;
+    ProtectedData protectedData;
+    auto status = provisionable_->generateCertificateRequest(
+            testMode, {} /* keysToSign */, getProdEekChain(), challenge_, &deviceInfo,
+            &protectedData, &keysToSignMac);
+    EXPECT_TRUE(status.isOk());
+}
+
+/**
  * Generate a non-empty certificate request in test mode.  Decrypt, parse and validate the contents.
  */
 TEST_P(CertificateRequestTest, NonEmptyRequest_testMode) {
@@ -420,13 +459,13 @@
 
     for (size_t eekLength : {2, 3, 7}) {
         SCOPED_TRACE(testing::Message() << "EEK of length " << eekLength);
-        generateEek(eekLength);
+        generateTestEekChain(eekLength);
 
         bytevec keysToSignMac;
         DeviceInfo deviceInfo;
         ProtectedData protectedData;
         auto status = provisionable_->generateCertificateRequest(
-                testMode, keysToSign_, eekChain_.chain, challenge_, &deviceInfo, &protectedData,
+                testMode, keysToSign_, testEekChain_.chain, challenge_, &deviceInfo, &protectedData,
                 &keysToSignMac);
         ASSERT_TRUE(status.isOk()) << status.getMessage();
 
@@ -435,30 +474,21 @@
 }
 
 /**
- * Generate a non-empty certificate request in prod mode.  Must fail because we don't have a valid
- * GEEK.
- *
- * TODO(swillden): Get a valid GEEK and use it so the generation can succeed, though we won't be
- * able to decrypt.
+ * Generate a non-empty certificate request in prod mode. This test must be run explicitly, and
+ * is not run by default. Not all devices are GMS devices, and therefore they do not all
+ * trust the Google EEK root.
  */
-TEST_P(CertificateRequestTest, NonEmptyRequest_prodMode) {
+TEST_P(CertificateRequestTest, DISABLED_NonEmptyRequest_prodMode) {
     bool testMode = false;
     generateKeys(testMode, 4 /* numKeys */);
 
-    for (size_t eekLength : {2, 3, 7}) {
-        SCOPED_TRACE(testing::Message() << "EEK of length " << eekLength);
-        generateEek(eekLength);
-
-        bytevec keysToSignMac;
-        DeviceInfo deviceInfo;
-        ProtectedData protectedData;
-        auto status = provisionable_->generateCertificateRequest(
-                testMode, keysToSign_, eekChain_.chain, challenge_, &deviceInfo, &protectedData,
-                &keysToSignMac);
-        EXPECT_FALSE(status.isOk());
-        EXPECT_EQ(status.getServiceSpecificError(),
-                  BnRemotelyProvisionedComponent::STATUS_INVALID_EEK);
-    }
+    bytevec keysToSignMac;
+    DeviceInfo deviceInfo;
+    ProtectedData protectedData;
+    auto status = provisionable_->generateCertificateRequest(
+            testMode, keysToSign_, getProdEekChain(), challenge_, &deviceInfo, &protectedData,
+            &keysToSignMac);
+    EXPECT_TRUE(status.isOk());
 }
 
 /**
@@ -473,8 +503,8 @@
     DeviceInfo deviceInfo;
     ProtectedData protectedData;
     auto status = provisionable_->generateCertificateRequest(
-            testMode, {keyWithCorruptMac}, eekChain_.chain, challenge_, &deviceInfo, &protectedData,
-            &keysToSignMac);
+            testMode, {keyWithCorruptMac}, testEekChain_.chain, challenge_, &deviceInfo,
+            &protectedData, &keysToSignMac);
     ASSERT_FALSE(status.isOk()) << status.getMessage();
     EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_INVALID_MAC);
 }
@@ -483,7 +513,7 @@
  * Generate a non-empty certificate request in prod mode, but with the MAC corrupted on the keypair.
  */
 TEST_P(CertificateRequestTest, NonEmptyRequestCorruptMac_prodMode) {
-    bool testMode = true;
+    bool testMode = false;
     generateKeys(testMode, 1 /* numKeys */);
     MacedPublicKey keyWithCorruptMac = corrupt_maced_key(keysToSign_[0]).moveValue();
 
@@ -491,38 +521,35 @@
     DeviceInfo deviceInfo;
     ProtectedData protectedData;
     auto status = provisionable_->generateCertificateRequest(
-            testMode, {keyWithCorruptMac}, eekChain_.chain, challenge_, &deviceInfo, &protectedData,
-            &keysToSignMac);
+            testMode, {keyWithCorruptMac}, getProdEekChain(), challenge_, &deviceInfo,
+            &protectedData, &keysToSignMac);
     ASSERT_FALSE(status.isOk()) << status.getMessage();
-    auto rc = status.getServiceSpecificError();
-
-    // TODO(drysdale): drop the INVALID_EEK potential error code when a real GEEK is available.
-    EXPECT_TRUE(rc == BnRemotelyProvisionedComponent::STATUS_INVALID_EEK ||
-                rc == BnRemotelyProvisionedComponent::STATUS_INVALID_MAC);
+    EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_INVALID_MAC);
 }
 
 /**
  * Generate a non-empty certificate request in prod mode that has a corrupt EEK chain.
  * Confirm that the request is rejected.
- *
- * TODO(drysdale): Update to use a valid GEEK, so that the test actually confirms that the
- * implementation is checking signatures.
  */
 TEST_P(CertificateRequestTest, NonEmptyCorruptEekRequest_prodMode) {
     bool testMode = false;
     generateKeys(testMode, 4 /* numKeys */);
 
-    for (size_t ii = 0; ii < eekLength_; ii++) {
-        auto chain = corrupt_sig_chain(eekChain_, ii);
+    auto prodEekChain = getProdEekChain();
+    auto [parsedChain, _, parseErr] = cppbor::parse(prodEekChain);
+    ASSERT_NE(parsedChain, nullptr) << parseErr;
+    ASSERT_NE(parsedChain->asArray(), nullptr);
+
+    for (int ii = 0; ii < parsedChain->asArray()->size(); ++ii) {
+        auto chain = corrupt_sig_chain(prodEekChain, ii);
         ASSERT_TRUE(chain) << chain.message();
-        EekChain corruptEek = chain.moveValue();
 
         bytevec keysToSignMac;
         DeviceInfo deviceInfo;
         ProtectedData protectedData;
-        auto status = provisionable_->generateCertificateRequest(
-                testMode, keysToSign_, corruptEek.chain, challenge_, &deviceInfo, &protectedData,
-                &keysToSignMac);
+        auto status = provisionable_->generateCertificateRequest(testMode, keysToSign_, *chain,
+                                                                 challenge_, &deviceInfo,
+                                                                 &protectedData, &keysToSignMac);
         ASSERT_FALSE(status.isOk());
         ASSERT_EQ(status.getServiceSpecificError(),
                   BnRemotelyProvisionedComponent::STATUS_INVALID_EEK);
@@ -532,9 +559,6 @@
 /**
  * Generate a non-empty certificate request in prod mode that has an incomplete EEK chain.
  * Confirm that the request is rejected.
- *
- * TODO(drysdale): Update to use a valid GEEK, so that the test actually confirms that the
- * implementation is checking signatures.
  */
 TEST_P(CertificateRequestTest, NonEmptyIncompleteEekRequest_prodMode) {
     bool testMode = false;
@@ -542,7 +566,7 @@
 
     // Build an EEK chain that omits the first self-signed cert.
     auto truncatedChain = cppbor::Array();
-    auto [chain, _, parseErr] = cppbor::parse(eekChain_.chain);
+    auto [chain, _, parseErr] = cppbor::parse(getProdEekChain());
     ASSERT_TRUE(chain);
     auto eekChain = chain->asArray();
     ASSERT_NE(eekChain, nullptr);
@@ -571,7 +595,7 @@
     DeviceInfo deviceInfo;
     ProtectedData protectedData;
     auto status = provisionable_->generateCertificateRequest(
-            true /* testMode */, keysToSign_, eekChain_.chain, challenge_, &deviceInfo,
+            true /* testMode */, keysToSign_, testEekChain_.chain, challenge_, &deviceInfo,
             &protectedData, &keysToSignMac);
     ASSERT_FALSE(status.isOk());
     ASSERT_EQ(status.getServiceSpecificError(),
@@ -589,7 +613,7 @@
     DeviceInfo deviceInfo;
     ProtectedData protectedData;
     auto status = provisionable_->generateCertificateRequest(
-            false /* testMode */, keysToSign_, eekChain_.chain, challenge_, &deviceInfo,
+            false /* testMode */, keysToSign_, testEekChain_.chain, challenge_, &deviceInfo,
             &protectedData, &keysToSignMac);
     ASSERT_FALSE(status.isOk());
     ASSERT_EQ(status.getServiceSpecificError(),
diff --git a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.xml b/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.xml
new file mode 100644
index 0000000..2375bde
--- /dev/null
+++ b/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<configuration description="Runs VtsHalRemotelyProvisionedComponentTargetTest.">
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-suite-tag" value="apct-native" />
+
+    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
+
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push-file"
+            key="VtsHalRemotelyProvisionedComponentTargetTest"
+            value="/data/local/tmp/VtsHalRemotelyProvisionedComponentTargetTest" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="VtsHalRemotelyProvisionedComponentTargetTest" />
+        <option name="native-test-timeout" value="900000"/> <!-- 15 minutes -->
+    </test>
+</configuration>
diff --git a/security/keymint/aidl/vts/performance/Android.bp b/security/keymint/aidl/vts/performance/Android.bp
index 79ed0d5..355f87b 100644
--- a/security/keymint/aidl/vts/performance/Android.bp
+++ b/security/keymint/aidl/vts/performance/Android.bp
@@ -39,8 +39,8 @@
         "libkeymint_support",
     ],
     static_libs: [
-        "android.hardware.security.keymint-V1-ndk_platform",
-        "android.hardware.security.secureclock-V1-ndk_platform",
+        "android.hardware.security.keymint-V1-ndk",
+        "android.hardware.security.secureclock-V1-ndk",
         "libcppbor_external",
         "libchrome",
     ],
diff --git a/security/keymint/support/Android.bp b/security/keymint/support/Android.bp
index 718133a..bdb4cdf 100644
--- a/security/keymint/support/Android.bp
+++ b/security/keymint/support/Android.bp
@@ -40,7 +40,7 @@
         "include",
     ],
     shared_libs: [
-        "android.hardware.security.keymint-V1-ndk_platform",
+        "android.hardware.security.keymint-V1-ndk",
         "libbase",
         "libcrypto",
         "libutils",
@@ -57,8 +57,28 @@
         "include",
     ],
     shared_libs: [
+        "libbase",
         "libcppbor_external",
         "libcppcose_rkp",
         "libcrypto",
+        "libjsoncpp",
+    ],
+}
+
+cc_test {
+    name: "libkeymint_remote_prov_support_test",
+    srcs: ["remote_prov_utils_test.cpp"],
+    static_libs: [
+        "libgmock",
+        "libgtest_main",
+    ],
+    shared_libs: [
+        "libbase",
+        "libcppbor_external",
+        "libcppcose_rkp",
+        "libcrypto",
+        "libjsoncpp",
+        "libkeymaster_portable",
+        "libkeymint_remote_prov_support",
     ],
 }
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 e4261f3..406b7a9 100644
--- a/security/keymint/support/include/remote_prov/remote_prov_utils.h
+++ b/security/keymint/support/include/remote_prov/remote_prov_utils.h
@@ -27,6 +27,31 @@
 
 extern bytevec kTestMacKey;
 
+// The Google root key for the Endpoint Encryption Key chain, encoded as COSE_Sign1
+inline constexpr uint8_t kCoseEncodedRootCert[] = {
+        0x84, 0x43, 0xa1, 0x01, 0x27, 0xa0, 0x58, 0x2a, 0xa4, 0x01, 0x01, 0x03, 0x27, 0x20, 0x06,
+        0x21, 0x58, 0x20, 0x99, 0xb9, 0xee, 0xdd, 0x5e, 0xe4, 0x52, 0xf6, 0x85, 0xc6, 0x4c, 0x62,
+        0xdc, 0x3e, 0x61, 0xab, 0x57, 0x48, 0x7d, 0x75, 0x37, 0x29, 0xad, 0x76, 0x80, 0x32, 0xd2,
+        0xb3, 0xcb, 0x63, 0x58, 0xd9, 0x58, 0x40, 0x1e, 0x22, 0x08, 0x4b, 0xa4, 0xb7, 0xa4, 0xc8,
+        0xd7, 0x4e, 0x03, 0x0e, 0xfe, 0xb8, 0xaf, 0x14, 0x4c, 0xa7, 0x3b, 0x6f, 0xa5, 0xcd, 0xdc,
+        0xda, 0x79, 0xc6, 0x2b, 0x64, 0xfe, 0x99, 0x39, 0xaf, 0x76, 0xe7, 0x80, 0xfa, 0x66, 0x00,
+        0x85, 0x0d, 0x07, 0x98, 0x2a, 0xac, 0x91, 0x5c, 0xa7, 0x25, 0x14, 0x49, 0x06, 0x34, 0x75,
+        0xca, 0x8a, 0x27, 0x7a, 0xd9, 0xe3, 0x5a, 0x49, 0xeb, 0x02, 0x03};
+
+// The Google Endpoint Encryption Key certificate, encoded as COSE_Sign1
+inline constexpr uint8_t kCoseEncodedGeekCert[] = {
+        0x84, 0x43, 0xa1, 0x01, 0x27, 0xa0, 0x58, 0x4e, 0xa5, 0x01, 0x01, 0x02, 0x58, 0x20,
+        0xd0, 0xae, 0xc1, 0x15, 0xca, 0x2a, 0xcf, 0x73, 0xae, 0x6b, 0xcc, 0xcb, 0xd1, 0x96,
+        0x1d, 0x65, 0xe8, 0xb1, 0xdd, 0xd7, 0x4a, 0x1a, 0x37, 0xb9, 0x43, 0x3a, 0x97, 0xd5,
+        0x99, 0xdf, 0x98, 0x08, 0x03, 0x38, 0x18, 0x20, 0x04, 0x21, 0x58, 0x20, 0xbe, 0x85,
+        0xe7, 0x46, 0xc4, 0xa3, 0x42, 0x5a, 0x40, 0xd9, 0x36, 0x3a, 0xa6, 0x15, 0xd0, 0x2c,
+        0x58, 0x7e, 0x3d, 0xdc, 0x33, 0x02, 0x32, 0xd2, 0xfc, 0x5e, 0x1e, 0x87, 0x25, 0x5f,
+        0x72, 0x60, 0x58, 0x40, 0x9b, 0xcf, 0x90, 0xe2, 0x2e, 0x4b, 0xab, 0xd1, 0x18, 0xb1,
+        0x0e, 0x8e, 0x5d, 0x20, 0x27, 0x4b, 0x84, 0x58, 0xfe, 0xfc, 0x32, 0x90, 0x7e, 0x72,
+        0x05, 0x83, 0xbc, 0xd7, 0x82, 0xbe, 0xfa, 0x64, 0x78, 0x2d, 0x54, 0x10, 0x4b, 0xc0,
+        0x31, 0xbf, 0x6b, 0xe8, 0x1e, 0x35, 0xe2, 0xf0, 0x2d, 0xce, 0x6c, 0x2f, 0x4f, 0xf2,
+        0xf5, 0x4f, 0xa5, 0xd4, 0x83, 0xad, 0x96, 0xa2, 0xf1, 0x87, 0x58, 0x04};
+
 /**
  * Generates random bytes.
  */
@@ -44,6 +69,11 @@
  */
 ErrMsgOr<EekChain> generateEekChain(size_t length, const bytevec& eekId);
 
+/**
+ * Returns the CBOR-encoded, production Google Endpoint Encryption Key chain.
+ */
+bytevec getProdEekChain();
+
 struct BccEntryData {
     bytevec pubKey;
 };
@@ -57,4 +87,26 @@
  */
 ErrMsgOr<std::vector<BccEntryData>> validateBcc(const cppbor::Array* bcc);
 
+struct JsonOutput {
+    static JsonOutput Ok(std::string json) { return {std::move(json), ""}; }
+    static JsonOutput Error(std::string error) { return {"", std::move(error)}; }
+
+    std::string output;
+    std::string error;  // if non-empty, this describes what went wrong
+};
+
+/**
+ * Take a given certificate request and output a JSON blob containing both the
+ * build fingerprint and certificate request. This data may be serialized, then
+ * later uploaded to the remote provisioning service. The input csr is not
+ * validated, only encoded.
+ *
+ * Output format:
+ *   {
+ *     "build_fingerprint": <string>
+ *     "csr": <base64 CBOR CSR>
+ *   }
+ */
+JsonOutput jsonEncodeCsrWithBuild(const cppbor::Array& csr);
+
 }  // namespace aidl::android::hardware::security::keymint::remote_prov
diff --git a/security/keymint/support/remote_prov_utils.cpp b/security/keymint/support/remote_prov_utils.cpp
index 33f1ed3..0cbee51 100644
--- a/security/keymint/support/remote_prov_utils.cpp
+++ b/security/keymint/support/remote_prov_utils.cpp
@@ -14,11 +14,15 @@
  * limitations under the License.
  */
 
-#include <remote_prov/remote_prov_utils.h>
+#include <iterator>
+#include <tuple>
 
-#include <openssl/rand.h>
-
+#include <android-base/properties.h>
 #include <cppbor.h>
+#include <json/json.h>
+#include <openssl/base64.h>
+#include <openssl/rand.h>
+#include <remote_prov/remote_prov_utils.h>
 
 namespace aidl::android::hardware::security::keymint::remote_prov {
 
@@ -31,6 +35,10 @@
 }
 
 ErrMsgOr<EekChain> generateEekChain(size_t length, const bytevec& eekId) {
+    if (length < 2) {
+        return "EEK chain must contain at least 2 certs.";
+    }
+
     auto eekChain = cppbor::Array();
 
     bytevec prev_priv_key;
@@ -78,6 +86,18 @@
     return EekChain{eekChain.encode(), pub_key, priv_key};
 }
 
+bytevec getProdEekChain() {
+    bytevec prodEek;
+    prodEek.reserve(1 + sizeof(kCoseEncodedRootCert) + sizeof(kCoseEncodedGeekCert));
+
+    // In CBOR encoding, 0x82 indicates an array of two items
+    prodEek.push_back(0x82);
+    prodEek.insert(prodEek.end(), std::begin(kCoseEncodedRootCert), std::end(kCoseEncodedRootCert));
+    prodEek.insert(prodEek.end(), std::begin(kCoseEncodedGeekCert), std::end(kCoseEncodedGeekCert));
+
+    return prodEek;
+}
+
 ErrMsgOr<bytevec> verifyAndParseCoseSign1Cwt(const cppbor::Array* coseSign1,
                                              const bytevec& signingCoseKey, const bytevec& aad) {
     if (!coseSign1 || coseSign1->size() != kCoseSign1EntryCount) {
@@ -162,4 +182,36 @@
     return result;
 }
 
+JsonOutput jsonEncodeCsrWithBuild(const cppbor::Array& csr) {
+    const std::string kFingerprintProp = "ro.build.fingerprint";
+
+    if (!::android::base::WaitForPropertyCreation(kFingerprintProp)) {
+        return JsonOutput::Error("Unable to read build fingerprint");
+    }
+
+    bytevec csrCbor = csr.encode();
+    size_t base64Length;
+    int rc = EVP_EncodedLength(&base64Length, csrCbor.size());
+    if (!rc) {
+        return JsonOutput::Error("Error getting base64 length. Size overflow?");
+    }
+
+    std::vector<char> base64(base64Length);
+    rc = EVP_EncodeBlock(reinterpret_cast<uint8_t*>(base64.data()), csrCbor.data(), csrCbor.size());
+    ++rc;  // Account for NUL, which BoringSSL does not for some reason.
+    if (rc != base64Length) {
+        return JsonOutput::Error("Error writing base64. Expected " + std::to_string(base64Length) +
+                                 " bytes to be written, but " + std::to_string(rc) +
+                                 " bytes were actually written.");
+    }
+
+    Json::Value json(Json::objectValue);
+    json["build_fingerprint"] = ::android::base::GetProperty(kFingerprintProp, /*default=*/"");
+    json["csr"] = base64.data();  // Boring writes a NUL-terminated c-string
+
+    Json::StreamWriterBuilder factory;
+    factory["indentation"] = "";  // disable pretty formatting
+    return JsonOutput::Ok(Json::writeString(factory, json));
+}
+
 }  // namespace aidl::android::hardware::security::keymint::remote_prov
diff --git a/security/keymint/support/remote_prov_utils_test.cpp b/security/keymint/support/remote_prov_utils_test.cpp
new file mode 100644
index 0000000..8697c51
--- /dev/null
+++ b/security/keymint/support/remote_prov_utils_test.cpp
@@ -0,0 +1,101 @@
+/*
+ * 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/properties.h>
+#include <cppbor_parse.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <keymaster/android_keymaster_utils.h>
+#include <keymaster/logger.h>
+#include <keymaster/remote_provisioning_utils.h>
+#include <openssl/curve25519.h>
+#include <remote_prov/remote_prov_utils.h>
+#include <cstdint>
+#include "cppbor.h"
+#include "keymaster/cppcose/cppcose.h"
+
+namespace aidl::android::hardware::security::keymint::remote_prov {
+namespace {
+
+using ::keymaster::KeymasterBlob;
+using ::keymaster::validateAndExtractEekPubAndId;
+using ::testing::ElementsAreArray;
+
+TEST(RemoteProvUtilsTest, GenerateEekChainInvalidLength) {
+    ASSERT_FALSE(generateEekChain(1, /*eekId=*/{}));
+}
+
+TEST(RemoteProvUtilsTest, GenerateEekChain) {
+    bytevec kTestEekId = {'t', 'e', 's', 't', 'I', 'd', 0};
+    for (size_t length : {2, 3, 31}) {
+        auto get_eek_result = generateEekChain(length, kTestEekId);
+        ASSERT_TRUE(get_eek_result) << get_eek_result.message();
+
+        auto& [chain, pubkey, privkey] = *get_eek_result;
+
+        auto validation_result = validateAndExtractEekPubAndId(
+                /*testMode=*/true, KeymasterBlob(chain.data(), chain.size()));
+        ASSERT_TRUE(validation_result.isOk());
+
+        auto& [eekPub, eekId] = *validation_result;
+        EXPECT_THAT(eekId, ElementsAreArray(kTestEekId));
+        EXPECT_THAT(eekPub, ElementsAreArray(pubkey));
+    }
+}
+
+TEST(RemoteProvUtilsTest, GetProdEekChain) {
+    auto chain = getProdEekChain();
+
+    auto validation_result = validateAndExtractEekPubAndId(
+            /*testMode=*/false, KeymasterBlob(chain.data(), chain.size()));
+    ASSERT_TRUE(validation_result.isOk()) << "Error: " << validation_result.moveError();
+
+    auto& [eekPub, eekId] = *validation_result;
+
+    auto [geekCert, ignoredNewPos, error] =
+            cppbor::parse(kCoseEncodedGeekCert, sizeof(kCoseEncodedGeekCert));
+    ASSERT_NE(geekCert, nullptr) << "Error: " << error;
+    ASSERT_NE(geekCert->asArray(), nullptr);
+
+    auto& encodedGeekCoseKey = geekCert->asArray()->get(kCoseSign1Payload);
+    ASSERT_NE(encodedGeekCoseKey, nullptr);
+    ASSERT_NE(encodedGeekCoseKey->asBstr(), nullptr);
+
+    auto geek = CoseKey::parse(encodedGeekCoseKey->asBstr()->value());
+    ASSERT_TRUE(geek) << "Error: " << geek.message();
+
+    const std::vector<uint8_t> empty;
+    EXPECT_THAT(eekId, ElementsAreArray(geek->getBstrValue(CoseKey::KEY_ID).value_or(empty)));
+    EXPECT_THAT(eekPub, ElementsAreArray(geek->getBstrValue(CoseKey::PUBKEY_X).value_or(empty)));
+}
+
+TEST(RemoteProvUtilsTest, JsonEncodeCsr) {
+    cppbor::Array array;
+    array.add(1);
+
+    auto [json, error] = jsonEncodeCsrWithBuild(array);
+
+    ASSERT_TRUE(error.empty()) << error;
+
+    std::string expected = R"({"build_fingerprint":")" +
+                           ::android::base::GetProperty("ro.build.fingerprint", /*default=*/"") +
+                           R"(","csr":"gQE="})";
+
+    ASSERT_EQ(json, expected);
+}
+
+}  // namespace
+}  // namespace aidl::android::hardware::security::keymint::remote_prov
diff --git a/security/secureclock/aidl/vts/functional/Android.bp b/security/secureclock/aidl/vts/functional/Android.bp
index 56c8e1d..806517d 100644
--- a/security/secureclock/aidl/vts/functional/Android.bp
+++ b/security/secureclock/aidl/vts/functional/Android.bp
@@ -41,8 +41,8 @@
         "libcrypto",
     ],
     static_libs: [
-        "android.hardware.security.keymint-V1-ndk_platform",
-        "android.hardware.security.secureclock-V1-ndk_platform",
+        "android.hardware.security.keymint-V1-ndk",
+        "android.hardware.security.secureclock-V1-ndk",
         "libkeymint",
     ],
     test_suites: [
diff --git a/security/sharedsecret/aidl/vts/functional/Android.bp b/security/sharedsecret/aidl/vts/functional/Android.bp
index d3747fc..94da675 100644
--- a/security/sharedsecret/aidl/vts/functional/Android.bp
+++ b/security/sharedsecret/aidl/vts/functional/Android.bp
@@ -41,8 +41,8 @@
         "libcrypto",
     ],
     static_libs: [
-        "android.hardware.security.keymint-V1-ndk_platform",
-        "android.hardware.security.sharedsecret-V1-ndk_platform",
+        "android.hardware.security.keymint-V1-ndk",
+        "android.hardware.security.sharedsecret-V1-ndk",
         "libkeymint",
     ],
     test_suites: [
diff --git a/security/sharedsecret/aidl/vts/functional/SharedSecretAidlTest.cpp b/security/sharedsecret/aidl/vts/functional/SharedSecretAidlTest.cpp
index 919f882..51938ba 100644
--- a/security/sharedsecret/aidl/vts/functional/SharedSecretAidlTest.cpp
+++ b/security/sharedsecret/aidl/vts/functional/SharedSecretAidlTest.cpp
@@ -268,10 +268,16 @@
                     << "Shared secret service that provided tweaked param should fail to compute "
                        "shared secret";
         } else {
-            EXPECT_EQ(ErrorCode::OK, responses[i].error) << "Others should succeed";
-            EXPECT_NE(correct_response, responses[i].sharing_check)
-                    << "Others should calculate a different shared secret, due to the tweaked "
-                       "nonce.";
+            // Other services *may* succeed, or may notice the invalid size for the nonce.
+            // However, if another service completes the computation, it should get the 'wrong'
+            // answer.
+            if (responses[i].error == ErrorCode::OK) {
+                EXPECT_NE(correct_response, responses[i].sharing_check)
+                        << "Others should calculate a different shared secret, due to the tweaked "
+                           "nonce.";
+            } else {
+                EXPECT_EQ(ErrorCode::INVALID_ARGUMENT, responses[i].error);
+            }
         }
     }
 }
@@ -348,10 +354,16 @@
                     << "Shared secret service that provided tweaked param should fail to compute "
                        "shared secret";
         } else {
-            EXPECT_EQ(ErrorCode::OK, responses[i].error) << "Others should succeed";
-            EXPECT_NE(correct_response, responses[i].sharing_check)
-                    << "Others should calculate a different shared secret, due to the tweaked "
-                       "nonce.";
+            // Other services *may* succeed, or may notice the invalid size for the seed.
+            // However, if another service completes the computation, it should get the 'wrong'
+            // answer.
+            if (responses[i].error == ErrorCode::OK) {
+                EXPECT_NE(correct_response, responses[i].sharing_check)
+                        << "Others should calculate a different shared secret, due to the tweaked "
+                           "seed.";
+            } else {
+                EXPECT_EQ(ErrorCode::INVALID_ARGUMENT, responses[i].error);
+            }
         }
     }
 }
diff --git a/tests/lazy_cb/1.0/.hidl_for_system_ext b/tests/lazy_cb/1.0/.hidl_for_system_ext
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/lazy_cb/1.0/.hidl_for_system_ext
diff --git a/tests/lazy_cb/1.0/Android.bp b/tests/lazy_cb/1.0/Android.bp
new file mode 100644
index 0000000..4d82b63
--- /dev/null
+++ b/tests/lazy_cb/1.0/Android.bp
@@ -0,0 +1,23 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_interfaces_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+hidl_interface {
+    name: "android.hardware.tests.lazy_cb@1.0",
+    root: "android.hardware",
+    system_ext_specific: true,
+    srcs: [
+        "ILazyCb.hal",
+    ],
+    interfaces: [
+        "android.hidl.base@1.0",
+    ],
+    gen_java: true,
+}
diff --git a/tests/lazy_cb/1.0/ILazyCb.hal b/tests/lazy_cb/1.0/ILazyCb.hal
new file mode 100644
index 0000000..a9046b3
--- /dev/null
+++ b/tests/lazy_cb/1.0/ILazyCb.hal
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+package android.hardware.tests.lazy_cb@1.0;
+
+interface ILazyCb {
+    /**
+     * Set the eventfd used to notify that the active services
+     * callback is being executed and is about to terminate the process.
+     */
+    setEventFd(handle fds) generates (bool success);
+};
diff --git a/tests/msgq/1.0/default/Android.bp b/tests/msgq/1.0/default/Android.bp
index 5f116e7..75973fc 100644
--- a/tests/msgq/1.0/default/Android.bp
+++ b/tests/msgq/1.0/default/Android.bp
@@ -100,10 +100,10 @@
     // These are static libs only for testing purposes and portability. Shared
     // libs should be used on device.
     static_libs: [
-        "android.hardware.common-V2-ndk_platform",
-        "android.hardware.common.fmq-V1-ndk_platform",
+        "android.hardware.common-V2-ndk",
+        "android.hardware.common.fmq-V1-ndk",
         "android.hardware.tests.msgq@1.0",
-        "android.fmq.test-ndk_platform",
+        "android.fmq.test-ndk",
     ],
     whole_static_libs: [
         "android.hardware.tests.msgq@1.0-impl",
diff --git a/tv/cec/1.0/default/Android.bp b/tv/cec/1.0/default/Android.bp
index fc4298d..b4053df 100644
--- a/tv/cec/1.0/default/Android.bp
+++ b/tv/cec/1.0/default/Android.bp
@@ -12,12 +12,16 @@
     defaults: ["hidl_defaults"],
     vendor: true,
     relative_install_path: "hw",
-    srcs: ["HdmiCec.cpp"],
+    srcs: [
+        "HdmiCec.cpp",
+        "HdmiCecDefault.cpp",
+    ],
 
     shared_libs: [
         "libhidlbase",
         "liblog",
         "libbase",
+        "libcutils",
         "libutils",
         "libhardware",
         "android.hardware.tv.cec@1.0",
diff --git a/tv/cec/1.0/default/HdmiCec.cpp b/tv/cec/1.0/default/HdmiCec.cpp
index 171bdfe..74de785 100644
--- a/tv/cec/1.0/default/HdmiCec.cpp
+++ b/tv/cec/1.0/default/HdmiCec.cpp
@@ -20,6 +20,7 @@
 #include <hardware/hardware.h>
 #include <hardware/hdmi_cec.h>
 #include "HdmiCec.h"
+#include "HdmiCecDefault.h"
 
 namespace android {
 namespace hardware {
@@ -390,6 +391,15 @@
     return mDevice->is_connected(mDevice, portId) > 0;
 }
 
+IHdmiCec* getHdmiCecDefault() {
+    HdmiCecDefault* hdmiCecDefault = new HdmiCecDefault();
+    Result result = hdmiCecDefault->init();
+    if (result == Result::SUCCESS) {
+        return hdmiCecDefault;
+    }
+    LOG(ERROR) << "Failed to load default HAL.";
+    return nullptr;
+}
 
 IHdmiCec* HIDL_FETCH_IHdmiCec(const char* hal) {
     hdmi_cec_device_t* hdmi_cec_device;
@@ -410,7 +420,7 @@
         return new HdmiCec(hdmi_cec_device);
     } else {
         LOG(ERROR) << "Passthrough failed to load legacy HAL.";
-        return nullptr;
+        return getHdmiCecDefault();
     }
 }
 
diff --git a/tv/cec/1.0/default/HdmiCecDefault.cpp b/tv/cec/1.0/default/HdmiCecDefault.cpp
new file mode 100644
index 0000000..299bcf0
--- /dev/null
+++ b/tv/cec/1.0/default/HdmiCecDefault.cpp
@@ -0,0 +1,461 @@
+/*
+ * 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 "android.hardware.tv.cec@1.0-impl"
+#include <android-base/logging.h>
+
+#include <cutils/properties.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <linux/cec.h>
+#include <linux/ioctl.h>
+#include <poll.h>
+#include <pthread.h>
+#include <sys/eventfd.h>
+#include <algorithm>
+
+#include "HdmiCecDefault.h"
+
+namespace android {
+namespace hardware {
+namespace tv {
+namespace cec {
+namespace V1_0 {
+namespace implementation {
+
+// When set to false, all the CEC commands are discarded. True by default after initialization.
+bool mCecEnabled;
+/*
+ * When set to false, HAL does not wake up the system upon receiving <Image View On> or
+ * <Text View On>. True by default after initialization.
+ */
+bool mWakeupEnabled;
+
+int mCecFd;
+int mExitFd;
+pthread_t mEventThread;
+sp<IHdmiCecCallback> mCallback;
+
+HdmiCecDefault::HdmiCecDefault() {
+    mCecFd = -1;
+    mExitFd = -1;
+    mCecEnabled = false;
+    mWakeupEnabled = false;
+    mCallback = nullptr;
+}
+
+HdmiCecDefault::~HdmiCecDefault() {
+    release();
+}
+
+// Methods from ::android::hardware::tv::cec::V1_0::IHdmiCec follow.
+Return<Result> HdmiCecDefault::addLogicalAddress(CecLogicalAddress addr) {
+    if (addr < CecLogicalAddress::TV || addr >= CecLogicalAddress::BROADCAST) {
+        LOG(ERROR) << "Add logical address failed, Invalid address";
+        return Result::FAILURE_INVALID_ARGS;
+    }
+
+    struct cec_log_addrs cecLogAddrs;
+    int ret = ioctl(mCecFd, CEC_ADAP_G_LOG_ADDRS, &cecLogAddrs);
+    if (ret) {
+        LOG(ERROR) << "Add logical address failed, Error = " << strerror(errno);
+        return Result::FAILURE_BUSY;
+    }
+
+    cecLogAddrs.cec_version = getCecVersion();
+    cecLogAddrs.vendor_id = getVendorId();
+
+    unsigned int logAddrType = CEC_LOG_ADDR_TYPE_UNREGISTERED;
+    unsigned int allDevTypes = 0;
+    unsigned int primDevType = 0xff;
+    switch (addr) {
+        case CecLogicalAddress::TV:
+            primDevType = CEC_OP_PRIM_DEVTYPE_TV;
+            logAddrType = CEC_LOG_ADDR_TYPE_TV;
+            allDevTypes = CEC_OP_ALL_DEVTYPE_TV;
+            break;
+        case CecLogicalAddress::RECORDER_1:
+        case CecLogicalAddress::RECORDER_2:
+        case CecLogicalAddress::RECORDER_3:
+            primDevType = CEC_OP_PRIM_DEVTYPE_RECORD;
+            logAddrType = CEC_LOG_ADDR_TYPE_RECORD;
+            allDevTypes = CEC_OP_ALL_DEVTYPE_RECORD;
+            break;
+        case CecLogicalAddress::TUNER_1:
+        case CecLogicalAddress::TUNER_2:
+        case CecLogicalAddress::TUNER_3:
+        case CecLogicalAddress::TUNER_4:
+            primDevType = CEC_OP_PRIM_DEVTYPE_TUNER;
+            logAddrType = CEC_LOG_ADDR_TYPE_TUNER;
+            allDevTypes = CEC_OP_ALL_DEVTYPE_TUNER;
+            break;
+        case CecLogicalAddress::PLAYBACK_1:
+        case CecLogicalAddress::PLAYBACK_2:
+        case CecLogicalAddress::PLAYBACK_3:
+            primDevType = CEC_OP_PRIM_DEVTYPE_PLAYBACK;
+            logAddrType = CEC_LOG_ADDR_TYPE_PLAYBACK;
+            allDevTypes = CEC_OP_ALL_DEVTYPE_PLAYBACK;
+            cecLogAddrs.flags |= CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU;
+            break;
+        case CecLogicalAddress::AUDIO_SYSTEM:
+            primDevType = CEC_OP_PRIM_DEVTYPE_AUDIOSYSTEM;
+            logAddrType = CEC_LOG_ADDR_TYPE_AUDIOSYSTEM;
+            allDevTypes = CEC_OP_ALL_DEVTYPE_AUDIOSYSTEM;
+            break;
+        case CecLogicalAddress::FREE_USE:
+            primDevType = CEC_OP_PRIM_DEVTYPE_PROCESSOR;
+            logAddrType = CEC_LOG_ADDR_TYPE_SPECIFIC;
+            allDevTypes = CEC_OP_ALL_DEVTYPE_SWITCH;
+            break;
+        case CecLogicalAddress::UNREGISTERED:
+            cecLogAddrs.flags |= CEC_LOG_ADDRS_FL_ALLOW_UNREG_FALLBACK;
+            break;
+    }
+
+    int logAddrIndex = cecLogAddrs.num_log_addrs;
+
+    cecLogAddrs.num_log_addrs += 1;
+    cecLogAddrs.log_addr[logAddrIndex] = static_cast<cec_logical_address_t>(addr);
+    cecLogAddrs.log_addr_type[logAddrIndex] = logAddrType;
+    cecLogAddrs.primary_device_type[logAddrIndex] = primDevType;
+    cecLogAddrs.all_device_types[logAddrIndex] = allDevTypes;
+    cecLogAddrs.features[logAddrIndex][0] = 0;
+    cecLogAddrs.features[logAddrIndex][1] = 0;
+
+    ret = ioctl(mCecFd, CEC_ADAP_S_LOG_ADDRS, &cecLogAddrs);
+    if (ret) {
+        LOG(ERROR) << "Add logical address failed, Error = " << strerror(errno);
+        return Result::FAILURE_BUSY;
+    }
+    return Result::SUCCESS;
+}
+
+Return<void> HdmiCecDefault::clearLogicalAddress() {
+    struct cec_log_addrs cecLogAddrs;
+    memset(&cecLogAddrs, 0, sizeof(cecLogAddrs));
+    int ret = ioctl(mCecFd, CEC_ADAP_S_LOG_ADDRS, &cecLogAddrs);
+    if (ret) {
+        LOG(ERROR) << "Clear logical Address failed, Error = " << strerror(errno);
+    }
+    return Void();
+}
+
+Return<void> HdmiCecDefault::getPhysicalAddress(getPhysicalAddress_cb callback) {
+    uint16_t addr;
+    int ret = ioctl(mCecFd, CEC_ADAP_G_PHYS_ADDR, &addr);
+    if (ret) {
+        LOG(ERROR) << "Get physical address failed, Error = " << strerror(errno);
+        callback(Result::FAILURE_INVALID_STATE, addr);
+        return Void();
+    }
+    callback(Result::SUCCESS, addr);
+    return Void();
+}
+
+Return<SendMessageResult> HdmiCecDefault::sendMessage(const CecMessage& message) {
+    if (!mCecEnabled) {
+        return SendMessageResult::FAIL;
+    }
+
+    struct cec_msg cecMsg;
+    memset(&cecMsg, 0, sizeof(cec_msg));
+
+    int initiator = static_cast<cec_logical_address_t>(message.initiator);
+    int destination = static_cast<cec_logical_address_t>(message.destination);
+
+    cecMsg.msg[0] = (initiator << 4) | destination;
+    for (size_t i = 0; i < message.body.size(); ++i) {
+        cecMsg.msg[i + 1] = message.body[i];
+    }
+    cecMsg.len = message.body.size() + 1;
+
+    int ret = ioctl(mCecFd, CEC_TRANSMIT, &cecMsg);
+
+    if (ret) {
+        LOG(ERROR) << "Send message failed, Error = " << strerror(errno);
+        return SendMessageResult::FAIL;
+    }
+
+    if (cecMsg.tx_status != CEC_TX_STATUS_OK) {
+        LOG(ERROR) << "Send message tx_status = " << cecMsg.tx_status;
+    }
+
+    switch (cecMsg.tx_status) {
+        case CEC_TX_STATUS_OK:
+            return SendMessageResult::SUCCESS;
+        case CEC_TX_STATUS_ARB_LOST:
+            return SendMessageResult::BUSY;
+        case CEC_TX_STATUS_NACK:
+            return SendMessageResult::NACK;
+        default:
+            return SendMessageResult::FAIL;
+    }
+}
+
+Return<void> HdmiCecDefault::setCallback(const sp<IHdmiCecCallback>& callback) {
+    if (mCallback != nullptr) {
+        mCallback->unlinkToDeath(this);
+        mCallback = nullptr;
+    }
+
+    if (callback != nullptr) {
+        mCallback = callback;
+        mCallback->linkToDeath(this, 0 /*cookie*/);
+    }
+    return Void();
+}
+
+Return<int32_t> HdmiCecDefault::getCecVersion() {
+    return property_get_int32("ro.hdmi.cec_version", CEC_OP_CEC_VERSION_1_4);
+}
+
+Return<uint32_t> HdmiCecDefault::getVendorId() {
+    return property_get_int32("ro.hdmi.vendor_id", 0x000c03 /* HDMI LLC vendor ID */);
+}
+
+Return<void> HdmiCecDefault::getPortInfo(getPortInfo_cb callback) {
+    uint16_t addr;
+    int ret = ioctl(mCecFd, CEC_ADAP_G_PHYS_ADDR, &addr);
+    if (ret) {
+        LOG(ERROR) << "Get port info failed, Error = " << strerror(errno);
+    }
+
+    unsigned int type = property_get_int32("ro.hdmi.device_type", CEC_DEVICE_PLAYBACK);
+    hidl_vec<HdmiPortInfo> portInfos(1);
+    portInfos[0] = {.type = (type == CEC_DEVICE_TV ? HdmiPortType::INPUT : HdmiPortType::OUTPUT),
+                    .portId = 1,
+                    .cecSupported = true,
+                    .arcSupported = false,
+                    .physicalAddress = addr};
+    callback(portInfos);
+    return Void();
+}
+
+Return<void> HdmiCecDefault::setOption(OptionKey key, bool value) {
+    switch (key) {
+        case OptionKey::ENABLE_CEC:
+            LOG(DEBUG) << "setOption: Enable CEC: " << value;
+            mCecEnabled = value;
+            break;
+        case OptionKey::WAKEUP:
+            LOG(DEBUG) << "setOption: WAKEUP: " << value;
+            mWakeupEnabled = value;
+            break;
+        default:
+            break;
+    }
+    return Void();
+}
+
+Return<void> HdmiCecDefault::setLanguage(const hidl_string& /*language*/) {
+    return Void();
+}
+
+Return<void> HdmiCecDefault::enableAudioReturnChannel(int32_t /*portId*/, bool /*enable*/) {
+    return Void();
+}
+
+Return<bool> HdmiCecDefault::isConnected(int32_t /*portId*/) {
+    uint16_t addr;
+    int ret = ioctl(mCecFd, CEC_ADAP_G_PHYS_ADDR, &addr);
+    if (ret) {
+        LOG(ERROR) << "Is connected failed, Error = " << strerror(errno);
+        return false;
+    }
+    if (addr == CEC_PHYS_ADDR_INVALID) {
+        return false;
+    }
+    return true;
+}
+
+// Initialise the cec file descriptor
+Return<Result> HdmiCecDefault::init() {
+    const char* path = "/dev/cec0";
+    mCecFd = open(path, O_RDWR);
+    if (mCecFd < 0) {
+        LOG(ERROR) << "Failed to open " << path << ", Error = " << strerror(errno);
+        return Result::FAILURE_NOT_SUPPORTED;
+    }
+    mExitFd = eventfd(0, EFD_NONBLOCK);
+    if (mExitFd < 0) {
+        LOG(ERROR) << "Failed to open eventfd, Error = " << strerror(errno);
+        release();
+        return Result::FAILURE_NOT_SUPPORTED;
+    }
+
+    // Ensure the CEC device supports required capabilities
+    struct cec_caps caps = {};
+    int ret = ioctl(mCecFd, CEC_ADAP_G_CAPS, &caps);
+    if (ret) {
+        LOG(ERROR) << "Unable to query cec adapter capabilities, Error = " << strerror(errno);
+        release();
+        return Result::FAILURE_NOT_SUPPORTED;
+    }
+
+    if (!(caps.capabilities & (CEC_CAP_LOG_ADDRS | CEC_CAP_TRANSMIT | CEC_CAP_PASSTHROUGH))) {
+        LOG(ERROR) << "Wrong cec adapter capabilities " << caps.capabilities;
+        release();
+        return Result::FAILURE_NOT_SUPPORTED;
+    }
+
+    uint32_t mode = CEC_MODE_INITIATOR | CEC_MODE_EXCL_FOLLOWER_PASSTHRU;
+    ret = ioctl(mCecFd, CEC_S_MODE, &mode);
+    if (ret) {
+        LOG(ERROR) << "Unable to set initiator mode, Error = " << strerror(errno);
+        release();
+        return Result::FAILURE_NOT_SUPPORTED;
+    }
+
+    /* thread loop for receiving cec messages and hotplug events*/
+    if (pthread_create(&mEventThread, NULL, event_thread, NULL)) {
+        LOG(ERROR) << "Can't create event thread: " << strerror(errno);
+        release();
+        return Result::FAILURE_NOT_SUPPORTED;
+    }
+
+    mCecEnabled = true;
+    mWakeupEnabled = true;
+    return Result::SUCCESS;
+}
+
+Return<void> HdmiCecDefault::release() {
+    if (mExitFd > 0) {
+        uint64_t tmp = 1;
+        write(mExitFd, &tmp, sizeof(tmp));
+        pthread_join(mEventThread, NULL);
+    }
+    if (mExitFd > 0) {
+        close(mExitFd);
+    }
+    if (mCecFd > 0) {
+        close(mCecFd);
+    }
+    mCecEnabled = false;
+    mWakeupEnabled = false;
+    setCallback(nullptr);
+    return Void();
+}
+
+void* HdmiCecDefault::event_thread(void*) {
+    struct pollfd ufds[3] = {
+            {mCecFd, POLLIN, 0},
+            {mCecFd, POLLERR, 0},
+            {mExitFd, POLLIN, 0},
+    };
+
+    while (1) {
+        ufds[0].revents = 0;
+        ufds[1].revents = 0;
+        ufds[2].revents = 0;
+
+        int ret = poll(ufds, /* size(ufds) = */ 3, /* timeout = */ -1);
+
+        if (ret <= 0) {
+            continue;
+        }
+
+        if (ufds[2].revents == POLLIN) { /* Exit */
+            break;
+        }
+
+        if (ufds[1].revents == POLLERR) { /* CEC Event */
+            struct cec_event ev;
+            ret = ioctl(mCecFd, CEC_DQEVENT, &ev);
+
+            if (!mCecEnabled) {
+                continue;
+            }
+
+            if (ret) {
+                LOG(ERROR) << "CEC_DQEVENT failed, Error = " << strerror(errno);
+                continue;
+            }
+
+            if (ev.event == CEC_EVENT_STATE_CHANGE) {
+                if (mCallback != nullptr) {
+                    HotplugEvent hotplugEvent{
+                            .connected = (ev.state_change.phys_addr != CEC_PHYS_ADDR_INVALID),
+                            .portId = 1};
+                    mCallback->onHotplugEvent(hotplugEvent);
+                } else {
+                    LOG(ERROR) << "No event callback for hotplug";
+                }
+            }
+        }
+
+        if (ufds[0].revents == POLLIN) { /* CEC Driver */
+            struct cec_msg msg = {};
+            ret = ioctl(mCecFd, CEC_RECEIVE, &msg);
+
+            if (!mCecEnabled) {
+                continue;
+            }
+
+            if (ret) {
+                LOG(ERROR) << "CEC_RECEIVE failed, Error = " << strerror(errno);
+                continue;
+            }
+
+            if (msg.rx_status != CEC_RX_STATUS_OK) {
+                LOG(ERROR) << "msg rx_status = " << msg.rx_status;
+                continue;
+            }
+
+            if (!mWakeupEnabled && isWakeupMessage(msg)) {
+                LOG(DEBUG) << "Filter wakeup message";
+                continue;
+            }
+
+            if (mCallback != nullptr) {
+                size_t length = std::min(msg.len - 1, (uint32_t)MaxLength::MESSAGE_BODY);
+                CecMessage cecMessage{
+                        .initiator = static_cast<CecLogicalAddress>(msg.msg[0] >> 4),
+                        .destination = static_cast<CecLogicalAddress>(msg.msg[0] & 0xf),
+                };
+                cecMessage.body.resize(length);
+                for (size_t i = 0; i < length; ++i) {
+                    cecMessage.body[i] = static_cast<uint8_t>(msg.msg[i + 1]);
+                }
+                mCallback->onCecMessage(cecMessage);
+            } else {
+                LOG(ERROR) << "no event callback for message";
+            }
+        }
+    }
+    return NULL;
+}
+
+int HdmiCecDefault::getOpcode(struct cec_msg message) {
+    return (static_cast<uint8_t>(message.msg[1]) & 0xff);
+}
+
+bool HdmiCecDefault::isWakeupMessage(struct cec_msg message) {
+    int opcode = getOpcode(message);
+    switch (opcode) {
+        case CEC_MESSAGE_TEXT_VIEW_ON:
+        case CEC_MESSAGE_IMAGE_VIEW_ON:
+            return true;
+        default:
+            return false;
+    }
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace cec
+}  // namespace tv
+}  // namespace hardware
+}  // namespace android
diff --git a/tv/cec/1.0/default/HdmiCecDefault.h b/tv/cec/1.0/default/HdmiCecDefault.h
new file mode 100644
index 0000000..c1bb2c7
--- /dev/null
+++ b/tv/cec/1.0/default/HdmiCecDefault.h
@@ -0,0 +1,60 @@
+/*
+ * 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 <android/hardware/tv/cec/1.0/IHdmiCec.h>
+#include <hardware/hdmi_cec.h>
+
+namespace android {
+namespace hardware {
+namespace tv {
+namespace cec {
+namespace V1_0 {
+namespace implementation {
+
+struct HdmiCecDefault : public IHdmiCec, public hidl_death_recipient {
+    HdmiCecDefault();
+    ~HdmiCecDefault();
+    // Methods from ::android::hardware::tv::cec::V1_0::IHdmiCec follow.
+    Return<Result> addLogicalAddress(CecLogicalAddress addr) override;
+    Return<void> clearLogicalAddress() override;
+    Return<void> getPhysicalAddress(getPhysicalAddress_cb _hidl_cb) override;
+    Return<SendMessageResult> sendMessage(const CecMessage& message) override;
+    Return<void> setCallback(const sp<IHdmiCecCallback>& callback) override;
+    Return<int32_t> getCecVersion() override;
+    Return<uint32_t> getVendorId() override;
+    Return<void> getPortInfo(getPortInfo_cb _hidl_cb) override;
+    Return<void> setOption(OptionKey key, bool value) override;
+    Return<void> setLanguage(const hidl_string& language) override;
+    Return<void> enableAudioReturnChannel(int32_t portId, bool enable) override;
+    Return<bool> isConnected(int32_t portId) override;
+
+    virtual void serviceDied(uint64_t, const wp<::android::hidl::base::V1_0::IBase>&) {
+        setCallback(nullptr);
+    }
+
+    Return<Result> init();
+    Return<void> release();
+    static void* event_thread(void*);
+    static int getOpcode(struct cec_msg message);
+    static bool isWakeupMessage(struct cec_msg message);
+};
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace cec
+}  // namespace tv
+}  // namespace hardware
+}  // namespace android
diff --git a/vibrator/aidl/default/Vibrator.cpp b/vibrator/aidl/default/Vibrator.cpp
index c446afd..322833b 100644
--- a/vibrator/aidl/default/Vibrator.cpp
+++ b/vibrator/aidl/default/Vibrator.cpp
@@ -125,6 +125,11 @@
 
 ndk::ScopedAStatus Vibrator::getPrimitiveDuration(CompositePrimitive primitive,
                                                   int32_t* durationMs) {
+    std::vector<CompositePrimitive> supported;
+    getSupportedPrimitives(&supported);
+    if (std::find(supported.begin(), supported.end(), primitive) == supported.end()) {
+        return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+    }
     if (primitive != CompositePrimitive::NOOP) {
         *durationMs = 100;
     } else {
diff --git a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
index e51f594..4364df2 100644
--- a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
+++ b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
@@ -55,9 +55,12 @@
         android::enum_range<CompositePrimitive>().begin(),
         android::enum_range<CompositePrimitive>().end()};
 
-const std::vector<CompositePrimitive> kOptionalPrimitives = {
-        CompositePrimitive::THUD,
-        CompositePrimitive::SPIN,
+const std::vector<CompositePrimitive> kRequiredPrimitives = {
+        CompositePrimitive::CLICK,
+        CompositePrimitive::LIGHT_TICK,
+        CompositePrimitive::QUICK_RISE,
+        CompositePrimitive::SLOW_RISE,
+        CompositePrimitive::QUICK_FALL,
 };
 
 const std::vector<CompositePrimitive> kInvalidPrimitives = {
@@ -274,11 +277,11 @@
         for (auto primitive : kCompositePrimitives) {
             bool isPrimitiveSupported =
                     std::find(supported.begin(), supported.end(), primitive) != supported.end();
-            bool isPrimitiveOptional =
-                    std::find(kOptionalPrimitives.begin(), kOptionalPrimitives.end(), primitive) !=
-                    kOptionalPrimitives.end();
+            bool isPrimitiveRequired =
+                    std::find(kRequiredPrimitives.begin(), kRequiredPrimitives.end(), primitive) !=
+                    kRequiredPrimitives.end();
 
-            EXPECT_TRUE(isPrimitiveSupported || isPrimitiveOptional) << toString(primitive);
+            EXPECT_TRUE(isPrimitiveSupported || !isPrimitiveRequired) << toString(primitive);
         }
     }
 }
diff --git a/weaver/aidl/default/Android.bp b/weaver/aidl/default/Android.bp
index 37a9c94..70d9171 100644
--- a/weaver/aidl/default/Android.bp
+++ b/weaver/aidl/default/Android.bp
@@ -34,7 +34,7 @@
         "Weaver.cpp",
     ],
     shared_libs: [
-        "android.hardware.weaver-V1-ndk_platform",
+        "android.hardware.weaver-V1-ndk",
         "libbase",
         "libbinder_ndk",
     ],
diff --git a/weaver/aidl/vts/Android.bp b/weaver/aidl/vts/Android.bp
index 8dec4c1..cf1661c 100644
--- a/weaver/aidl/vts/Android.bp
+++ b/weaver/aidl/vts/Android.bp
@@ -34,7 +34,7 @@
         "libbinder_ndk",
         "libbase",
     ],
-    static_libs: ["android.hardware.weaver-V1-ndk_platform"],
+    static_libs: ["android.hardware.weaver-V1-ndk"],
     test_suites: [
         "general-tests",
         "vts",