Merge "le_audio_offload: Support two sources for conversational"
diff --git a/OWNERS b/OWNERS
index 3a1a038..a53d83e 100644
--- a/OWNERS
+++ b/OWNERS
@@ -9,6 +9,3 @@
 
 # historical/backup
 maco@google.com
-
-# vts tests
-guangzhu@google.com
diff --git a/audio/OWNERS b/audio/OWNERS
new file mode 100644
index 0000000..ede448c
--- /dev/null
+++ b/audio/OWNERS
@@ -0,0 +1 @@
+per-file README.md = elaurent@google.com,mnaganov@google.com
diff --git a/audio/aidl/Android.bp b/audio/aidl/Android.bp
index 6a0cfa5..3851c0f 100644
--- a/audio/aidl/Android.bp
+++ b/audio/aidl/Android.bp
@@ -44,9 +44,6 @@
             platform_apis: true,
         },
         ndk: {
-            vndk: {
-                enabled: true,
-            },
             apex_available: [
                 "//apex_available:platform",
                 "com.android.bluetooth",
diff --git a/audio/common/all-versions/default/tests/hidlutils_tests.cpp b/audio/common/all-versions/default/tests/hidlutils_tests.cpp
index ec16b02..e5ed844 100644
--- a/audio/common/all-versions/default/tests/hidlutils_tests.cpp
+++ b/audio/common/all-versions/default/tests/hidlutils_tests.cpp
@@ -17,6 +17,7 @@
 #include <array>
 #include <string>
 
+#include <android-base/test_utils.h>
 #include <gtest/gtest.h>
 
 #define LOG_TAG "HidlUtils_Test"
@@ -1100,6 +1101,7 @@
 TYPED_TEST_SUITE(FilterTest, FilterTestTypeParams);
 
 TYPED_TEST(FilterTest, FilterOutNonVendorTags) {
+    SKIP_WITH_HWASAN; // b/230535046
     TypeParam emptyTags;
     EXPECT_EQ(emptyTags, HidlUtils::filterOutNonVendorTags(emptyTags));
 
diff --git a/audio/common/all-versions/test/utility/src/ValidateXml.cpp b/audio/common/all-versions/test/utility/src/ValidateXml.cpp
index f111c01..4d6f003 100644
--- a/audio/common/all-versions/test/utility/src/ValidateXml.cpp
+++ b/audio/common/all-versions/test/utility/src/ValidateXml.cpp
@@ -63,11 +63,8 @@
         xmlSetGenericErrorFunc(this, errorCb);
     }
     ~Libxml2Global() {
-        // TODO: check if all those cleanup are needed
         xmlSetGenericErrorFunc(nullptr, nullptr);
-        xmlSchemaCleanupTypes();
         xmlCleanupParser();
-        xmlCleanupThreads();
     }
 
     const std::string& getErrors() { return errors; }
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 f25c391..dfc2386 100644
--- a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
@@ -715,7 +715,7 @@
             sink.base.channelMask.value(getConfig().base.channelMask);
             sink.ext.mix({});
             sink.ext.mix().ioHandle = helper.getIoHandle();
-            sink.ext.mix().useCase.source(toString(xsd::AudioSource::AUDIO_SOURCE_MIC));
+            sink.ext.mix().useCase.source(initMetadata.tracks[0].source);
             EXPECT_OK(getDevice()->createAudioPatch(hidl_vec<AudioPortConfig>{source},
                                                     hidl_vec<AudioPortConfig>{sink},
                                                     returnIn(res, mPatchHandle)));
diff --git a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
index fa3ee7f..61d447d 100644
--- a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
+++ b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
@@ -34,6 +34,7 @@
 
 #include <hwbinder/IPCThreadState.h>
 
+#include <android-base/expected.h>
 #include <android-base/logging.h>
 #include <system/audio_config.h>
 
@@ -130,6 +131,33 @@
     using IDevice = ::android::hardware::audio::CPP_VERSION::IDevice;
     using IDevicesFactory = ::android::hardware::audio::CPP_VERSION::IDevicesFactory;
 
+    static android::base::expected<std::vector<std::string>, std::string> getAllFactoryInstances() {
+        using ::android::hardware::audio::CPP_VERSION::IDevicesFactory;
+        const std::string factoryDescriptor = IDevicesFactory::descriptor;
+        // Make sure that the instance is the exact minor version.
+        // Using a 7.1 factory for 7.0 test is not always possible because
+        // 7.1 can be configured via the XML config to use features that are
+        // absent in 7.0.
+        auto instances = ::android::hardware::getAllHalInstanceNames(factoryDescriptor);
+        if (instances.empty()) return instances;
+        // Use the default instance for checking the implementation version.
+        auto defaultInstance = IDevicesFactory::getService("default");
+        if (defaultInstance == nullptr) {
+            return ::android::base::unexpected("Failed to obtain IDevicesFactory/default");
+        }
+        std::string actualDescriptor;
+        auto intDescRet = defaultInstance->interfaceDescriptor(
+                [&](const auto& descriptor) { actualDescriptor = descriptor; });
+        if (!intDescRet.isOk()) {
+            return ::android::base::unexpected("Failed to obtain interface descriptor: " +
+                                               intDescRet.description());
+        }
+        if (factoryDescriptor == actualDescriptor)
+            return instances;
+        else
+            return {};
+    }
+
     virtual ~HidlTest() = default;
     // public access to avoid annoyances when using this method in template classes
     // derived from test classes
@@ -174,9 +202,11 @@
 }
 
 TEST(CheckConfig, audioPolicyConfigurationValidation) {
-    const auto factories = ::android::hardware::getAllHalInstanceNames(
-            ::android::hardware::audio::CPP_VERSION::IDevicesFactory::descriptor);
-    if (factories.size() == 0) {
+    const auto factories = HidlTest::getAllFactoryInstances();
+    if (!factories.ok()) {
+        FAIL() << factories.error();
+    }
+    if (factories.value().size() == 0) {
         GTEST_SKIP() << "Skipping audioPolicyConfigurationValidation because no factory instances "
                         "are found.";
     }
@@ -205,11 +235,11 @@
 const std::vector<DeviceParameter>& getDeviceParameters() {
     static std::vector<DeviceParameter> parameters = [] {
         std::vector<DeviceParameter> result;
-        const auto factories = ::android::hardware::getAllHalInstanceNames(
-                ::android::hardware::audio::CPP_VERSION::IDevicesFactory::descriptor);
+        const auto factories = HidlTest::getAllFactoryInstances();
+        if (!factories.ok()) return result;
         const auto devices = getCachedPolicyConfig().getModulesWithDevicesNames();
         result.reserve(devices.size());
-        for (const auto& factoryName : factories) {
+        for (const auto& factoryName : factories.value()) {
             for (const auto& deviceName : devices) {
                 if (DeviceManager::getInstance().get(factoryName, deviceName) != nullptr) {
                     result.emplace_back(factoryName, deviceName);
@@ -224,9 +254,9 @@
 const std::vector<DeviceParameter>& getDeviceParametersForFactoryTests() {
     static std::vector<DeviceParameter> parameters = [] {
         std::vector<DeviceParameter> result;
-        const auto factories = ::android::hardware::getAllHalInstanceNames(
-                ::android::hardware::audio::CPP_VERSION::IDevicesFactory::descriptor);
-        for (const auto& factoryName : factories) {
+        const auto factories = HidlTest::getAllFactoryInstances();
+        if (!factories.ok()) return result;
+        for (const auto& factoryName : factories.value()) {
             result.emplace_back(factoryName,
                                 DeviceManager::getInstance().getPrimary(factoryName) != nullptr
                                         ? DeviceManager::kPrimaryDevice
@@ -1209,23 +1239,30 @@
     : public OpenStreamTest<::android::hardware::audio::CORE_TYPES_CPP_VERSION::IStreamIn> {
     void SetUp() override {
         ASSERT_NO_FATAL_FAILURE(OpenStreamTest::SetUp());  // setup base
+        auto flags = getInputFlags();
 #if MAJOR_VERSION <= 6
         address.device = AudioDevice::IN_DEFAULT;
 #elif MAJOR_VERSION >= 7
         auto maybeSourceAddress = getCachedPolicyConfig().getSourceDeviceForMixPort(
                 getDeviceName(), getMixPortName());
+        auto& metadata = initMetadata.tracks[0];
         if (maybeSourceAddress.has_value() &&
             !xsd::isTelephonyDevice(maybeSourceAddress.value().deviceType)) {
             address = maybeSourceAddress.value();
-            auto& metadata = initMetadata.tracks[0];
             metadata.source = toString(xsd::AudioSource::AUDIO_SOURCE_UNPROCESSED);
             metadata.channelMask = getConfig().base.channelMask;
         } else {
             address.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_IN_DEFAULT);
         }
-#endif
+#if MAJOR_VERSION == 7 && MINOR_VERSION >= 1
+        auto flagsIt = std::find(flags.begin(), flags.end(),
+                                 toString(xsd::AudioInOutFlag::AUDIO_INPUT_FLAG_ULTRASOUND));
+        if (flagsIt != flags.end()) {
+            metadata.source = toString(xsd::AudioSource::AUDIO_SOURCE_ULTRASOUND);
+        }
+#endif  // 7.1
+#endif  // MAJOR_VERSION >= 7
         const AudioConfig& config = getConfig();
-        auto flags = getInputFlags();
         testOpen(
                 [&](AudioIoHandle handle, AudioConfig config, auto cb) {
                     return getDevice()->openInputStream(handle, address, config, flags,
diff --git a/audio/core/all-versions/vts/functional/VtsHalAudioV6_0TargetTest.xml b/audio/core/all-versions/vts/functional/VtsHalAudioV6_0TargetTest.xml
index ae57125..1e73f8a 100644
--- a/audio/core/all-versions/vts/functional/VtsHalAudioV6_0TargetTest.xml
+++ b/audio/core/all-versions/vts/functional/VtsHalAudioV6_0TargetTest.xml
@@ -34,6 +34,6 @@
     <test class="com.android.tradefed.testtype.GTest" >
         <option name="native-test-device-path" value="/data/local/tmp" />
         <option name="module-name" value="VtsHalAudioV6_0TargetTest" />
-        <option name="native-test-timeout" value="5m" />
+        <option name="native-test-timeout" value="10m" />
     </test>
 </configuration>
diff --git a/audio/core/all-versions/vts/functional/VtsHalAudioV7_0TargetTest.xml b/audio/core/all-versions/vts/functional/VtsHalAudioV7_0TargetTest.xml
index 55dbaf1..f0e2695 100644
--- a/audio/core/all-versions/vts/functional/VtsHalAudioV7_0TargetTest.xml
+++ b/audio/core/all-versions/vts/functional/VtsHalAudioV7_0TargetTest.xml
@@ -34,6 +34,6 @@
     <test class="com.android.tradefed.testtype.GTest" >
         <option name="native-test-device-path" value="/data/local/tmp" />
         <option name="module-name" value="VtsHalAudioV7_0TargetTest" />
-        <option name="native-test-timeout" value="5m" />
+        <option name="native-test-timeout" value="10m" />
     </test>
 </configuration>
diff --git a/audio/core/all-versions/vts/functional/VtsHalAudioV7_1TargetTest.xml b/audio/core/all-versions/vts/functional/VtsHalAudioV7_1TargetTest.xml
index 7b33a8f..7ce1477 100644
--- a/audio/core/all-versions/vts/functional/VtsHalAudioV7_1TargetTest.xml
+++ b/audio/core/all-versions/vts/functional/VtsHalAudioV7_1TargetTest.xml
@@ -34,6 +34,6 @@
     <test class="com.android.tradefed.testtype.GTest" >
         <option name="native-test-device-path" value="/data/local/tmp" />
         <option name="module-name" value="VtsHalAudioV7_1TargetTest" />
-        <option name="native-test-timeout" value="5m" />
+        <option name="native-test-timeout" value="10m" />
     </test>
 </configuration>
diff --git a/audio/policy/1.0/xml/api/current.txt b/audio/policy/1.0/xml/api/current.txt
index 29a9cd4..0b77d45 100644
--- a/audio/policy/1.0/xml/api/current.txt
+++ b/audio/policy/1.0/xml/api/current.txt
@@ -232,10 +232,12 @@
 
   public class ValueType {
     ctor public ValueType();
+    method public String getAndroid_type();
     method public String getLiteral();
-    method public int getNumerical();
+    method public long getNumerical();
+    method public void setAndroid_type(String);
     method public void setLiteral(String);
-    method public void setNumerical(int);
+    method public void setNumerical(long);
   }
 
   public class ValuesType {
diff --git a/audio/policy/1.0/xml/audio_policy_engine_configuration.xsd b/audio/policy/1.0/xml/audio_policy_engine_configuration.xsd
index 842e724..3ce12e7 100644
--- a/audio/policy/1.0/xml/audio_policy_engine_configuration.xsd
+++ b/audio/policy/1.0/xml/audio_policy_engine_configuration.xsd
@@ -189,9 +189,20 @@
     </xs:complexType>
     <xs:complexType name="valueType">
         <xs:attribute name="literal" type="xs:string" use="required"/>
-        <xs:attribute name="numerical" type="xs:int" use="required"/>
+        <xs:attribute name="numerical" type="xs:long" use="required"/>
+        <xs:attribute name="android_type" type="longDecimalOrHexType" use="optional"/>
     </xs:complexType>
 
+    <xs:simpleType name="longDecimalOrHexType">
+      <xs:union memberTypes="xs:long longHexType" />
+    </xs:simpleType>
+
+    <xs:simpleType name="longHexType">
+      <xs:restriction base="xs:string">
+        <xs:pattern value="0x[0-9A-Fa-f]{1,16}"/>
+      </xs:restriction>
+    </xs:simpleType>
+
     <xs:complexType name="attributesRefType">
         <xs:sequence>
             <xs:element name="Attributes" type="AttributesType" minOccurs="1" maxOccurs="1"/>
diff --git a/authsecret/aidl/Android.bp b/authsecret/aidl/Android.bp
index 432c1b9..90e128d 100644
--- a/authsecret/aidl/Android.bp
+++ b/authsecret/aidl/Android.bp
@@ -16,11 +16,6 @@
         java: {
             platform_apis: true,
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
     },
     versions: ["1"],
 }
diff --git a/automotive/OWNERS b/automotive/OWNERS
index 43c5f3e..09e257c 100644
--- a/automotive/OWNERS
+++ b/automotive/OWNERS
@@ -1,6 +1 @@
-pirozzoj@google.com
-twasilczyk@google.com
-krachuri@google.com
-gurunagarajan@google.com
-keunyoung@google.com
-felipeal@google.com
+include platform/packages/services/Car:/OWNERS
diff --git a/automotive/audiocontrol/OWNERS b/automotive/audiocontrol/OWNERS
new file mode 100644
index 0000000..f55eff3
--- /dev/null
+++ b/automotive/audiocontrol/OWNERS
@@ -0,0 +1 @@
+oscarazu@google.com
diff --git a/automotive/can/OWNERS b/automotive/can/OWNERS
new file mode 100644
index 0000000..ffa4828
--- /dev/null
+++ b/automotive/can/OWNERS
@@ -0,0 +1,3 @@
+kevinme@google.com
+chrisweir@google.com
+twasilczyk@google.com
diff --git a/automotive/occupant_awareness/aidl/Android.bp b/automotive/occupant_awareness/aidl/Android.bp
index 26c53fa..1b180d9 100644
--- a/automotive/occupant_awareness/aidl/Android.bp
+++ b/automotive/occupant_awareness/aidl/Android.bp
@@ -18,11 +18,6 @@
         java: {
             platform_apis: true,
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
     },
     versions: ["1"],
 }
diff --git a/automotive/sv/1.0/default/Android.bp b/automotive/sv/1.0/default/Android.bp
index da974a0..82e11a8 100644
--- a/automotive/sv/1.0/default/Android.bp
+++ b/automotive/sv/1.0/default/Android.bp
@@ -29,9 +29,7 @@
     relative_install_path: "hw",
     srcs: [
         "service.cpp",
-        "SurroundViewService.cpp",
-        "SurroundView2dSession.cpp",
-        "SurroundView3dSession.cpp",
+        ":automotiveSvV1.0_sources",
     ],
     init_rc: ["android.hardware.automotive.sv@1.0-service.rc"],
     vintf_fragments: ["android.hardware.automotive.sv@1.0-service.xml"],
@@ -54,3 +52,17 @@
         "-g",
     ],
 }
+
+filegroup {
+    name: "automotiveSvV1.0_sources",
+    srcs: [
+        "SurroundViewService.cpp",
+        "SurroundView2dSession.cpp",
+        "SurroundView3dSession.cpp",
+    ],
+}
+
+cc_library_headers {
+    name: "automotiveSvV1.0_headers",
+    export_include_dirs: ["."],
+}
diff --git a/automotive/sv/1.0/default/tests/fuzzer/Android.bp b/automotive/sv/1.0/default/tests/fuzzer/Android.bp
new file mode 100644
index 0000000..394c532
--- /dev/null
+++ b/automotive/sv/1.0/default/tests/fuzzer/Android.bp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2022 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 {
+    // 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"],
+}
+
+cc_fuzz {
+    name: "automotiveSvV1.0_fuzzer",
+    srcs: [
+        "AutomotiveSvV1_0Fuzzer.cpp",
+        "SurroundViewStream.cpp",
+        ":automotiveSvV1.0_sources",
+    ],
+    header_libs: [
+        "automotiveSvV1.0_headers",
+    ],
+    shared_libs: [
+        "android.hardware.automotive.sv@1.0",
+        "android.hidl.allocator@1.0",
+        "libhidlbase",
+        "libutils",
+        "libhidlmemory",
+        "liblog",
+    ],
+    fuzz_config: {
+        cc: [
+            "android-media-fuzzing-reports@google.com",
+        ],
+        componentid: 533764,
+    },
+}
diff --git a/automotive/sv/1.0/default/tests/fuzzer/AutomotiveSvV1_0Fuzzer.cpp b/automotive/sv/1.0/default/tests/fuzzer/AutomotiveSvV1_0Fuzzer.cpp
new file mode 100644
index 0000000..98834f5
--- /dev/null
+++ b/automotive/sv/1.0/default/tests/fuzzer/AutomotiveSvV1_0Fuzzer.cpp
@@ -0,0 +1,433 @@
+/*
+ * Copyright (C) 2022 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 "AutomotiveSvV1_0Fuzzer.h"
+#include <SurroundViewStream.h>
+#include <android/hidl/allocator/1.0/IAllocator.h>
+#include <hidlmemory/mapping.h>
+
+namespace android::hardware::automotive::sv::V1_0::implementation::fuzzer {
+
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hidl::allocator::V1_0::IAllocator;
+
+constexpr uint32_t kMinConfigDimension = 0;
+constexpr uint32_t kMaxConfigDimension = 4096;
+constexpr uint32_t kVertexByteSize = (3 * sizeof(float)) + 4;
+constexpr uint32_t kIdByteSize = 2;
+constexpr size_t kMaxCharacters = 30;
+constexpr size_t kMaxVertices = 10;
+constexpr size_t kMaxCameraPoints = 10;
+constexpr size_t kMaxViews = 10;
+constexpr size_t kMaxOverlays = 10;
+constexpr size_t kMinSvBuffers = 0;
+constexpr size_t kMaxSvBuffers = 10;
+
+void SurroundViewFuzzer::invoke2dSessionAPI() {
+    sp<ISurroundView2dSession> surroundView2dSession;
+
+    while (mFuzzedDataProvider.remaining_bytes() > 0) {
+        auto surroundView2dFunc = mFuzzedDataProvider.PickValueInArray<
+                const std::function<void()>>({
+                [&]() {
+                    mSurroundViewService->start2dSession(
+                            [&surroundView2dSession](const sp<ISurroundView2dSession>& session,
+                                                     SvResult result) {
+                                if (result == SvResult::OK) {
+                                    surroundView2dSession = session;
+                                }
+                            });
+                },
+                [&]() {
+                    if (surroundView2dSession) {
+                        sp<SurroundViewStream> handler =
+                                sp<SurroundViewStream>::make(surroundView2dSession);
+                        surroundView2dSession->startStream(handler);
+                        mIs2dStreamStarted = true;
+                    }
+                },
+                [&]() {
+                    if (surroundView2dSession) {
+                        surroundView2dSession->get2dMappingInfo(
+                                []([[maybe_unused]] Sv2dMappingInfo info) {});
+                    }
+                },
+                [&]() {
+                    if (surroundView2dSession) {
+                        Sv2dConfig config;
+                        config.width = mFuzzedDataProvider.ConsumeIntegralInRange<uint32_t>(
+                                kMinConfigDimension, kMaxConfigDimension);
+                        if (mFuzzedDataProvider.ConsumeBool()) {
+                            config.blending = static_cast<SvQuality>(
+                                    mFuzzedDataProvider.ConsumeIntegral<uint32_t>());
+                        } else {
+                            config.blending = mFuzzedDataProvider.ConsumeBool() ? (SvQuality::HIGH)
+                                                                                : (SvQuality::LOW);
+                        }
+                        surroundView2dSession->set2dConfig(config);
+                    }
+                },
+                [&]() {
+                    if (surroundView2dSession) {
+                        surroundView2dSession->get2dConfig([&](Sv2dConfig) {});
+                    }
+                },
+                [&]() {
+                    if (surroundView2dSession) {
+                        hidl_vec<Point2dInt> points2dCamera;
+                        const size_t camPoints = mFuzzedDataProvider.ConsumeIntegralInRange<size_t>(
+                                1, kMaxCameraPoints);
+                        points2dCamera.resize(camPoints);
+                        for (size_t i = 0; i < camPoints; ++i) {
+                            points2dCamera[i].x = mFuzzedDataProvider.ConsumeFloatingPoint<float>();
+                            points2dCamera[i].y = mFuzzedDataProvider.ConsumeFloatingPoint<float>();
+                        }
+
+                        hidl_vec<hidl_string> cameraIds;
+                        mSurroundViewService->getCameraIds(
+                                [&cameraIds](const hidl_vec<hidl_string>& camIds) {
+                                    cameraIds = camIds;
+                                });
+                        hidl_string cameraId;
+                        if (cameraIds.size() > 0 && mFuzzedDataProvider.ConsumeBool()) {
+                            const size_t cameraIndex =
+                                    mFuzzedDataProvider.ConsumeIntegralInRange<size_t>(
+                                            0, cameraIds.size() - 1);
+                            cameraId = cameraIds[cameraIndex];
+                        } else {
+                            cameraId =
+                                    mFuzzedDataProvider.ConsumeRandomLengthString(kMaxCharacters);
+                        }
+                        surroundView2dSession->projectCameraPoints(
+                                points2dCamera, cameraId,
+                                []([[maybe_unused]] const hidl_vec<Point2dFloat>& outPoints) {});
+                    }
+                },
+                [&]() {
+                    if (surroundView2dSession) {
+                        SvFramesDesc frames;
+                        frames.timestampNs = mFuzzedDataProvider.ConsumeIntegral<uint64_t>();
+                        frames.sequenceId = mFuzzedDataProvider.ConsumeIntegral<uint32_t>();
+                        size_t numSvBuffers = mFuzzedDataProvider.ConsumeIntegralInRange<size_t>(
+                                kMinSvBuffers, kMaxSvBuffers);
+                        frames.svBuffers.resize(numSvBuffers);
+                        for (int i = 0; i < numSvBuffers; ++i) {
+                            frames.svBuffers[i].viewId =
+                                    mFuzzedDataProvider.ConsumeIntegral<uint32_t>();
+                            frames.svBuffers[i].hardwareBuffer.nativeHandle = new native_handle_t();
+                            frames.svBuffers[i].hardwareBuffer.description[0] =
+                                    mFuzzedDataProvider.ConsumeIntegral<uint32_t>();
+                            frames.svBuffers[i].hardwareBuffer.description[1] =
+                                    mFuzzedDataProvider.ConsumeIntegral<uint32_t>();
+                        }
+                        surroundView2dSession->doneWithFrames(frames);
+                        for (int i = 0; i < numSvBuffers; ++i) {
+                            delete frames.svBuffers[i].hardwareBuffer.nativeHandle;
+                        }
+                    }
+                },
+                [&]() {
+                    if (surroundView2dSession) {
+                        surroundView2dSession->stopStream();
+                        mIs2dStreamStarted = false;
+                    }
+                },
+                [&]() {
+                    mSurroundViewService->stop2dSession(
+                            mFuzzedDataProvider.ConsumeBool() ? surroundView2dSession : nullptr);
+                },
+        });
+        surroundView2dFunc();
+    }
+
+    if (surroundView2dSession && mIs2dStreamStarted) {
+        surroundView2dSession->stopStream();
+    }
+}
+
+void SurroundViewFuzzer::invoke3dSessionAPI() {
+    sp<ISurroundView3dSession> surroundView3dSession;
+    while (mFuzzedDataProvider.remaining_bytes() > 0) {
+        auto surroundView3dFunc = mFuzzedDataProvider.PickValueInArray<
+                const std::function<void()>>({
+                [&]() {
+                    mSurroundViewService->start3dSession(
+                            [&surroundView3dSession](const sp<ISurroundView3dSession>& session,
+                                                     SvResult result) {
+                                if (result == SvResult::OK) {
+                                    surroundView3dSession = session;
+                                }
+                            });
+                },
+                [&]() {
+                    if (surroundView3dSession) {
+                        sp<SurroundViewStream> handler =
+                                sp<SurroundViewStream>::make(surroundView3dSession);
+                        surroundView3dSession->startStream(handler);
+                        mIs3dStreamStarted = true;
+                    }
+                },
+                [&]() {
+                    if (surroundView3dSession) {
+                        const size_t numViews =
+                                mFuzzedDataProvider.ConsumeIntegralInRange<size_t>(1, kMaxViews);
+                        std::vector<View3d> views(numViews);
+                        for (size_t i = 0; i < numViews; ++i) {
+                            views[i].viewId = mFuzzedDataProvider.ConsumeIntegral<uint32_t>();
+                        }
+                        surroundView3dSession->setViews(views);
+                    }
+                },
+                [&]() {
+                    if (surroundView3dSession) {
+                        Sv3dConfig config;
+                        config.width = mFuzzedDataProvider.ConsumeIntegralInRange<uint32_t>(
+                                kMinConfigDimension, kMaxConfigDimension);
+                        config.height = mFuzzedDataProvider.ConsumeIntegralInRange<uint32_t>(
+                                kMinConfigDimension, kMaxConfigDimension);
+                        if (mFuzzedDataProvider.ConsumeBool()) {
+                            config.carDetails = static_cast<SvQuality>(
+                                    mFuzzedDataProvider.ConsumeIntegral<uint32_t>());
+                        } else {
+                            config.carDetails = mFuzzedDataProvider.ConsumeBool()
+                                                        ? (SvQuality::HIGH)
+                                                        : (SvQuality::LOW);
+                        }
+                        surroundView3dSession->set3dConfig(config);
+                    }
+                },
+                [&]() {
+                    if (surroundView3dSession) {
+                        surroundView3dSession->get3dConfig([&](Sv3dConfig) {});
+                    }
+                },
+                [&]() {
+                    if (surroundView3dSession) {
+                        Point2dInt cameraPoint;
+                        cameraPoint.x = mFuzzedDataProvider.ConsumeFloatingPoint<float>();
+                        cameraPoint.y = mFuzzedDataProvider.ConsumeFloatingPoint<float>();
+                        std::vector<Point2dInt> cameraPoints = {cameraPoint};
+                        hidl_vec<hidl_string> cameraIds;
+                        mSurroundViewService->getCameraIds(
+                                [&cameraIds](const hidl_vec<hidl_string>& camIds) {
+                                    cameraIds = camIds;
+                                });
+                        hidl_string cameraId;
+                        if (cameraIds.size() > 0 && mFuzzedDataProvider.ConsumeBool()) {
+                            const size_t cameraIndex =
+                                    mFuzzedDataProvider.ConsumeIntegralInRange<size_t>(
+                                            0, cameraIds.size() - 1);
+                            cameraId = cameraIds[cameraIndex];
+                        } else {
+                            cameraId =
+                                    mFuzzedDataProvider.ConsumeRandomLengthString(kMaxCharacters);
+                        }
+                        std::vector<Point3dFloat> points3d;
+                        surroundView3dSession->projectCameraPointsTo3dSurface(
+                                cameraPoints, cameraId,
+                                [&points3d]([[maybe_unused]] const hidl_vec<Point3dFloat>&
+                                                    points3dproj) { points3d = points3dproj; });
+                    }
+                },
+                [&]() {
+                    if (surroundView3dSession) {
+                        // success case
+                        surroundView3dSession->updateOverlays(mOverlaysdata);
+                    }
+                },
+                [&]() {
+                    if (surroundView3dSession) {
+                        initSampleOverlaysData();
+                        // Fail with ID mismatch
+                        // Set id of second overlay in shared memory to 2 (expected is 1).
+                        auto& overlaysDescVector = mOverlaysdata.overlaysMemoryDesc;
+                        auto& pIMemory = mMemory;
+                        int32_t indexPosition = mFuzzedDataProvider.ConsumeIntegralInRange<int32_t>(
+                                0, mNumOverlays - 1);
+                        int32_t mismatchedValueIndex =
+                                mFuzzedDataProvider.ConsumeIntegralInRange<int32_t>(
+                                        0, mNumOverlays - 1);
+                        setIndexOfOverlaysMemory(overlaysDescVector, pIMemory, indexPosition,
+                                                 overlaysDescVector[mismatchedValueIndex].id);
+                        surroundView3dSession->updateOverlays(mOverlaysdata);
+                    }
+                },
+                [&]() {
+                    if (surroundView3dSession) {
+                        // Fail with NULL memory
+                        // Set shared memory to null.
+                        mOverlaysdata.overlaysMemory = hidl_memory();
+                        surroundView3dSession->updateOverlays(mOverlaysdata);
+                    }
+                },
+                [&]() {
+                    if (surroundView3dSession) {
+                        SvFramesDesc frames;
+                        frames.timestampNs = mFuzzedDataProvider.ConsumeIntegral<uint64_t>();
+                        frames.sequenceId = mFuzzedDataProvider.ConsumeIntegral<uint32_t>();
+                        size_t numSvBuffers = mFuzzedDataProvider.ConsumeIntegralInRange<size_t>(
+                                kMinSvBuffers, kMaxSvBuffers);
+                        frames.svBuffers.resize(numSvBuffers);
+                        for (int i = 0; i < numSvBuffers; ++i) {
+                            frames.svBuffers[i].viewId =
+                                    mFuzzedDataProvider.ConsumeIntegral<uint32_t>();
+                            frames.svBuffers[i].hardwareBuffer.nativeHandle = new native_handle_t();
+                            frames.svBuffers[i].hardwareBuffer.description[0] =
+                                    mFuzzedDataProvider.ConsumeIntegral<uint32_t>();
+                            frames.svBuffers[i].hardwareBuffer.description[1] =
+                                    mFuzzedDataProvider.ConsumeIntegral<uint32_t>();
+                        }
+                        surroundView3dSession->doneWithFrames(frames);
+                        for (int i = 0; i < numSvBuffers; ++i) {
+                            delete frames.svBuffers[i].hardwareBuffer.nativeHandle;
+                        }
+                    }
+                },
+                [&]() {
+                    if (surroundView3dSession) {
+                        surroundView3dSession->stopStream();
+                        mIs3dStreamStarted = false;
+                    }
+                },
+                [&]() {
+                    mSurroundViewService->stop3dSession(
+                            mFuzzedDataProvider.ConsumeBool() ? surroundView3dSession : nullptr);
+                },
+        });
+        surroundView3dFunc();
+    }
+    if (surroundView3dSession && mIs3dStreamStarted) {
+        surroundView3dSession->stopStream();
+    }
+}
+
+void SurroundViewFuzzer::process() {
+    mFuzzedDataProvider.ConsumeBool() ? invoke2dSessionAPI() : invoke3dSessionAPI();
+}
+
+std::pair<hidl_memory, sp<IMemory>> SurroundViewFuzzer::getMappedSharedMemory(int32_t bytesSize) {
+    const auto nullResult = std::make_pair(hidl_memory(), nullptr);
+
+    sp<IAllocator> ashmemAllocator = IAllocator::getService("ashmem");
+    if (ashmemAllocator.get() == nullptr) {
+        return nullResult;
+    }
+
+    // Allocate shared memory.
+    hidl_memory hidlMemory;
+    bool allocateSuccess = false;
+    Return<void> result =
+            ashmemAllocator->allocate(bytesSize, [&](bool success, const hidl_memory& hidlMem) {
+                if (!success) {
+                    return;
+                }
+                allocateSuccess = success;
+                hidlMemory = hidlMem;
+            });
+
+    // Check result of allocated memory.
+    if (!result.isOk() || !allocateSuccess) {
+        return nullResult;
+    }
+
+    // Map shared memory.
+    sp<IMemory> pIMemory = mapMemory(hidlMemory);
+    if (pIMemory.get() == nullptr) {
+        return nullResult;
+    }
+
+    return std::make_pair(hidlMemory, pIMemory);
+}
+
+void SurroundViewFuzzer::setIndexOfOverlaysMemory(
+        const std::vector<OverlayMemoryDesc>& overlaysMemDesc, sp<IMemory> pIMemory,
+        int32_t indexPosition, uint16_t indexValue) {
+    // Count the number of vertices until the index.
+    int32_t totalVerticesCount = 0;
+    for (int32_t i = 0; i < indexPosition; ++i) {
+        totalVerticesCount += overlaysMemDesc[i].verticesCount;
+    }
+
+    const int32_t indexBytePosition =
+            (indexPosition * kIdByteSize) + (kVertexByteSize * totalVerticesCount);
+
+    uint8_t* pSharedMemoryData = (uint8_t*)((void*)pIMemory->getPointer());
+    pSharedMemoryData += indexBytePosition;
+    uint16_t* pIndex16bit = (uint16_t*)pSharedMemoryData;
+
+    // Modify shared memory.
+    pIMemory->update();
+    *pIndex16bit = indexValue;
+    pIMemory->commit();
+}
+
+void SurroundViewFuzzer::initSampleOverlaysData() {
+    const size_t mNumOverlays =
+            mFuzzedDataProvider.ConsumeIntegralInRange<size_t>(kMinOverlays, kMaxOverlays);
+    mOverlaysdata.overlaysMemoryDesc.resize(mNumOverlays);
+
+    int32_t sharedMemBytesSize = 0;
+    std::vector<OverlayMemoryDesc> overlaysDescVector = {};
+    OverlayMemoryDesc overlayMemDesc[mNumOverlays];
+    for (size_t i = 0; i < mNumOverlays; ++i) {
+        overlayMemDesc[i].id = i;
+        overlayMemDesc[i].verticesCount =
+                mFuzzedDataProvider.ConsumeIntegralInRange<size_t>(1, kMaxVertices);
+        overlayMemDesc[i].overlayPrimitive = mFuzzedDataProvider.ConsumeBool()
+                                                     ? (OverlayPrimitive::TRIANGLES)
+                                                     : (OverlayPrimitive::TRIANGLES_STRIP);
+        mOverlaysdata.overlaysMemoryDesc[i] = overlayMemDesc[i];
+
+        sharedMemBytesSize += kIdByteSize + kVertexByteSize * overlayMemDesc[i].verticesCount;
+        overlaysDescVector.push_back(overlayMemDesc[i]);
+    }
+
+    std::pair<hidl_memory, sp<IMemory>> sharedMem = getMappedSharedMemory(sharedMemBytesSize);
+    sp<IMemory> pIMemory = std::get<1>(sharedMem);
+    if (pIMemory.get() == nullptr) {
+        mOverlaysdata = OverlaysData();
+        mMemory = nullptr;
+        return;
+    }
+
+    // Get pointer to shared memory data and set all bytes to 0.
+    uint8_t* pSharedMemoryData = (uint8_t*)((void*)pIMemory->getPointer());
+    pIMemory->update();
+    memset(pSharedMemoryData, 0, sharedMemBytesSize);
+    pIMemory->commit();
+
+    // Set indexes in shared memory.
+    for (size_t i = 0; i < mNumOverlays; ++i) {
+        setIndexOfOverlaysMemory(overlaysDescVector, pIMemory, i, overlayMemDesc[i].id);
+    }
+
+    mOverlaysdata.overlaysMemoryDesc = overlaysDescVector;
+    mOverlaysdata.overlaysMemory = std::get<0>(sharedMem);
+    mMemory = pIMemory;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    if (size < 1) {
+        return 0;
+    }
+    SurroundViewFuzzer surroundViewFuzzer(data, size);
+    surroundViewFuzzer.process();
+    return 0;
+}
+}  // namespace android::hardware::automotive::sv::V1_0::implementation::fuzzer
diff --git a/automotive/sv/1.0/default/tests/fuzzer/AutomotiveSvV1_0Fuzzer.h b/automotive/sv/1.0/default/tests/fuzzer/AutomotiveSvV1_0Fuzzer.h
new file mode 100644
index 0000000..23e5a31
--- /dev/null
+++ b/automotive/sv/1.0/default/tests/fuzzer/AutomotiveSvV1_0Fuzzer.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#pragma once
+#include <SurroundViewService.h>
+#include <android/hidl/memory/1.0/IMemory.h>
+#include <fuzzer/FuzzedDataProvider.h>
+
+namespace android::hardware::automotive::sv::V1_0::implementation::fuzzer {
+
+using ::android::sp;
+using ::android::hidl::memory::V1_0::IMemory;
+
+constexpr size_t kMinOverlays = 2;
+
+class SurroundViewFuzzer {
+  public:
+    SurroundViewFuzzer(const uint8_t* data, size_t size) : mFuzzedDataProvider(data, size) {
+        mSurroundViewService = sp<SurroundViewService>::make();
+    }
+    ~SurroundViewFuzzer() = default;
+    void process();
+
+  private:
+    void invoke2dSessionAPI();
+    void invoke3dSessionAPI();
+    std::pair<hidl_memory, sp<IMemory>> getMappedSharedMemory(int32_t bytesSize);
+    void initSampleOverlaysData();
+    void setIndexOfOverlaysMemory(const std::vector<OverlayMemoryDesc>& overlaysMemDesc,
+                                  sp<IMemory> pIMemory, int32_t indexPosition, uint16_t indexValue);
+    OverlaysData mOverlaysdata = {};
+    size_t mNumOverlays = kMinOverlays;
+    sp<IMemory> mMemory = nullptr;
+    FuzzedDataProvider mFuzzedDataProvider;
+    sp<SurroundViewService> mSurroundViewService = nullptr;
+    bool mIs2dStreamStarted = false;
+    bool mIs3dStreamStarted = false;
+};
+}  // namespace android::hardware::automotive::sv::V1_0::implementation::fuzzer
diff --git a/automotive/sv/1.0/default/tests/fuzzer/SurroundViewStream.cpp b/automotive/sv/1.0/default/tests/fuzzer/SurroundViewStream.cpp
new file mode 100644
index 0000000..b81a08c
--- /dev/null
+++ b/automotive/sv/1.0/default/tests/fuzzer/SurroundViewStream.cpp
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2022 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 "SurroundViewStream.h"
+
+namespace android::hardware::automotive::sv::V1_0::implementation::fuzzer {
+
+using std::lock_guard;
+
+SurroundViewStream::SurroundViewStream(sp<ISurroundViewSession> pSession)
+    : mSession(pSession), mReceiveFramesCount(0) {}
+
+Return<void> SurroundViewStream::notify(SvEvent svEvent) {
+    lock_guard<mutex> lock(mLock);
+    switch (svEvent) {
+        case SvEvent::STREAM_STARTED:
+        case SvEvent::CONFIG_UPDATED:
+        case SvEvent::STREAM_STOPPED:
+        case SvEvent::FRAME_DROPPED:
+        case SvEvent::TIMEOUT:
+            mReceivedEvents.emplace_back(svEvent);
+            break;
+        default:
+            break;
+    }
+
+    return android::hardware::Void();
+}
+
+Return<void> SurroundViewStream::receiveFrames(const SvFramesDesc& svFramesDesc) {
+    lock_guard<mutex> lock(mLock);
+    if ((mLastReceivedFrames.timestampNs >= svFramesDesc.timestampNs ||
+         mLastReceivedFrames.sequenceId >= svFramesDesc.sequenceId) &&
+        mReceiveFramesCount != 0) {
+        // The incoming frames are with invalid timestamp or sequenceId
+        mAllFramesValid = false;
+    }
+
+    for (int i = 0; i < svFramesDesc.svBuffers.size(); ++i) {
+        if (svFramesDesc.svBuffers[i].hardwareBuffer.nativeHandle == nullptr) {
+            mAllFramesValid = false;
+            // The incoming frames are with invalid nativeHandle
+            break;
+        }
+    }
+
+    ++mReceiveFramesCount;
+
+    // Store all the information except for the handle
+    mLastReceivedFrames.timestampNs = svFramesDesc.timestampNs;
+    mLastReceivedFrames.sequenceId = svFramesDesc.sequenceId;
+    mLastReceivedFrames.svBuffers.resize(svFramesDesc.svBuffers.size());
+    for (int i = 0; i < svFramesDesc.svBuffers.size(); ++i) {
+        mLastReceivedFrames.svBuffers[i].viewId = svFramesDesc.svBuffers[i].viewId;
+        mLastReceivedFrames.svBuffers[i].hardwareBuffer.description =
+                svFramesDesc.svBuffers[i].hardwareBuffer.description;
+    }
+
+    return android::hardware::Void();
+}
+}  // namespace android::hardware::automotive::sv::V1_0::implementation::fuzzer
diff --git a/automotive/sv/1.0/default/tests/fuzzer/SurroundViewStream.h b/automotive/sv/1.0/default/tests/fuzzer/SurroundViewStream.h
new file mode 100644
index 0000000..8135bc1
--- /dev/null
+++ b/automotive/sv/1.0/default/tests/fuzzer/SurroundViewStream.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/hardware/automotive/sv/1.0/ISurroundViewSession.h>
+#include <android/hardware/automotive/sv/1.0/ISurroundViewStream.h>
+#include <android/hardware/automotive/sv/1.0/types.h>
+
+#include <thread>
+#include <vector>
+
+namespace android::hardware::automotive::sv::V1_0::implementation::fuzzer {
+
+using android::sp;
+using android::hardware::Return;
+using std::mutex;
+using std::vector;
+
+class SurroundViewStream : public ISurroundViewStream {
+  public:
+    SurroundViewStream(sp<ISurroundViewSession> session);
+
+    Return<void> notify(SvEvent svEvent) override;
+    Return<void> receiveFrames(const SvFramesDesc& svFramesDesc) override;
+
+    bool checkEventReceived(SvEvent svEvent);
+    SvFramesDesc getLastReceivedFrames();
+    int getReceiveFramesCount();
+    bool areAllFramesValid();
+    void setDoNotReturnFrames(bool flag);
+
+  private:
+    mutex mLock;
+
+    vector<SvEvent> mReceivedEvents;
+    sp<ISurroundViewSession> mSession;
+    SvFramesDesc mLastReceivedFrames;
+    int mReceiveFramesCount;
+    bool mAllFramesValid = true;
+};
+}  // namespace android::hardware::automotive::sv::V1_0::implementation::fuzzer
diff --git a/automotive/sv/OWNERS b/automotive/sv/OWNERS
new file mode 100644
index 0000000..af6788b
--- /dev/null
+++ b/automotive/sv/OWNERS
@@ -0,0 +1 @@
+tanmayp@google.com
diff --git a/automotive/vehicle/2.0/default/VehicleService.cpp b/automotive/vehicle/2.0/default/VehicleService.cpp
index 7e8deb6..5a48284 100644
--- a/automotive/vehicle/2.0/default/VehicleService.cpp
+++ b/automotive/vehicle/2.0/default/VehicleService.cpp
@@ -35,7 +35,7 @@
     auto userHal = connector->getEmulatedUserHal();
     auto hal = std::make_unique<impl::EmulatedVehicleHal>(store.get(), connector.get(), userHal);
     auto emulator = std::make_unique<impl::VehicleEmulator>(hal.get());
-    auto service = std::make_unique<VehicleHalManager>(hal.get());
+    auto service = android::sp<VehicleHalManager>::make(hal.get());
     connector->setValuePool(hal->getValuePool());
 
     configureRpcThreadpool(4, true /* callerWillJoin */);
diff --git a/bluetooth/1.0/default/test/fuzzer/Android.bp b/bluetooth/1.0/default/test/fuzzer/Android.bp
index 81f328e..691136f 100644
--- a/bluetooth/1.0/default/test/fuzzer/Android.bp
+++ b/bluetooth/1.0/default/test/fuzzer/Android.bp
@@ -46,7 +46,6 @@
         "android.hardware.bluetooth-async",
         "android.hardware.bluetooth-hci",
         "libcutils",
-        "libutils",
     ],
     shared_libs: [
         "android.hardware.bluetooth@1.0",
@@ -54,6 +53,7 @@
         "libhidlbase",
         "libbt-vendor-fuzz",
         "liblog",
+        "libutils",
     ],
     fuzz_config: {
         cc: [
diff --git a/bluetooth/1.0/default/test/fuzzer/bluetoothV1.0_fuzzer.cpp b/bluetooth/1.0/default/test/fuzzer/bluetoothV1.0_fuzzer.cpp
index 90cdc66..fb8df99 100644
--- a/bluetooth/1.0/default/test/fuzzer/bluetoothV1.0_fuzzer.cpp
+++ b/bluetooth/1.0/default/test/fuzzer/bluetoothV1.0_fuzzer.cpp
@@ -88,11 +88,18 @@
     }
     mBtHci->close();
     mBtHci.clear();
+    for (size_t i = 0; i < mFdCount; ++i) {
+      if (mFdList[i]) {
+        close(mFdList[i]);
+      }
+    }
   }
   bool init(const uint8_t* data, size_t size);
   void process();
 
  private:
+  size_t mFdCount = 1;
+  int32_t mFdList[CH_MAX] = {0};
   sp<BluetoothHci> mBtHci = nullptr;
   FuzzedDataProvider* mFdp = nullptr;
 };
@@ -143,17 +150,15 @@
   bool shouldSetH4Protocol = mFdp->ConsumeBool();
   BtVendor* btVendor = BtVendor::getInstance();
 
-  size_t fdcount = 1;
-  int32_t fdList[CH_MAX] = {0};
   if (!shouldSetH4Protocol) {
-    fdcount = mFdp->ConsumeIntegralInRange<size_t>(kMinFdcount, CH_MAX - 1);
+    mFdCount = mFdp->ConsumeIntegralInRange<size_t>(kMinFdcount, CH_MAX - 1);
   }
 
-  for (size_t i = 0; i < fdcount; ++i) {
-    fdList[i] = open("/dev/null", O_RDWR | O_CREAT);
+  for (size_t i = 0; i < mFdCount; ++i) {
+    mFdList[i] = open("/dev/null", O_RDWR | O_CREAT);
   }
 
-  btVendor->populateFdList(fdList, fdcount);
+  btVendor->populateFdList(mFdList, mFdCount);
   mBtHci->initialize(bluetoothCallback);
 
   if (!bluetoothCallback->isInitialized) {
@@ -181,12 +186,6 @@
   }
 
   btVendor->callRemainingCbacks();
-
-  for (size_t i = 0; i < fdcount; ++i) {
-    if (fdList[i]) {
-      close(fdList[i]);
-    }
-  }
 }
 
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
diff --git a/bluetooth/1.1/vts/functional/VtsHalBluetoothV1_1TargetTest.xml b/bluetooth/1.1/vts/functional/VtsHalBluetoothV1_1TargetTest.xml
index d64751a..98b62ef 100644
--- a/bluetooth/1.1/vts/functional/VtsHalBluetoothV1_1TargetTest.xml
+++ b/bluetooth/1.1/vts/functional/VtsHalBluetoothV1_1TargetTest.xml
@@ -20,8 +20,11 @@
     <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
     </target_preparer>
 
-    <target_preparer class="com.android.tradefed.targetprep.DeviceSetup">
-        <option name="bluetooth" value="off" />
+    <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+        <option name="run-command" value="settings put global ble_scan_always_enabled 0" />
+        <option name="run-command" value="su u$(am get-current-user)_system svc bluetooth disable" />
+        <option name="teardown-command" value="su u$(am get-current-user)_system svc bluetooth enable" />
+        <option name="teardown-command" value="settings put global ble_scan_always_enabled 1" />
     </target_preparer>
 
     <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
diff --git a/bluetooth/audio/aidl/Android.bp b/bluetooth/audio/aidl/Android.bp
index 52671b8..aca301c 100644
--- a/bluetooth/audio/aidl/Android.bp
+++ b/bluetooth/audio/aidl/Android.bp
@@ -40,9 +40,6 @@
             enabled: false,
         },
         ndk: {
-            vndk: {
-                enabled: true,
-            },
             apex_available: [
                 "//apex_available:platform",
                 "com.android.bluetooth",
diff --git a/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp b/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp
index 0dd8148..2a88959 100644
--- a/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp
+++ b/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp
@@ -45,6 +45,7 @@
   latency_modes_ = latencyModes;
   audio_config_ = std::make_unique<AudioConfiguration>(audio_config);
   stack_iface_ = host_if;
+  is_binder_died = false;
 
   AIBinder_linkToDeath(stack_iface_->asBinder().get(), death_recipient_.get(),
                        this);
@@ -59,8 +60,10 @@
   if (stack_iface_ != nullptr) {
     BluetoothAudioSessionReport::OnSessionEnded(session_type_);
 
-    AIBinder_unlinkToDeath(stack_iface_->asBinder().get(),
-                           death_recipient_.get(), this);
+    if (!is_binder_died) {
+      AIBinder_unlinkToDeath(stack_iface_->asBinder().get(),
+                             death_recipient_.get(), this);
+    }
   } else {
     LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
               << " has NO session";
@@ -147,6 +150,7 @@
     LOG(ERROR) << __func__ << ": Null AudioProvider HAL died";
     return;
   }
+  provider->is_binder_died = true;
   provider->endSession();
 }
 
diff --git a/bluetooth/audio/aidl/default/BluetoothAudioProvider.h b/bluetooth/audio/aidl/default/BluetoothAudioProvider.h
index a9f830a..dbfff7d 100644
--- a/bluetooth/audio/aidl/default/BluetoothAudioProvider.h
+++ b/bluetooth/audio/aidl/default/BluetoothAudioProvider.h
@@ -62,6 +62,7 @@
   std::unique_ptr<AudioConfiguration> audio_config_ = nullptr;
   SessionType session_type_;
   std::vector<LatencyMode> latency_modes_;
+  bool is_binder_died = false;
 };
 
 }  // namespace audio
diff --git a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp
index 0e22e44..7f610ef 100644
--- a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp
+++ b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp
@@ -55,21 +55,20 @@
     const std::shared_ptr<IBluetoothAudioPort>& host_if,
     const AudioConfiguration& audio_config,
     const std::vector<LatencyMode>& latency_modes, DataMQDesc* _aidl_return) {
-  if (audio_config.getTag() != AudioConfiguration::leAudioConfig) {
+  if (session_type_ ==
+      SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
+    if (audio_config.getTag() != AudioConfiguration::leAudioBroadcastConfig) {
+      LOG(WARNING) << __func__ << " - Invalid Audio Configuration="
+                   << audio_config.toString();
+      *_aidl_return = DataMQDesc();
+      return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+  } else if (audio_config.getTag() != AudioConfiguration::leAudioConfig) {
     LOG(WARNING) << __func__ << " - Invalid Audio Configuration="
                  << audio_config.toString();
     *_aidl_return = DataMQDesc();
     return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
   }
-  const auto& le_audio_config =
-      audio_config.get<AudioConfiguration::leAudioConfig>();
-  if (!BluetoothAudioCodecs::IsOffloadLeAudioConfigurationValid(
-          session_type_, le_audio_config)) {
-    LOG(WARNING) << __func__ << " - Unsupported LC3 Offloaded Configuration="
-                 << le_audio_config.toString();
-    *_aidl_return = DataMQDesc();
-    return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
-  }
 
   return BluetoothAudioProvider::startSession(
       host_if, audio_config, latency_modes, _aidl_return);
diff --git a/bluetooth/audio/aidl/default/LeAudioSoftwareAudioProvider.cpp b/bluetooth/audio/aidl/default/LeAudioSoftwareAudioProvider.cpp
index 911c928..c16ff54 100644
--- a/bluetooth/audio/aidl/default/LeAudioSoftwareAudioProvider.cpp
+++ b/bluetooth/audio/aidl/default/LeAudioSoftwareAudioProvider.cpp
@@ -91,17 +91,21 @@
   else if (session_type_ == SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH)
     buffer_modifier = kBufferInCount;
 
+  // 24 bit audio stream is sent as unpacked
+  int bytes_per_sample =
+      (pcm_config.bitsPerSample == 24) ? 4 : (pcm_config.bitsPerSample / 8);
+
   uint32_t data_mq_size =
       (ceil(pcm_config.sampleRateHz) / 1000) *
-      channel_mode_to_channel_count(pcm_config.channelMode) *
-      (pcm_config.bitsPerSample / 8) * (pcm_config.dataIntervalUs / 1000) *
-      buffer_modifier;
+      channel_mode_to_channel_count(pcm_config.channelMode) * bytes_per_sample *
+      (pcm_config.dataIntervalUs / 1000) * buffer_modifier;
   if (data_mq_size <= 0) {
     LOG(ERROR) << __func__ << "Unexpected audio buffer size: " << data_mq_size
                << ", SampleRateHz: " << pcm_config.sampleRateHz
                << ", ChannelMode: " << toString(pcm_config.channelMode)
                << ", BitsPerSample: "
                << static_cast<int>(pcm_config.bitsPerSample)
+               << ", BytesPerSample: " << bytes_per_sample
                << ", DataIntervalUs: " << pcm_config.dataIntervalUs
                << ", SessionType: " << toString(session_type_);
     return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp
index 8e9aa55..8c42e91 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp
@@ -37,7 +37,7 @@
 namespace audio {
 
 static const PcmCapabilities kDefaultSoftwarePcmCapabilities = {
-    .sampleRateHz = {16000, 24000, 44100, 48000, 88200, 96000},
+    .sampleRateHz = {16000, 24000, 32000, 44100, 48000, 88200, 96000},
     .channelMode = {ChannelMode::MONO, ChannelMode::STEREO},
     .bitsPerSample = {16, 24, 32},
     .dataIntervalUs = {},
@@ -115,6 +115,20 @@
     .octetsPerFrame = {40}};
 
 // Default Supported Codecs
+// LC3 24_2: sample rate: 24 kHz, frame duration: 10 ms, octets per frame: 60
+static const Lc3Capabilities kLc3Capability_24_2 = {
+    .samplingFrequencyHz = {24000},
+    .frameDurationUs = {10000},
+    .octetsPerFrame = {60}};
+
+// Default Supported Codecs
+// LC3 32_2: sample rate: 32 kHz, frame duration: 10 ms, octets per frame: 80
+static const Lc3Capabilities kLc3Capability_32_2 = {
+    .samplingFrequencyHz = {32000},
+    .frameDurationUs = {10000},
+    .octetsPerFrame = {80}};
+
+// Default Supported Codecs
 // LC3 48_4: sample rate: 48 kHz, frame duration: 10 ms, octets per frame: 120
 static const Lc3Capabilities kLc3Capability_48_4 = {
     .samplingFrequencyHz = {48000},
@@ -122,7 +136,8 @@
     .octetsPerFrame = {120}};
 
 static const std::vector<Lc3Capabilities> supportedLc3CapabilityList = {
-    kLc3Capability_48_4, kLc3Capability_16_2, kLc3Capability_16_1};
+    kLc3Capability_48_4, kLc3Capability_32_2, kLc3Capability_24_2,
+    kLc3Capability_16_2, kLc3Capability_16_1};
 
 static AudioLocation stereoAudio = static_cast<AudioLocation>(
     static_cast<uint8_t>(AudioLocation::FRONT_LEFT) |
@@ -302,19 +317,6 @@
   return false;
 }
 
-bool BluetoothAudioCodecs::IsOffloadLeAudioConfigurationValid(
-    const SessionType& session_type, const LeAudioConfiguration&) {
-  if (session_type !=
-          SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
-      session_type !=
-          SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH &&
-      session_type !=
-          SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
-    return false;
-  }
-  return true;
-}
-
 std::vector<PcmCapabilities>
 BluetoothAudioCodecs::GetSoftwarePcmCapabilities() {
   return {kDefaultSoftwarePcmCapabilities};
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h
index 0259a7e..c5e08d3 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h
@@ -44,9 +44,6 @@
   static bool IsOffloadCodecConfigurationValid(
       const SessionType& session_type, const CodecConfiguration& codec_config);
 
-  static bool IsOffloadLeAudioConfigurationValid(
-      const SessionType& session_type, const LeAudioConfiguration&);
-
   static std::vector<LeAudioCodecCapabilitiesSetting>
   GetLeAudioOffloadCodecCapabilities(const SessionType& session_type);
 
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
index 3214bf2..292d352 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
@@ -111,7 +111,9 @@
   if (session_type_ !=
           SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
       session_type_ !=
-          SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
+          SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH &&
+      session_type_ !=
+          SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
     return;
   }
   std::lock_guard<std::recursive_mutex> guard(mutex_);
@@ -274,11 +276,14 @@
   bool is_offload_a2dp_session =
       (session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
        session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH);
-  bool is_offload_le_audio_session =
+  bool is_offload_le_audio_unicast_session =
       (session_type_ ==
            SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
        session_type_ ==
            SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
+  bool is_offload_le_audio_broadcast_session =
+      (session_type_ ==
+       SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
   auto audio_config_tag = audio_config.getTag();
   bool is_software_audio_config =
       (is_software_session &&
@@ -286,11 +291,15 @@
   bool is_a2dp_offload_audio_config =
       (is_offload_a2dp_session &&
        audio_config_tag == AudioConfiguration::a2dpConfig);
-  bool is_le_audio_offload_audio_config =
-      (is_offload_le_audio_session &&
+  bool is_le_audio_offload_unicast_audio_config =
+      (is_offload_le_audio_unicast_session &&
        audio_config_tag == AudioConfiguration::leAudioConfig);
+  bool is_le_audio_offload_broadcast_audio_config =
+      (is_offload_le_audio_broadcast_session &&
+       audio_config_tag == AudioConfiguration::leAudioBroadcastConfig);
   if (!is_software_audio_config && !is_a2dp_offload_audio_config &&
-      !is_le_audio_offload_audio_config) {
+      !is_le_audio_offload_unicast_audio_config &&
+      !is_le_audio_offload_broadcast_audio_config) {
     return false;
   }
   audio_config_ = std::make_unique<AudioConfiguration>(audio_config);
diff --git a/boot/1.1/default/boot_control/include/libboot_control/libboot_control.h b/boot/1.1/default/boot_control/include/libboot_control/libboot_control.h
index ac17d6d..572a8b6 100644
--- a/boot/1.1/default/boot_control/include/libboot_control/libboot_control.h
+++ b/boot/1.1/default/boot_control/include/libboot_control/libboot_control.h
@@ -25,9 +25,8 @@
 
 // Helper library to implement the IBootControl HAL using the misc partition.
 class BootControl {
-  using MergeStatus = ::android::hardware::boot::V1_1::MergeStatus;
-
  public:
+  using MergeStatus = ::android::hardware::boot::V1_1::MergeStatus;
   bool Init();
   unsigned int GetNumberSlots();
   unsigned int GetCurrentSlot();
diff --git a/boot/1.1/default/boot_control/include/private/boot_control_definition.h b/boot/1.1/default/boot_control/include/private/boot_control_definition.h
index 8f02111..57c2f73 100644
--- a/boot/1.1/default/boot_control/include/private/boot_control_definition.h
+++ b/boot/1.1/default/boot_control/include/private/boot_control_definition.h
@@ -14,6 +14,9 @@
  * limitations under the License.
  */
 
+#include <stdint.h>
+
+#include <bootloader_message/bootloader_message.h>
 
 /**
  * The A/B-specific bootloader message structure (4-KiB).
diff --git a/boot/1.1/vts/functional/VtsHalBootV1_1TargetTest.cpp b/boot/1.1/vts/functional/VtsHalBootV1_1TargetTest.cpp
index c38f257..05f136e 100644
--- a/boot/1.1/vts/functional/VtsHalBootV1_1TargetTest.cpp
+++ b/boot/1.1/vts/functional/VtsHalBootV1_1TargetTest.cpp
@@ -1,4 +1,5 @@
 /*
+
  * Copyright (C) 2019 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,6 +20,7 @@
 #include <vector>
 
 #include <android-base/logging.h>
+#include <android-base/properties.h>
 #include <android/hardware/boot/1.1/IBootControl.h>
 #include <android/hardware/boot/1.1/types.h>
 #include <gmock/gmock.h>
@@ -37,9 +39,21 @@
 using ::android::hardware::boot::V1_1::MergeStatus;
 using ::testing::Contains;
 
+bool IsVirtualAbEnabled();
+
+#define SKIP_IF_NON_VIRTUAL_AB()                                                        \
+    do {                                                                                \
+        if (!IsVirtualAbEnabled()) GTEST_SKIP() << "Test for Virtual A/B devices only"; \
+    } while (0)
+
+bool IsVirtualAbEnabled() {
+    return android::base::GetBoolProperty("ro.virtual_ab.enabled", false);
+}
+
 class BootHidlTest : public testing::TestWithParam<std::string> {
   public:
     virtual void SetUp() override {
+        SKIP_IF_NON_VIRTUAL_AB();
         boot = IBootControl::getService(GetParam());
         ASSERT_NE(boot, nullptr);
 
diff --git a/boot/aidl/Android.bp b/boot/aidl/Android.bp
new file mode 100644
index 0000000..be38245
--- /dev/null
+++ b/boot/aidl/Android.bp
@@ -0,0 +1,40 @@
+//
+// Copyright (C) 2022 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 {
+    // 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"],
+}
+
+aidl_interface {
+    name: "android.hardware.boot",
+    vendor_available: true,
+    srcs: ["android/hardware/boot/*.aidl"],
+    stability: "vintf",
+    recovery_available: true,
+    backend: {
+        java: {
+            sdk_version: "module_current",
+        },
+        cpp: {
+            enabled: false,
+        },
+    },
+}
diff --git a/boot/aidl/aidl_api/android.hardware.boot/current/android/hardware/boot/IBootControl.aidl b/boot/aidl/aidl_api/android.hardware.boot/current/android/hardware/boot/IBootControl.aidl
new file mode 100644
index 0000000..c8ab51e
--- /dev/null
+++ b/boot/aidl/aidl_api/android.hardware.boot/current/android/hardware/boot/IBootControl.aidl
@@ -0,0 +1,50 @@
+//
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.boot;
+@VintfStability
+interface IBootControl {
+  int getActiveBootSlot();
+  int getCurrentSlot();
+  int getNumberSlots();
+  android.hardware.boot.MergeStatus getSnapshotMergeStatus();
+  String getSuffix(in int slot);
+  boolean isSlotBootable(in int slot);
+  boolean isSlotMarkedSuccessful(in int slot);
+  void markBootSuccessful();
+  void setActiveBootSlot(in int slot);
+  void setSlotAsUnbootable(in int slot);
+  void setSnapshotMergeStatus(in android.hardware.boot.MergeStatus status);
+  const int INVALID_SLOT = -1;
+  const int COMMAND_FAILED = -2;
+}
diff --git a/boot/aidl/aidl_api/android.hardware.boot/current/android/hardware/boot/MergeStatus.aidl b/boot/aidl/aidl_api/android.hardware.boot/current/android/hardware/boot/MergeStatus.aidl
new file mode 100644
index 0000000..53c6204
--- /dev/null
+++ b/boot/aidl/aidl_api/android.hardware.boot/current/android/hardware/boot/MergeStatus.aidl
@@ -0,0 +1,42 @@
+//
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.boot;
+@Backing(type="int") @VintfStability
+enum MergeStatus {
+  NONE = 0,
+  UNKNOWN = 1,
+  SNAPSHOTTED = 2,
+  MERGING = 3,
+  CANCELLED = 4,
+}
diff --git a/boot/aidl/android/hardware/boot/IBootControl.aidl b/boot/aidl/android/hardware/boot/IBootControl.aidl
new file mode 100644
index 0000000..6c9e8ce
--- /dev/null
+++ b/boot/aidl/android/hardware/boot/IBootControl.aidl
@@ -0,0 +1,158 @@
+//
+// Copyright (C) 2022 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.boot;
+
+import android.hardware.boot.MergeStatus;
+
+@VintfStability
+interface IBootControl {
+    const int INVALID_SLOT = -1;
+    const int COMMAND_FAILED = -2;
+    /**
+     * Returns the active slot to boot into on the next boot. If
+     * setActiveBootSlot() has been called, the getter function should return the
+     * same slot as the one provided in the last setActiveBootSlot() call.
+     * The returned value is always guaranteed to be strictly less than the
+     * value returned by getNumberSlots. Slots start at 0 and finish at
+     * getNumberSlots() - 1. For instance, a system with A/B must return 0 or 1.
+     * @return the active slot to boot into on the next boot.
+     */
+    int getActiveBootSlot();
+
+    /**
+     * getCurrentSlot() returns the slot number of that the current boot is booted
+     * from, for example slot number 0 (Slot A). It is assumed that if the current
+     * slot is A, then the block devices underlying B can be accessed directly
+     * without any risk of corruption.
+     * The returned value is always guaranteed to be strictly less than the
+     * value returned by getNumberSlots. Slots start at 0 and finish at
+     * getNumberSlots() - 1. The value returned here must match the suffix passed
+     * from the bootloader, regardless of which slot is active or successful.
+     * @return the slot number of that the current boot is booted
+     */
+    int getCurrentSlot();
+
+    /**
+     * getNumberSlots() returns the number of available slots.
+     * For instance, a system with a single set of partitions must return
+     * 1, a system with A/B must return 2, A/B/C -> 3 and so on. A system with
+     * less than two slots doesn't support background updates, for example if
+     * running from a virtual machine with only one copy of each partition for the
+     * purpose of testing.
+     * @return number of available slots
+     */
+    int getNumberSlots();
+
+    /**
+     * Returns whether a snapshot-merge of any dynamic partition is in progress.
+     *
+     * This function must return the merge status set by the last setSnapshotMergeStatus call and
+     * recorded by the bootloader with one exception. If the partitions are being flashed from the
+     * bootloader such that the pending merge must be canceled (for example, if the super partition
+     * is being flashed), this function must return CANCELLED.
+     *
+     * @param out success True if the merge status is read successfully, false otherwise.
+     * @return Merge status.
+     */
+    MergeStatus getSnapshotMergeStatus();
+
+    /**
+     * getSuffix() returns the string suffix used by partitions that correspond to
+     * the slot number passed in as a parameter. The bootloader must pass the
+     * suffix of the currently active slot either through a kernel command line
+     * property at androidboot.slot_suffix, or the device tree at
+     * /firmware/android/slot_suffix.
+     * @return suffix for the input slot, or the empty string "" if slot
+     * does not match an existing slot.
+     */
+    String getSuffix(in int slot);
+
+    /**
+     * isSlotBootable() returns if the slot passed in parameter is bootable. Note
+     * that slots can be made unbootable by both the bootloader and by the OS
+     * using setSlotAsUnbootable.
+     * @return true if the slot is bootable, false if it's not.
+     * @throws service specific error INVALID_SLOT if slot is invalid.
+     */
+    boolean isSlotBootable(in int slot);
+
+    /**
+     * isSlotMarkedSuccessful() returns if the slot passed in parameter has been
+     * marked as successful using markBootSuccessful. Note that only the current
+     * slot can be marked as successful but any slot can be queried.
+     * @return true if the slot has been marked as successful, false if it has
+     * not.
+     * @throws service specific error INVALID_SLOT if slot is invalid.
+     */
+    boolean isSlotMarkedSuccessful(in int slot);
+
+    /**
+     * markBootSuccessful() marks the current slot as having booted successfully.
+     *
+     * @throws Service specific error COMMAND_FAILED if command failed.
+     */
+    void markBootSuccessful();
+
+    /**
+     * setActiveBootSlot() marks the slot passed in parameter as the active boot
+     * slot (see getCurrentSlot for an explanation of the "slot" parameter). This
+     * overrides any previous call to setSlotAsUnbootable.
+     * @throws Service specific error INVALID_SLOT if slot is invalid, or COMMAND_FAILED if
+     * operation failed.
+     */
+    void setActiveBootSlot(in int slot);
+
+    /**
+     * setSlotAsUnbootable() marks the slot passed in parameter as
+     * an unbootable. This can be used while updating the contents of the slot's
+     * partitions, so that the system must not attempt to boot a known bad set up.
+     * @throws Service specific error INVALID_SLOT if slot is invalid, or COMMAND_FAILED if
+     * operation failed.
+     */
+    void setSlotAsUnbootable(in int slot);
+
+    /**
+     * Sets whether a snapshot-merge of any dynamic partition is in progress.
+     *
+     * After the merge status is set to a given value, subsequent calls to
+     * getSnapshotMergeStatus must return the set value.
+     *
+     * The merge status must be persistent across reboots. That is, getSnapshotMergeStatus
+     * must return the same value after a reboot if the merge status is not altered in any way
+     * (e.g. set by setSnapshotMergeStatus or set to CANCELLED by bootloader).
+     *
+     * Read/write access to the merge status must be atomic. When the HAL is processing a
+     * setSnapshotMergeStatus call, all subsequent calls to getSnapshotMergeStatus must block until
+     * setSnapshotMergeStatus has returned.
+     *
+     * A MERGING state indicates that dynamic partitions are partially comprised by blocks in the
+     * userdata partition.
+     *
+     * When the merge status is set to MERGING, the following operations must be prohibited from the
+     * bootloader:
+     *  - Flashing or erasing "userdata" or "metadata".
+     *
+     * The following operations may be prohibited when the status is set to MERGING. If not
+     * prohibited, it is recommended that the user receive a warning.
+     *  - Changing the active slot (e.g. via "fastboot set_active")
+     *
+     * @param status Merge status.
+     *
+     * @throws service specific error COMMAND_FAILED if operation failed.
+     */
+    void setSnapshotMergeStatus(in MergeStatus status);
+}
diff --git a/boot/aidl/android/hardware/boot/MergeStatus.aidl b/boot/aidl/android/hardware/boot/MergeStatus.aidl
new file mode 100644
index 0000000..16ac85f
--- /dev/null
+++ b/boot/aidl/android/hardware/boot/MergeStatus.aidl
@@ -0,0 +1,42 @@
+//
+// Copyright (C) 2022 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.boot;
+
+@VintfStability
+@Backing(type="int")
+enum MergeStatus {
+    /**
+     * No snapshot or merge is in progress.
+     */
+    NONE = 0,
+    /**
+     * The merge status could not be determined.
+     */
+    UNKNOWN,
+    /**
+     * Partitions are being snapshotted, but no merge has been started.
+     */
+    SNAPSHOTTED,
+    /**
+     * At least one partition has merge is in progress.
+     */
+    MERGING,
+    /**
+     * A merge was in progress, but it was canceled by the bootloader.
+     */
+    CANCELLED,
+}
diff --git a/boot/aidl/client/Android.bp b/boot/aidl/client/Android.bp
new file mode 100644
index 0000000..db4a7ea
--- /dev/null
+++ b/boot/aidl/client/Android.bp
@@ -0,0 +1,31 @@
+
+
+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"],
+}
+
+cc_library {
+    name: "libboot_control_client",
+    srcs: [
+        "BootControlClient.cpp"
+    ],
+    export_include_dirs: ["include"],
+    export_shared_lib_headers: ["android.hardware.boot-V1-ndk"],
+    recovery_available: true,
+    shared_libs: [
+        "android.hardware.boot-V1-ndk",
+        "android.hardware.boot@1.0",
+        "android.hardware.boot@1.1",
+        "android.hardware.boot@1.2",
+        "libhidlbase",
+        "libbinder_ndk",
+        "libbase",
+        "libcutils",
+        "libutils",
+    ],
+}
diff --git a/boot/aidl/client/BootControlClient.cpp b/boot/aidl/client/BootControlClient.cpp
new file mode 100644
index 0000000..89258d2
--- /dev/null
+++ b/boot/aidl/client/BootControlClient.cpp
@@ -0,0 +1,364 @@
+/*
+ * Copyright (C) 2022 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 <BootControlClient.h>
+
+#include <aidl/android/hardware/boot/IBootControl.h>
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/hardware/boot/1.0/IBootControl.h>
+#include <android/hardware/boot/1.1/IBootControl.h>
+#include <android/hardware/boot/1.2/IBootControl.h>
+#include "utils/StrongPointer.h"
+
+#define CONCAT(x, y) x##y
+
+#define LOG_NDK_STATUS(x)                                                                   \
+    do {                                                                                    \
+        const auto CONCAT(status, __COUNTER__) = x;                                         \
+        if (!CONCAT(status, __COUNTER__).isOk()) {                                          \
+            LOG(ERROR) << #x << " failed " << CONCAT(status, __COUNTER__).getDescription(); \
+        }                                                                                   \
+    } while (0)
+
+using aidl::android::hardware::boot::MergeStatus;
+
+std::ostream& operator<<(std::ostream& os, MergeStatus status) {
+    switch (status) {
+        case MergeStatus::NONE:
+            os << "MergeStatus::NONE";
+            break;
+        case MergeStatus::UNKNOWN:
+            os << "MergeStatus::UNKNOWN";
+            break;
+        case MergeStatus::SNAPSHOTTED:
+            os << "MergeStatus::SNAPSHOTTED";
+            break;
+        case MergeStatus::MERGING:
+            os << "MergeStatus::MERGING";
+            break;
+        case MergeStatus::CANCELLED:
+            os << "MergeStatus::CANCELLED";
+            break;
+        default:
+            os << static_cast<int>(status);
+            break;
+    }
+    return os;
+}
+
+namespace android::hal {
+class BootControlClientAidl final : public BootControlClient {
+    using IBootControl = ::aidl::android::hardware::boot::IBootControl;
+
+  public:
+    BootControlClientAidl(std::shared_ptr<IBootControl> module) : module_(module) {}
+
+    BootControlVersion GetVersion() const override { return BootControlVersion::BOOTCTL_AIDL; }
+
+    ~BootControlClientAidl() = default;
+    virtual int32_t GetNumSlots() const {
+        int32_t ret = -1;
+        LOG_NDK_STATUS(module_->getNumberSlots(&ret));
+        return ret;
+    }
+
+    int32_t GetCurrentSlot() const {
+        int32_t ret = -1;
+        LOG_NDK_STATUS(module_->getCurrentSlot(&ret));
+        return ret;
+    }
+    MergeStatus getSnapshotMergeStatus() const {
+        MergeStatus status = MergeStatus::UNKNOWN;
+        LOG_NDK_STATUS(module_->getSnapshotMergeStatus(&status));
+        return status;
+    }
+    std::string GetSuffix(int32_t slot) const {
+        std::string ret;
+        const auto status = module_->getSuffix(slot, &ret);
+        if (!status.isOk()) {
+            LOG(ERROR) << __FUNCTION__ << "(" << slot << ")"
+                       << " failed " << status.getDescription();
+            return {};
+        }
+        return ret;
+    }
+
+    std::optional<bool> IsSlotBootable(int32_t slot) const {
+        bool ret = false;
+        const auto status = module_->isSlotBootable(slot, &ret);
+        if (!status.isOk()) {
+            LOG(ERROR) << __FUNCTION__ << "(" << slot << ")"
+                       << " failed " << status.getDescription();
+            return {};
+        }
+        return ret;
+    }
+
+    CommandResult MarkSlotUnbootable(int32_t slot) {
+        const auto status = module_->setSlotAsUnbootable(slot);
+        if (!status.isOk()) {
+            LOG(ERROR) << __FUNCTION__ << "(" << slot << ")"
+                       << " failed " << status.getDescription();
+        }
+        return {.success = status.isOk(), .errMsg = status.getDescription()};
+    }
+
+    CommandResult SetActiveBootSlot(int slot) {
+        const auto status = module_->setActiveBootSlot(slot);
+        if (!status.isOk()) {
+            LOG(ERROR) << __FUNCTION__ << "(" << slot << ")"
+                       << " failed " << status.getDescription();
+        }
+        return {.success = status.isOk(), .errMsg = status.getDescription()};
+    }
+    int GetActiveBootSlot() const {
+        int ret = -1;
+        LOG_NDK_STATUS(module_->getActiveBootSlot(&ret));
+        return ret;
+    }
+
+    // Check if |slot| is marked boot successfully.
+    std::optional<bool> IsSlotMarkedSuccessful(int slot) const {
+        bool ret = false;
+        const auto status = module_->isSlotMarkedSuccessful(slot, &ret);
+        if (!status.isOk()) {
+            LOG(ERROR) << __FUNCTION__ << "(" << slot << ")"
+                       << " failed " << status.getDescription();
+            return {};
+        }
+        return ret;
+    }
+
+    CommandResult MarkBootSuccessful() {
+        const auto status = module_->markBootSuccessful();
+        if (!status.isOk()) {
+            LOG(ERROR) << __FUNCTION__ << " failed " << status.getDescription();
+        }
+        return {.success = status.isOk(), .errMsg = status.getDescription()};
+    }
+
+    CommandResult SetSnapshotMergeStatus(aidl::android::hardware::boot::MergeStatus merge_status) {
+        const auto status = module_->setSnapshotMergeStatus(merge_status);
+        if (!status.isOk()) {
+            LOG(ERROR) << __FUNCTION__ << "(" << merge_status << ")"
+                       << " failed " << status.getDescription();
+        }
+        return {.success = status.isOk(), .errMsg = status.getDescription()};
+    }
+
+  private:
+    const std::shared_ptr<IBootControl> module_;
+};
+
+using namespace android::hardware::boot;
+
+class BootControlClientHIDL final : public BootControlClient {
+  public:
+    BootControlClientHIDL(android::sp<V1_0::IBootControl> module_v1,
+                          android::sp<V1_1::IBootControl> module_v1_1,
+                          android::sp<V1_2::IBootControl> module_v1_2)
+        : module_v1_(module_v1), module_v1_1_(module_v1_1), module_v1_2_(module_v1_2) {
+        CHECK(module_v1_ != nullptr);
+    }
+    BootControlVersion GetVersion() const override {
+        if (module_v1_2_ != nullptr) {
+            return BootControlVersion::BOOTCTL_V1_2;
+        } else if (module_v1_1_ != nullptr) {
+            return BootControlVersion::BOOTCTL_V1_1;
+        } else {
+            return BootControlVersion::BOOTCTL_V1_0;
+        }
+    }
+    int32_t GetNumSlots() const {
+        const auto ret = module_v1_->getNumberSlots();
+        if (!ret.isOk()) {
+            LOG(ERROR) << __FUNCTION__ << " failed " << ret.description();
+        }
+        return ret.withDefault(-1);
+    }
+
+    int32_t GetCurrentSlot() const {
+        const auto ret = module_v1_->getCurrentSlot();
+        if (!ret.isOk()) {
+            LOG(ERROR) << __FUNCTION__ << " failed " << ret.description();
+        }
+        return ret.withDefault(-1);
+    }
+
+    std::string GetSuffix(int32_t slot) const {
+        std::string suffix;
+        const auto ret = module_v1_->getSuffix(
+                slot,
+                [&](const ::android::hardware::hidl_string& slotSuffix) { suffix = slotSuffix; });
+        if (!ret.isOk()) {
+            LOG(ERROR) << __FUNCTION__ << "(" << slot << ")"
+                       << " failed " << ret.description();
+        }
+        return suffix;
+    }
+
+    std::optional<bool> IsSlotBootable(int32_t slot) const {
+        const auto ret = module_v1_->isSlotBootable(slot);
+        if (!ret.isOk()) {
+            LOG(ERROR) << __FUNCTION__ << "(" << slot << ")"
+                       << " failed " << ret.description();
+            return {};
+        }
+        const auto bool_result = ret.withDefault(V1_0::BoolResult::INVALID_SLOT);
+        if (bool_result == V1_0::BoolResult::INVALID_SLOT) {
+            return {};
+        }
+        return bool_result == V1_0::BoolResult::TRUE;
+    }
+
+    CommandResult MarkSlotUnbootable(int32_t slot) {
+        CommandResult result;
+        const auto ret =
+                module_v1_->setSlotAsUnbootable(slot, [&](const V1_0::CommandResult& error) {
+                    result.success = error.success;
+                    result.errMsg = error.errMsg;
+                });
+        if (!ret.isOk()) {
+            LOG(ERROR) << __FUNCTION__ << "(" << slot << ")"
+                       << " failed " << ret.description();
+        }
+        return result;
+    }
+
+    CommandResult SetActiveBootSlot(int32_t slot) {
+        CommandResult result;
+        const auto ret = module_v1_->setActiveBootSlot(slot, [&](const V1_0::CommandResult& error) {
+            result.success = error.success;
+            result.errMsg = error.errMsg;
+        });
+        if (!ret.isOk()) {
+            LOG(ERROR) << __FUNCTION__ << "(" << slot << ")"
+                       << " failed " << ret.description();
+        }
+        return result;
+    }
+
+    CommandResult MarkBootSuccessful() {
+        CommandResult result;
+        const auto ret = module_v1_->markBootSuccessful([&](const V1_0::CommandResult& error) {
+            result.success = error.success;
+            result.errMsg = error.errMsg;
+        });
+        if (!ret.isOk()) {
+            LOG(ERROR) << __FUNCTION__ << " failed " << ret.description();
+        }
+        return result;
+    }
+
+    std::optional<bool> IsSlotMarkedSuccessful(int32_t slot) const {
+        const auto ret = module_v1_->isSlotMarkedSuccessful(slot);
+        if (!ret.isOk()) {
+            LOG(ERROR) << __FUNCTION__ << "(" << slot << ")"
+                       << " failed " << ret.description();
+            return {};
+        }
+        const auto bool_result = ret.withDefault(V1_0::BoolResult::INVALID_SLOT);
+        if (bool_result == V1_0::BoolResult::INVALID_SLOT) {
+            return {};
+        }
+        return bool_result == V1_0::BoolResult::TRUE;
+    }
+
+    MergeStatus getSnapshotMergeStatus() const {
+        if (module_v1_1_ == nullptr) {
+            LOG(ERROR) << __FUNCTION__ << " is unsupported, requires at least boot v1.1";
+            return MergeStatus::UNKNOWN;
+        }
+        const auto ret = module_v1_1_->getSnapshotMergeStatus();
+        if (!ret.isOk()) {
+            LOG(ERROR) << __FUNCTION__ << " failed " << ret.description();
+        }
+        return static_cast<MergeStatus>(
+                ret.withDefault(static_cast<V1_1::MergeStatus>(MergeStatus::UNKNOWN)));
+    }
+
+    CommandResult SetSnapshotMergeStatus(MergeStatus merge_status) {
+        if (module_v1_1_ == nullptr) {
+            return {.success = false,
+                    .errMsg = "setSnapshotMergeStatus is unsupported, requires at least boot v1.1"};
+        }
+        const auto ret =
+                module_v1_1_->setSnapshotMergeStatus(static_cast<V1_1::MergeStatus>(merge_status));
+        if (!ret.isOk()) {
+            LOG(ERROR) << __FUNCTION__ << "(" << merge_status << ")"
+                       << " failed " << ret.description();
+        }
+        return {.success = ret.isOk(), .errMsg = ret.description()};
+    }
+
+    int32_t GetActiveBootSlot() const {
+        if (module_v1_2_ == nullptr) {
+            LOG(ERROR) << __FUNCTION__ << " is unsupported, requires at least boot v1.2";
+            return -1;
+        }
+        const auto ret = module_v1_2_->getActiveBootSlot();
+        if (!ret.isOk()) {
+            LOG(ERROR) << __FUNCTION__ << " failed " << ret.description();
+        }
+        return ret.withDefault(-1);
+    }
+
+  private:
+    android::sp<V1_0::IBootControl> module_v1_;
+    android::sp<V1_1::IBootControl> module_v1_1_;
+    android::sp<V1_2::IBootControl> module_v1_2_;
+};
+
+std::unique_ptr<BootControlClient> BootControlClient::WaitForService() {
+    const auto instance_name =
+            std::string(::aidl::android::hardware::boot::IBootControl::descriptor) + "/default";
+
+    if (AServiceManager_isDeclared(instance_name.c_str())) {
+        auto module = ::aidl::android::hardware::boot::IBootControl::fromBinder(
+                ndk::SpAIBinder(AServiceManager_waitForService(instance_name.c_str())));
+        if (module == nullptr) {
+            LOG(ERROR) << "AIDL " << instance_name
+                       << " is declared but waitForService returned nullptr.";
+            return nullptr;
+        }
+        LOG(INFO) << "Using AIDL version of IBootControl";
+        return std::make_unique<BootControlClientAidl>(module);
+    }
+    LOG(INFO) << "AIDL IBootControl not available, falling back to HIDL.";
+
+    android::sp<V1_0::IBootControl> v1_0_module;
+    android::sp<V1_1::IBootControl> v1_1_module;
+    android::sp<V1_2::IBootControl> v1_2_module;
+    v1_0_module = V1_0::IBootControl::getService();
+    if (v1_0_module == nullptr) {
+        LOG(ERROR) << "Error getting bootctrl v1.0 module.";
+        return nullptr;
+    }
+    v1_1_module = V1_1::IBootControl::castFrom(v1_0_module);
+    v1_2_module = V1_2::IBootControl::castFrom(v1_0_module);
+    if (v1_2_module != nullptr) {
+        LOG(INFO) << "Using HIDL version 1.2 of IBootControl";
+    } else if (v1_1_module != nullptr) {
+        LOG(INFO) << "Using HIDL version 1.1 of IBootControl";
+    } else {
+        LOG(INFO) << "Using HIDL version 1.0 of IBootControl";
+    }
+
+    return std::make_unique<BootControlClientHIDL>(v1_0_module, v1_1_module, v1_2_module);
+}
+
+}  // namespace android::hal
diff --git a/boot/aidl/client/include/BootControlClient.h b/boot/aidl/client/include/BootControlClient.h
new file mode 100644
index 0000000..472e82e
--- /dev/null
+++ b/boot/aidl/client/include/BootControlClient.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __BOOT_CONTROL_CLIENT_H_
+#define __BOOT_CONTROL_CLIENT_H_
+
+#include <aidl/android/hardware/boot/MergeStatus.h>
+
+#include <stdint.h>
+
+#include <memory>
+#include <optional>
+
+namespace android::hal {
+
+struct CommandResult {
+    bool success;
+    std::string errMsg;
+    constexpr bool IsOk() const { return success; }
+};
+
+enum class BootControlVersion { BOOTCTL_V1_0, BOOTCTL_V1_1, BOOTCTL_V1_2, BOOTCTL_AIDL };
+
+class BootControlClient {
+  public:
+    using MergeStatus = aidl::android::hardware::boot::MergeStatus;
+    virtual ~BootControlClient() = default;
+    virtual BootControlVersion GetVersion() const = 0;
+    // Return the number of update slots in the system. A system will normally
+    // have two slots, named "A" and "B" in the documentation, but sometimes
+    // images running from other media can have only one slot, like some USB
+    // image. Systems with only one slot won't be able to update.
+    [[nodiscard]] virtual int32_t GetNumSlots() const = 0;
+
+    // Return the slot where we are running the system from. On success, the
+    // result is a number between 0 and GetNumSlots() - 1. Otherwise, log an error
+    // and return kInvalidSlot.
+    [[nodiscard]] virtual int32_t GetCurrentSlot() const = 0;
+
+    // Return string suffix for input slot. Usually, for slot 0 the suffix is _a, and for slot 1 the
+    // suffix is _b.
+    [[nodiscard]] virtual std::string GetSuffix(int32_t slot) const = 0;
+
+    // Returns whether the passed |slot| is marked as bootable. Returns false if
+    // the slot is invalid.
+    [[nodiscard]] virtual std::optional<bool> IsSlotBootable(int32_t slot) const = 0;
+
+    // Mark the specified slot unbootable. No other slot flags are modified.
+    // Returns true on success.
+    [[nodiscard]] virtual CommandResult MarkSlotUnbootable(int32_t slot) = 0;
+
+    // Set the passed |slot| as the preferred boot slot. Returns whether it
+    // succeeded setting the active slot. If succeeded, on next boot the
+    // bootloader will attempt to load the |slot| marked as active. Note that this
+    // method doesn't change the value of GetCurrentSlot() on the current boot.
+    // Return true if operation succeeded.
+    [[nodiscard]] virtual CommandResult SetActiveBootSlot(int32_t slot) = 0;
+
+    // Check if |slot| is marked boot successfully. Return empty optional if the RPC call failed.
+    [[nodiscard]] virtual std::optional<bool> IsSlotMarkedSuccessful(int32_t slot) const = 0;
+
+    // Mark boot as successful. Return an error message if operation failed.
+    [[nodiscard]] virtual CommandResult MarkBootSuccessful() = 0;
+
+    // Added in IBootControl v1.1
+    // Return the current merge status.
+    [[nodiscard]] virtual MergeStatus getSnapshotMergeStatus() const = 0;
+
+    // Set snapshot merge status, return true if succeeded.
+    [[nodiscard]] virtual CommandResult SetSnapshotMergeStatus(MergeStatus status) = 0;
+
+    // Added in IBootControl v1.2
+    // Get the active slot. In other words, the slot which will be used on
+    // next system reboot. This should match the |slot| parameter of last
+    // successful call to |SetActiveBootSlot|.
+    // Return 0xFFFFFFFF if underlying HAL doesn't support this operation.
+    [[nodiscard]] virtual int32_t GetActiveBootSlot() const = 0;
+
+    [[nodiscard]] static std::unique_ptr<BootControlClient> WaitForService();
+};
+
+}  // namespace android::hal
+
+#endif
diff --git a/boot/aidl/default/Android.bp b/boot/aidl/default/Android.bp
new file mode 100644
index 0000000..6aefae8
--- /dev/null
+++ b/boot/aidl/default/Android.bp
@@ -0,0 +1,43 @@
+//
+// Copyright (C) 2022 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 {
+    // 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"],
+}
+
+cc_binary {
+    name: "android.hardware.boot-service.default",
+    defaults: ["libboot_control_defaults"],
+    relative_install_path: "hw",
+    init_rc: ["boot-default.rc"],
+    vintf_fragments: ["boot-default.xml"],
+    vendor: true,
+    shared_libs: [
+        "libbase",
+        "libbinder_ndk",
+        "android.hardware.boot@1.1",
+        "android.hardware.boot-V1-ndk",
+    ],
+    static_libs: [
+        "libboot_control",
+    ],
+    srcs: ["main.cpp", "BootControl.cpp"],
+}
diff --git a/boot/aidl/default/BootControl.cpp b/boot/aidl/default/BootControl.cpp
new file mode 100644
index 0000000..b73c94d
--- /dev/null
+++ b/boot/aidl/default/BootControl.cpp
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2022 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 "BootControl.h"
+#include <cstdint>
+
+#include <android-base/logging.h>
+
+using HIDLMergeStatus = ::android::bootable::BootControl::MergeStatus;
+using ndk::ScopedAStatus;
+
+namespace aidl::android::hardware::boot {
+
+BootControl::BootControl() {
+    CHECK(impl_.Init());
+}
+
+ScopedAStatus BootControl::getActiveBootSlot(int32_t* _aidl_return) {
+    *_aidl_return = impl_.GetActiveBootSlot();
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus BootControl::getCurrentSlot(int32_t* _aidl_return) {
+    *_aidl_return = impl_.GetCurrentSlot();
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus BootControl::getNumberSlots(int32_t* _aidl_return) {
+    *_aidl_return = impl_.GetNumberSlots();
+    return ScopedAStatus::ok();
+}
+
+namespace {
+
+static constexpr MergeStatus ToAIDLMergeStatus(HIDLMergeStatus status) {
+    switch (status) {
+        case HIDLMergeStatus::NONE:
+            return MergeStatus::NONE;
+        case HIDLMergeStatus::UNKNOWN:
+            return MergeStatus::UNKNOWN;
+        case HIDLMergeStatus::SNAPSHOTTED:
+            return MergeStatus::SNAPSHOTTED;
+        case HIDLMergeStatus::MERGING:
+            return MergeStatus::MERGING;
+        case HIDLMergeStatus::CANCELLED:
+            return MergeStatus::CANCELLED;
+    }
+}
+
+static constexpr HIDLMergeStatus ToHIDLMergeStatus(MergeStatus status) {
+    switch (status) {
+        case MergeStatus::NONE:
+            return HIDLMergeStatus::NONE;
+        case MergeStatus::UNKNOWN:
+            return HIDLMergeStatus::UNKNOWN;
+        case MergeStatus::SNAPSHOTTED:
+            return HIDLMergeStatus::SNAPSHOTTED;
+        case MergeStatus::MERGING:
+            return HIDLMergeStatus::MERGING;
+        case MergeStatus::CANCELLED:
+            return HIDLMergeStatus::CANCELLED;
+    }
+}
+
+}
+
+ScopedAStatus BootControl::getSnapshotMergeStatus(MergeStatus* _aidl_return) {
+    *_aidl_return = ToAIDLMergeStatus(impl_.GetSnapshotMergeStatus());
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus BootControl::getSuffix(int32_t in_slot, std::string* _aidl_return) {
+    if (!impl_.IsValidSlot(in_slot)) {
+        // Old HIDL hal returns empty string for invalid slots. We should maintain this behavior in
+        // AIDL for compatibility.
+        _aidl_return->clear();
+    } else {
+        *_aidl_return = impl_.GetSuffix(in_slot);
+    }
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus BootControl::isSlotBootable(int32_t in_slot, bool* _aidl_return) {
+    if (!impl_.IsValidSlot(in_slot)) {
+        return ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                INVALID_SLOT, (std::string("Invalid slot ") + std::to_string(in_slot)).c_str());
+    }
+    *_aidl_return = impl_.IsSlotBootable(in_slot);
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus BootControl::isSlotMarkedSuccessful(int32_t in_slot, bool* _aidl_return) {
+    if (!impl_.IsValidSlot(in_slot)) {
+        return ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                INVALID_SLOT, (std::string("Invalid slot ") + std::to_string(in_slot)).c_str());
+    }
+    *_aidl_return = impl_.IsSlotMarkedSuccessful(in_slot);
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus BootControl::markBootSuccessful() {
+    if (!impl_.MarkBootSuccessful()) {
+        return ScopedAStatus::fromServiceSpecificErrorWithMessage(COMMAND_FAILED,
+                                                                  "Operation failed");
+    }
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus BootControl::setActiveBootSlot(int32_t in_slot) {
+    if (!impl_.IsValidSlot(in_slot)) {
+        return ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                INVALID_SLOT, (std::string("Invalid slot ") + std::to_string(in_slot)).c_str());
+    }
+    if (!impl_.SetActiveBootSlot(in_slot)) {
+        return ScopedAStatus::fromServiceSpecificErrorWithMessage(COMMAND_FAILED,
+                                                                  "Operation failed");
+    }
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus BootControl::setSlotAsUnbootable(int32_t in_slot) {
+    if (!impl_.IsValidSlot(in_slot)) {
+        return ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                INVALID_SLOT, (std::string("Invalid slot ") + std::to_string(in_slot)).c_str());
+    }
+    if (!impl_.SetSlotAsUnbootable(in_slot)) {
+        return ScopedAStatus::fromServiceSpecificErrorWithMessage(COMMAND_FAILED,
+                                                                  "Operation failed");
+    }
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus BootControl::setSnapshotMergeStatus(MergeStatus in_status) {
+    if (!impl_.SetSnapshotMergeStatus(ToHIDLMergeStatus(in_status))) {
+        return ScopedAStatus::fromServiceSpecificErrorWithMessage(COMMAND_FAILED,
+                                                                  "Operation failed");
+    }
+    return ScopedAStatus::ok();
+}
+
+}  // namespace aidl::android::hardware::boot
diff --git a/boot/aidl/default/BootControl.h b/boot/aidl/default/BootControl.h
new file mode 100644
index 0000000..54cd32d
--- /dev/null
+++ b/boot/aidl/default/BootControl.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/boot/BnBootControl.h>
+#include <libboot_control/libboot_control.h>
+
+namespace aidl::android::hardware::boot {
+
+class BootControl final : public BnBootControl {
+  public:
+    BootControl();
+    ::ndk::ScopedAStatus getActiveBootSlot(int32_t* _aidl_return) override;
+    ::ndk::ScopedAStatus getCurrentSlot(int32_t* _aidl_return) override;
+    ::ndk::ScopedAStatus getNumberSlots(int32_t* _aidl_return) override;
+    ::ndk::ScopedAStatus getSnapshotMergeStatus(
+            ::aidl::android::hardware::boot::MergeStatus* _aidl_return) override;
+    ::ndk::ScopedAStatus getSuffix(int32_t in_slot, std::string* _aidl_return) override;
+    ::ndk::ScopedAStatus isSlotBootable(int32_t in_slot, bool* _aidl_return) override;
+    ::ndk::ScopedAStatus isSlotMarkedSuccessful(int32_t in_slot, bool* _aidl_return) override;
+    ::ndk::ScopedAStatus markBootSuccessful() override;
+    ::ndk::ScopedAStatus setActiveBootSlot(int32_t in_slot) override;
+    ::ndk::ScopedAStatus setSlotAsUnbootable(int32_t in_slot) override;
+    ::ndk::ScopedAStatus setSnapshotMergeStatus(
+            ::aidl::android::hardware::boot::MergeStatus in_status) override;
+
+  private:
+    ::android::bootable::BootControl impl_;
+};
+
+}  // namespace aidl::android::hardware::boot
diff --git a/boot/aidl/default/boot-default.rc b/boot/aidl/default/boot-default.rc
new file mode 100644
index 0000000..589f803
--- /dev/null
+++ b/boot/aidl/default/boot-default.rc
@@ -0,0 +1,5 @@
+service vendor.boot-default /vendor/bin/hw/android.hardware.boot-service.default
+    class early_hal
+    user root
+    group root
+
diff --git a/boot/aidl/default/boot-default.xml b/boot/aidl/default/boot-default.xml
new file mode 100644
index 0000000..23ccc4e
--- /dev/null
+++ b/boot/aidl/default/boot-default.xml
@@ -0,0 +1,6 @@
+<manifest version="1.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.boot</name>
+        <fqname>IBootControl/default</fqname>
+    </hal>
+</manifest>
diff --git a/boot/aidl/default/main.cpp b/boot/aidl/default/main.cpp
new file mode 100644
index 0000000..70b284e
--- /dev/null
+++ b/boot/aidl/default/main.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 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 "BootControl.h"
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+using aidl::android::hardware::boot::BootControl;
+using aidl::android::hardware::boot::IBootControl;
+
+int main(int, char* argv[]) {
+    android::base::InitLogging(argv, android::base::KernelLogger);
+    ABinderProcess_setThreadPoolMaxThreadCount(0);
+    std::shared_ptr<IBootControl> service = ndk::SharedRefBase::make<BootControl>();
+
+    const std::string instance = std::string(BootControl::descriptor) + "/default";
+    auto status = AServiceManager_addService(service->asBinder().get(), instance.c_str());
+    CHECK_EQ(status, STATUS_OK) << "Failed to add service " << instance << " " << status;
+    LOG(INFO) << "IBootControl AIDL service running...";
+
+    ABinderProcess_joinThreadPool();
+    return EXIT_FAILURE;  // should not reach
+}
diff --git a/boot/aidl/vts/functional/Android.bp b/boot/aidl/vts/functional/Android.bp
new file mode 100644
index 0000000..e46cbef
--- /dev/null
+++ b/boot/aidl/vts/functional/Android.bp
@@ -0,0 +1,41 @@
+//
+// Copyright (C) 2022 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 {
+    // 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"],
+}
+
+cc_test {
+    name: "VtsHalBootAidlTargetTest",
+    defaults: [
+        "VtsHalTargetTestDefaults",
+        "use_libaidlvintf_gtest_helper_static"
+    ],
+    srcs: ["VtsHalBootAidlTargetTest.cpp"],
+    static_libs: [
+        "android.hardware.boot-V1-ndk",
+    ],
+    shared_libs: [
+        "libbinder_ndk",
+        "libvintf",
+    ],
+    test_suites: ["general-tests", "vts"],
+}
diff --git a/boot/aidl/vts/functional/OWNERS b/boot/aidl/vts/functional/OWNERS
new file mode 100644
index 0000000..bc813d8
--- /dev/null
+++ b/boot/aidl/vts/functional/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 30545
+zhangkelvin@google.com
diff --git a/boot/aidl/vts/functional/VtsHalBootAidlTargetTest.cpp b/boot/aidl/vts/functional/VtsHalBootAidlTargetTest.cpp
new file mode 100644
index 0000000..ab3c789
--- /dev/null
+++ b/boot/aidl/vts/functional/VtsHalBootAidlTargetTest.cpp
@@ -0,0 +1,194 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+
+#include <cutils/properties.h>
+
+#include <aidl/android/hardware/boot/IBootControl.h>
+
+#include <aidl/Vintf.h>
+#include <android/binder_manager.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
+
+#include <unordered_set>
+
+using aidl::android::hardware::boot::IBootControl;
+using std::string;
+using std::unordered_set;
+
+// The main test class for the Boot HIDL HAL.
+class BootHidlTest : public ::testing::TestWithParam<std::string> {
+  public:
+    virtual void SetUp() override {
+        const auto instance_name = GetParam();
+        ASSERT_TRUE(AServiceManager_isDeclared(instance_name.c_str()))
+                << " instance " << instance_name << " not declared.";
+        boot = ::aidl::android::hardware::boot::IBootControl::fromBinder(
+                ndk::SpAIBinder(AServiceManager_waitForService(instance_name.c_str())));
+        ASSERT_NE(boot, nullptr);
+    }
+
+    std::shared_ptr<IBootControl> boot;
+};
+
+// validity check Boot::getNumberSlots().
+TEST_P(BootHidlTest, GetNumberSlots) {
+    int32_t slots{};
+    boot->getNumberSlots(&slots);
+    ASSERT_LE(2, slots);
+}
+
+// validity check Boot::getCurrentSlot().
+TEST_P(BootHidlTest, GetCurrentSlot) {
+    int curSlot = -1;
+    boot->getCurrentSlot(&curSlot);
+    int slots = 0;
+    boot->getNumberSlots(&slots);
+    ASSERT_LT(curSlot, slots);
+}
+
+// validity check Boot::markBootSuccessful().
+TEST_P(BootHidlTest, MarkBootSuccessful) {
+    const auto result = boot->markBootSuccessful();
+    ASSERT_TRUE(result.isOk());
+    int curSlot = 0;
+    boot->getCurrentSlot(&curSlot);
+    bool ret = false;
+    boot->isSlotMarkedSuccessful(curSlot, &ret);
+    ASSERT_TRUE(ret);
+}
+
+TEST_P(BootHidlTest, SetActiveBootSlot) {
+    int curSlot = -1;
+    boot->getCurrentSlot(&curSlot);
+    ASSERT_GE(curSlot, 0);
+    int otherSlot = curSlot ? 0 : 1;
+    bool otherBootable = true;
+    boot->isSlotBootable(otherSlot, &otherBootable);
+
+    for (int s = 0; s < 2; s++) {
+        const auto result = boot->setActiveBootSlot(s);
+        ASSERT_TRUE(result.isOk());
+    }
+    {
+        // Restore original flags to avoid problems on reboot
+        auto result = boot->setActiveBootSlot(curSlot);
+        ASSERT_TRUE(result.isOk());
+
+        if (!otherBootable) {
+            const auto result = boot->setSlotAsUnbootable(otherSlot);
+            ASSERT_TRUE(result.isOk());
+        }
+
+        result = boot->markBootSuccessful();
+        ASSERT_TRUE(result.isOk());
+    }
+    {
+        int slots = 0;
+        boot->getNumberSlots(&slots);
+        const auto result = boot->setActiveBootSlot(slots);
+        ASSERT_FALSE(result.isOk()) << "setActiveBootSlot on invalid slot should fail";
+    }
+}
+
+TEST_P(BootHidlTest, SetSlotAsUnbootable) {
+    int curSlot = -1;
+    boot->getCurrentSlot(&curSlot);
+    ASSERT_GE(curSlot, 0);
+    int otherSlot = curSlot ? 0 : 1;
+    bool otherBootable = false;
+    boot->isSlotBootable(otherSlot, &otherBootable);
+    {
+        auto result = boot->setSlotAsUnbootable(otherSlot);
+        ASSERT_TRUE(result.isOk());
+        boot->isSlotBootable(otherSlot, &otherBootable);
+        ASSERT_FALSE(otherBootable);
+
+        // Restore original flags to avoid problems on reboot
+        if (otherBootable) {
+            result = boot->setActiveBootSlot(otherSlot);
+            ASSERT_TRUE(result.isOk());
+        }
+        result = boot->setActiveBootSlot(curSlot);
+        ASSERT_TRUE(result.isOk());
+        result = boot->markBootSuccessful();
+        ASSERT_TRUE(result.isOk());
+    }
+    {
+        int32_t slots = 0;
+        boot->getNumberSlots(&slots);
+        const auto result = boot->setSlotAsUnbootable(slots);
+        ASSERT_FALSE(result.isOk());
+    }
+}
+
+// validity check Boot::isSlotBootable() on good and bad inputs.
+TEST_P(BootHidlTest, IsSlotBootable) {
+    for (int s = 0; s < 2; s++) {
+        bool bootable = false;
+        const auto res = boot->isSlotBootable(s, &bootable);
+        ASSERT_TRUE(res.isOk()) << res.getMessage();
+    }
+    int32_t slots = 0;
+    boot->getNumberSlots(&slots);
+    bool bootable = false;
+    const auto res = boot->isSlotBootable(slots, &bootable);
+    ASSERT_FALSE(res.isOk());
+}
+
+// validity check Boot::isSlotMarkedSuccessful() on good and bad inputs.
+TEST_P(BootHidlTest, IsSlotMarkedSuccessful) {
+    for (int32_t s = 0; s < 2; s++) {
+        bool isSuccess = false;
+        const auto res = boot->isSlotMarkedSuccessful(s, &isSuccess);
+    }
+    int32_t slots = 0;
+    boot->getNumberSlots(&slots);
+    bool isSuccess = false;
+    const auto res = boot->isSlotMarkedSuccessful(slots, &isSuccess);
+    ASSERT_FALSE(res.isOk());
+}
+
+// validity check Boot::getSuffix() on good and bad inputs.
+TEST_P(BootHidlTest, GetSuffix) {
+    string suffixStr;
+    unordered_set<string> suffixes;
+    int numSlots = 0;
+    boot->getNumberSlots(&numSlots);
+    for (int32_t i = 0; i < numSlots; i++) {
+        std::string suffix;
+        const auto result = boot->getSuffix(i, &suffixStr);
+        ASSERT_TRUE(result.isOk());
+        ASSERT_EQ('_', suffixStr[0]);
+        ASSERT_LE((unsigned)2, suffixStr.size());
+        suffixes.insert(suffixStr);
+    }
+    // All suffixes should be unique
+    ASSERT_EQ(numSlots, suffixes.size());
+    {
+        const string emptySuffix = "";
+        const auto result = boot->getSuffix(numSlots, &suffixStr);
+        ASSERT_TRUE(result.isOk());
+        ASSERT_EQ(suffixStr, emptySuffix);
+    }
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, BootHidlTest,
+        testing::ValuesIn(android::getAidlHalInstanceNames(IBootControl::descriptor)));
diff --git a/broadcastradio/1.0/default/OWNERS b/broadcastradio/1.0/default/OWNERS
index 57e6592..302fdd7 100644
--- a/broadcastradio/1.0/default/OWNERS
+++ b/broadcastradio/1.0/default/OWNERS
@@ -1,3 +1,4 @@
-elaurent@google.com
-mnaganov@google.com
-twasilczyk@google.com
+xuweilin@google.com
+oscarazu@google.com
+ericjeong@google.com
+keunyoung@google.com
diff --git a/broadcastradio/1.0/vts/functional/OWNERS b/broadcastradio/1.0/vts/functional/OWNERS
index 778c4a2..aa19d6a 100644
--- a/broadcastradio/1.0/vts/functional/OWNERS
+++ b/broadcastradio/1.0/vts/functional/OWNERS
@@ -1,2 +1,5 @@
 # Bug component: 533946
+xuweilin@google.com
 oscarazu@google.com
+ericjeong@google.com
+keunyoung@google.com
diff --git a/broadcastradio/1.1/default/OWNERS b/broadcastradio/1.1/default/OWNERS
index 136b607..259b91e 100644
--- a/broadcastradio/1.1/default/OWNERS
+++ b/broadcastradio/1.1/default/OWNERS
@@ -1,3 +1,5 @@
 # Automotive team
-egranata@google.com
-twasilczyk@google.com
+xuweilin@google.com
+oscarazu@google.com
+ericjeong@google.com
+keunyoung@google.com
diff --git a/broadcastradio/1.1/vts/OWNERS b/broadcastradio/1.1/vts/OWNERS
index 2c21c25..aa19d6a 100644
--- a/broadcastradio/1.1/vts/OWNERS
+++ b/broadcastradio/1.1/vts/OWNERS
@@ -1,3 +1,5 @@
 # Bug component: 533946
+xuweilin@google.com
 oscarazu@google.com
+ericjeong@google.com
 keunyoung@google.com
diff --git a/broadcastradio/2.0/default/OWNERS b/broadcastradio/2.0/default/OWNERS
index 136b607..259b91e 100644
--- a/broadcastradio/2.0/default/OWNERS
+++ b/broadcastradio/2.0/default/OWNERS
@@ -1,3 +1,5 @@
 # Automotive team
-egranata@google.com
-twasilczyk@google.com
+xuweilin@google.com
+oscarazu@google.com
+ericjeong@google.com
+keunyoung@google.com
diff --git a/broadcastradio/2.0/vts/OWNERS b/broadcastradio/2.0/vts/OWNERS
index 1ff7407..09690ef 100644
--- a/broadcastradio/2.0/vts/OWNERS
+++ b/broadcastradio/2.0/vts/OWNERS
@@ -1,6 +1,8 @@
 # Automotive team
-egranata@google.com
-twasilczyk@google.com
+xuweilin@google.com
+oscarazu@google.com
+ericjeong@google.com
+keunyoung@google.com
 
 # VTS team
 dshi@google.com
diff --git a/broadcastradio/2.0/vts/functional/OWNERS b/broadcastradio/2.0/vts/functional/OWNERS
index 2c21c25..aa19d6a 100644
--- a/broadcastradio/2.0/vts/functional/OWNERS
+++ b/broadcastradio/2.0/vts/functional/OWNERS
@@ -1,3 +1,5 @@
 # Bug component: 533946
+xuweilin@google.com
 oscarazu@google.com
+ericjeong@google.com
 keunyoung@google.com
diff --git a/broadcastradio/common/OWNERS b/broadcastradio/common/OWNERS
index 136b607..259b91e 100644
--- a/broadcastradio/common/OWNERS
+++ b/broadcastradio/common/OWNERS
@@ -1,3 +1,5 @@
 # Automotive team
-egranata@google.com
-twasilczyk@google.com
+xuweilin@google.com
+oscarazu@google.com
+ericjeong@google.com
+keunyoung@google.com
diff --git a/compatibility_matrices/Android.bp b/compatibility_matrices/Android.bp
index 193fd2b..524242f 100644
--- a/compatibility_matrices/Android.bp
+++ b/compatibility_matrices/Android.bp
@@ -74,6 +74,18 @@
 }
 
 vintf_compatibility_matrix {
+    name: "framework_compatibility_matrix.7.xml",
+    stem: "compatibility_matrix.7.xml",
+    srcs: [
+        "compatibility_matrix.7.xml",
+    ],
+    kernel_configs: [
+        "kernel_config_t_5.10",
+        "kernel_config_t_5.15",
+    ],
+}
+
+vintf_compatibility_matrix {
     name: "framework_compatibility_matrix.current.xml",
     stem: "compatibility_matrix.current.xml",
     srcs: [
diff --git a/compatibility_matrices/Android.mk b/compatibility_matrices/Android.mk
index 9e715bf..d19f0da 100644
--- a/compatibility_matrices/Android.mk
+++ b/compatibility_matrices/Android.mk
@@ -102,6 +102,7 @@
     framework_compatibility_matrix.4.xml \
     framework_compatibility_matrix.5.xml \
     framework_compatibility_matrix.6.xml \
+    framework_compatibility_matrix.7.xml \
     framework_compatibility_matrix.current.xml \
     framework_compatibility_matrix.device.xml \
 
diff --git a/compatibility_matrices/compatibility_matrix.7.xml b/compatibility_matrices/compatibility_matrix.7.xml
new file mode 100644
index 0000000..6967671
--- /dev/null
+++ b/compatibility_matrices/compatibility_matrix.7.xml
@@ -0,0 +1,720 @@
+<compatibility-matrix version="1.0" type="framework" level="7">
+    <hal format="hidl" optional="true">
+        <name>android.hardware.atrace</name>
+        <version>1.0</version>
+        <interface>
+            <name>IAtraceDevice</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="false">
+        <name>android.hardware.audio</name>
+        <version>6.0</version>
+        <version>7.0-1</version>
+        <interface>
+            <name>IDevicesFactory</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="false">
+        <name>android.hardware.audio.effect</name>
+        <version>6.0</version>
+        <version>7.0</version>
+        <interface>
+            <name>IEffectsFactory</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+         <name>android.hardware.authsecret</name>
+         <version>1</version>
+         <interface>
+             <name>IAuthSecret</name>
+             <instance>default</instance>
+         </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.authsecret</name>
+        <version>1.0</version>
+        <interface>
+            <name>IAuthSecret</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.automotive.audiocontrol</name>
+        <interface>
+            <name>IAudioControl</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.automotive.can</name>
+        <version>1.0</version>
+        <interface>
+            <name>ICanBus</name>
+            <regex-instance>.*</regex-instance>
+        </interface>
+        <interface>
+            <name>ICanController</name>
+            <regex-instance>.*</regex-instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.automotive.evs</name>
+        <version>1.0-1</version>
+        <interface>
+            <name>IEvsEnumerator</name>
+            <instance>default</instance>
+            <regex-instance>[a-z]+/[0-9]+</regex-instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.automotive.occupant_awareness</name>
+        <version>1</version>
+        <interface>
+            <name>IOccupantAwareness</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.automotive.sv</name>
+        <version>1.0</version>
+        <interface>
+            <name>ISurroundViewService</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.automotive.vehicle</name>
+        <version>2.0</version>
+        <interface>
+            <name>IVehicle</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.biometrics.face</name>
+        <version>1.0</version>
+        <interface>
+            <name>IBiometricsFace</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.biometrics.face</name>
+        <interface>
+            <name>IFace</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.biometrics.fingerprint</name>
+        <version>2.1-3</version>
+        <interface>
+            <name>IBiometricsFingerprint</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.biometrics.fingerprint</name>
+        <interface>
+            <name>IFingerprint</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.bluetooth</name>
+        <version>1.0-1</version>
+        <interface>
+            <name>IBluetoothHci</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.bluetooth.audio</name>
+        <interface>
+            <name>IBluetoothAudioProviderFactory</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.boot</name>
+        <version>1.2</version>
+        <interface>
+            <name>IBootControl</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.broadcastradio</name>
+        <version>1.0-1</version>
+        <interface>
+            <name>IBroadcastRadioFactory</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.broadcastradio</name>
+        <version>2.0</version>
+        <interface>
+            <name>IBroadcastRadio</name>
+            <regex-instance>.*</regex-instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.camera.provider</name>
+        <version>2.4-7</version>
+        <interface>
+            <name>ICameraProvider</name>
+            <regex-instance>[^/]+/[0-9]+</regex-instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.cas</name>
+        <version>1.1-2</version>
+        <interface>
+            <name>IMediaCasService</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.confirmationui</name>
+        <version>1.0</version>
+        <interface>
+            <name>IConfirmationUI</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.contexthub</name>
+        <version>1.2</version>
+        <interface>
+            <name>IContexthub</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.drm</name>
+        <version>1.3-4</version>
+        <interface>
+            <name>ICryptoFactory</name>
+            <regex-instance>.*</regex-instance>
+        </interface>
+        <interface>
+            <name>IDrmFactory</name>
+            <regex-instance>.*</regex-instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.dumpstate</name>
+        <interface>
+            <name>IDumpstateDevice</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="false">
+        <name>android.hardware.gatekeeper</name>
+        <version>1.0</version>
+        <interface>
+            <name>IGatekeeper</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.gnss</name>
+        <version>2.0-1</version>
+        <interface>
+            <name>IGnss</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.gnss</name>
+        <interface>
+            <name>IGnss</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="false">
+        <name>android.hardware.graphics.allocator</name>
+        <!-- New, non-Go devices should use 4.0, tested in vts_treble_vintf_vendor_test -->
+        <version>2.0</version>
+        <version>3.0</version>
+        <version>4.0</version>
+        <interface>
+            <name>IAllocator</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="false">
+        <name>android.hardware.graphics.composer</name>
+        <version>2.1-4</version>
+        <interface>
+            <name>IComposer</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="false">
+        <name>android.hardware.graphics.mapper</name>
+        <!-- New, non-Go devices should use 4.0, tested in vts_treble_vintf_vendor_test -->
+        <version>2.1</version>
+        <version>3.0</version>
+        <version>4.0</version>
+        <interface>
+            <name>IMapper</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="false">
+        <name>android.hardware.health</name>
+        <version>1</version>
+        <interface>
+            <name>IHealth</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.health.storage</name>
+        <version>1</version>
+        <interface>
+            <name>IStorage</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.identity</name>
+        <version>1-4</version>
+        <interface>
+            <name>IIdentityCredentialStore</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.oemlock</name>
+        <version>1</version>
+        <interface>
+            <name>IOemLock</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.ir</name>
+        <version>1</version>
+        <interface>
+            <name>IConsumerIr</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.input.classifier</name>
+        <version>1.0</version>
+        <interface>
+            <name>IInputClassifier</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.keymaster</name>
+        <version>3.0</version>
+        <version>4.0-1</version>
+        <interface>
+            <name>IKeymasterDevice</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.keymaster</name>
+        <version>4.0-1</version>
+        <interface>
+            <name>IKeymasterDevice</name>
+            <instance>strongbox</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.security.dice</name>
+        <version>1</version>
+        <interface>
+            <name>IDiceDevice</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.security.keymint</name>
+        <version>1-2</version>
+        <interface>
+            <name>IKeyMintDevice</name>
+            <instance>default</instance>
+            <instance>strongbox</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.security.keymint</name>
+        <version>1-2</version>
+        <interface>
+            <name>IRemotelyProvisionedComponent</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.light</name>
+        <version>1</version>
+        <interface>
+            <name>ILights</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.media.c2</name>
+        <version>1.0-2</version>
+        <interface>
+            <name>IComponentStore</name>
+            <regex-instance>default[0-9]*</regex-instance>
+            <regex-instance>vendor[0-9]*_software</regex-instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.media.omx</name>
+        <version>1.0</version>
+        <interface>
+            <name>IOmx</name>
+            <instance>default</instance>
+        </interface>
+        <interface>
+            <name>IOmxStore</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.memtrack</name>
+        <version>1</version>
+        <interface>
+            <name>IMemtrack</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.neuralnetworks</name>
+        <version>1.0-3</version>
+        <interface>
+            <name>IDevice</name>
+            <regex-instance>.*</regex-instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.neuralnetworks</name>
+        <version>1-4</version>
+        <interface>
+            <name>IDevice</name>
+            <regex-instance>.*</regex-instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.nfc</name>
+        <version>1.2</version>
+        <interface>
+            <name>INfc</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.nfc</name>
+        <interface>
+            <name>INfc</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.oemlock</name>
+        <version>1.0</version>
+        <interface>
+            <name>IOemLock</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="false">
+        <name>android.hardware.power</name>
+        <version>1-2</version>
+        <interface>
+            <name>IPower</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.power.stats</name>
+        <interface>
+            <name>IPowerStats</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.radio.config</name>
+        <version>1</version>
+        <interface>
+            <name>IRadioConfig</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.radio.data</name>
+        <version>1</version>
+        <interface>
+            <name>IRadioData</name>
+            <instance>slot1</instance>
+            <instance>slot2</instance>
+            <instance>slot3</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.radio.messaging</name>
+        <version>1</version>
+        <interface>
+            <name>IRadioMessaging</name>
+            <instance>slot1</instance>
+            <instance>slot2</instance>
+            <instance>slot3</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.radio.modem</name>
+        <version>1</version>
+        <interface>
+            <name>IRadioModem</name>
+            <instance>slot1</instance>
+            <instance>slot2</instance>
+            <instance>slot3</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.radio.network</name>
+        <version>1</version>
+        <interface>
+            <name>IRadioNetwork</name>
+            <instance>slot1</instance>
+            <instance>slot2</instance>
+            <instance>slot3</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.radio.sim</name>
+        <version>1</version>
+        <interface>
+            <name>IRadioSim</name>
+            <instance>slot1</instance>
+            <instance>slot2</instance>
+            <instance>slot3</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.radio.voice</name>
+        <version>1</version>
+        <interface>
+            <name>IRadioVoice</name>
+            <instance>slot1</instance>
+            <instance>slot2</instance>
+            <instance>slot3</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.radio</name>
+        <version>1.2</version>
+        <interface>
+            <name>ISap</name>
+            <instance>slot1</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.renderscript</name>
+        <version>1.0</version>
+        <interface>
+            <name>IDevice</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.rebootescrow</name>
+        <version>1</version>
+        <interface>
+            <name>IRebootEscrow</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.secure_element</name>
+        <version>1.0-2</version>
+        <interface>
+            <name>ISecureElement</name>
+            <regex-instance>eSE[1-9][0-9]*</regex-instance>
+            <regex-instance>SIM[1-9][0-9]*</regex-instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.security.secureclock</name>
+        <version>1</version>
+        <interface>
+            <name>ISecureClock</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.security.sharedsecret</name>
+        <version>1</version>
+        <interface>
+            <name>ISharedSecret</name>
+            <instance>default</instance>
+            <instance>strongbox</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.sensors</name>
+        <version>1.0</version>
+        <version>2.0-1</version>
+        <interface>
+            <name>ISensors</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.soundtrigger</name>
+        <version>2.3</version>
+        <interface>
+            <name>ISoundTriggerHw</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.tetheroffload.config</name>
+        <version>1.0</version>
+        <interface>
+            <name>IOffloadConfig</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.tetheroffload.control</name>
+        <version>1.1</version>
+        <interface>
+            <name>IOffloadControl</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="false">
+        <name>android.hardware.thermal</name>
+        <version>2.0</version>
+        <interface>
+            <name>IThermal</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.tv.cec</name>
+        <version>1.0-1</version>
+        <interface>
+            <name>IHdmiCec</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.tv.input</name>
+        <version>1.0</version>
+        <interface>
+            <name>ITvInput</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.tv.tuner</name>
+        <version>1.0-1</version>
+        <interface>
+            <name>ITuner</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.usb</name>
+        <version>1.0-3</version>
+        <interface>
+            <name>IUsb</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.usb.gadget</name>
+        <version>1.0-2</version>
+        <interface>
+            <name>IUsbGadget</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.vibrator</name>
+        <version>1-2</version>
+        <interface>
+            <name>IVibrator</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.vibrator</name>
+        <version>1-2</version>
+        <interface>
+            <name>IVibratorManager</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.weaver</name>
+        <version>1.0</version>
+        <interface>
+            <name>IWeaver</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.weaver</name>
+        <version>1</version>
+        <interface>
+            <name>IWeaver</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.wifi</name>
+        <version>1.3-5</version>
+        <interface>
+            <name>IWifi</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.wifi.hostapd</name>
+        <version>1.0-3</version>
+        <interface>
+            <name>IHostapd</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.wifi.hostapd</name>
+        <version>1</version>
+        <interface>
+            <name>IHostapd</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="hidl" optional="true">
+        <name>android.hardware.wifi.supplicant</name>
+        <version>1.2-4</version>
+        <interface>
+            <name>ISupplicant</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.wifi.supplicant</name>
+        <interface>
+            <name>ISupplicant</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+</compatibility-matrix>
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index 6967671..74fddda 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -1,4 +1,4 @@
-<compatibility-matrix version="1.0" type="framework" level="7">
+<compatibility-matrix version="1.0" type="framework" level="8">
     <hal format="hidl" optional="true">
         <name>android.hardware.atrace</name>
         <version>1.0</version>
@@ -138,9 +138,8 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="aidl" optional="true">
         <name>android.hardware.boot</name>
-        <version>1.2</version>
         <interface>
             <name>IBootControl</name>
             <instance>default</instance>
@@ -354,6 +353,7 @@
         <interface>
             <name>IRemotelyProvisionedComponent</name>
             <instance>default</instance>
+            <instance>strongbox</instance>
         </interface>
     </hal>
     <hal format="aidl" optional="true">
@@ -638,6 +638,13 @@
             <instance>default</instance>
         </interface>
     </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.usb</name>
+        <interface>
+            <name>IUsb</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
     <hal format="hidl" optional="true">
         <name>android.hardware.usb.gadget</name>
         <version>1.0-2</version>
@@ -678,6 +685,14 @@
             <instance>default</instance>
         </interface>
     </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.wifi</name>
+        <version>1</version>
+        <interface>
+            <name>IWifi</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
     <hal format="hidl" optional="true">
         <name>android.hardware.wifi</name>
         <version>1.3-5</version>
diff --git a/confirmationui/support/Android.bp b/confirmationui/support/Android.bp
index 6ab83f2..1200115 100644
--- a/confirmationui/support/Android.bp
+++ b/confirmationui/support/Android.bp
@@ -36,7 +36,7 @@
     ],
     export_include_dirs: [
         "include",
-    ]
+    ],
 }
 
 cc_test {
@@ -56,6 +56,5 @@
         "libhidlbase",
     ],
     test_suites: ["general-tests"],
-    clang: true,
-    cflags: [ "-O0" ],
+    cflags: ["-O0"],
 }
diff --git a/dumpstate/aidl/Android.bp b/dumpstate/aidl/Android.bp
index 22d836b..4de5da3 100644
--- a/dumpstate/aidl/Android.bp
+++ b/dumpstate/aidl/Android.bp
@@ -33,10 +33,5 @@
         java: {
             enabled: false,
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
     },
 }
diff --git a/gatekeeper/1.0/vts/functional/VtsHalGatekeeperV1_0TargetTest.cpp b/gatekeeper/1.0/vts/functional/VtsHalGatekeeperV1_0TargetTest.cpp
index f3fa0b4..e938b01 100644
--- a/gatekeeper/1.0/vts/functional/VtsHalGatekeeperV1_0TargetTest.cpp
+++ b/gatekeeper/1.0/vts/functional/VtsHalGatekeeperV1_0TargetTest.cpp
@@ -244,6 +244,47 @@
 }
 
 /**
+ * Ensure that passwords containing a NUL byte aren't truncated
+ */
+TEST_P(GatekeeperHidlTest, PasswordIsBinaryData) {
+  GatekeeperResponse enrollRsp;
+  GatekeeperResponse verifyRsp;
+  hidl_vec<uint8_t> rightPassword = {'A', 'B', 'C', '\0', 'D', 'E', 'F'};
+  hidl_vec<uint8_t> wrongPassword = {'A', 'B', 'C', '\0', '\0', '\0', '\0'};
+
+  ALOGI("Testing Enroll+Verify of password with embedded NUL (expected success)");
+  enrollNewPassword(rightPassword, enrollRsp, true);
+  verifyPassword(rightPassword, enrollRsp.data, 1, verifyRsp, true);
+
+  ALOGI("Testing Verify of wrong password (expected failure)");
+  verifyPassword(wrongPassword, enrollRsp.data, 1, verifyRsp, false);
+
+  ALOGI("PasswordIsBinaryData test done");
+}
+
+/**
+ * Ensure that long passwords aren't truncated
+ */
+TEST_P(GatekeeperHidlTest, LongPassword) {
+  GatekeeperResponse enrollRsp;
+  GatekeeperResponse verifyRsp;
+  hidl_vec<uint8_t> password;
+
+  password.resize(64); // maximum length used by Android
+  memset(password.data(), 'A', password.size());
+
+  ALOGI("Testing Enroll+Verify of long password (expected success)");
+  enrollNewPassword(password, enrollRsp, true);
+  verifyPassword(password, enrollRsp.data, 1, verifyRsp, true);
+
+  ALOGI("Testing Verify of wrong password (expected failure)");
+  password[password.size() - 1] ^= 1;
+  verifyPassword(password, enrollRsp.data, 1, verifyRsp, false);
+
+  ALOGI("LongPassword test done");
+}
+
+/**
  * Ensure we can securely update password (keep the same
  * secure user_id) if we prove we know old password
  */
diff --git a/gnss/aidl/Android.bp b/gnss/aidl/Android.bp
index b197eae..3797c69 100644
--- a/gnss/aidl/Android.bp
+++ b/gnss/aidl/Android.bp
@@ -32,11 +32,6 @@
         java: {
             platform_apis: true,
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
     },
     versions: ["1"],
 }
diff --git a/gnss/aidl/default/GnssMeasurementInterface.cpp b/gnss/aidl/default/GnssMeasurementInterface.cpp
index fcc1f98..9e4f7c7 100644
--- a/gnss/aidl/default/GnssMeasurementInterface.cpp
+++ b/gnss/aidl/default/GnssMeasurementInterface.cpp
@@ -19,11 +19,17 @@
 #include "GnssMeasurementInterface.h"
 #include <aidl/android/hardware/gnss/BnGnss.h>
 #include <log/log.h>
+#include "DeviceFileReader.h"
+#include "GnssRawMeasurementParser.h"
+#include "GnssReplayUtils.h"
 #include "Utils.h"
 
 namespace aidl::android::hardware::gnss {
 
 using Utils = ::android::hardware::gnss::common::Utils;
+using ReplayUtils = ::android::hardware::gnss::common::ReplayUtils;
+using GnssRawMeasurementParser = ::android::hardware::gnss::common::GnssRawMeasurementParser;
+using DeviceFileReader = ::android::hardware::gnss::common::DeviceFileReader;
 
 std::shared_ptr<IGnssMeasurementCallback> GnssMeasurementInterface::sCallback = nullptr;
 
@@ -63,9 +69,22 @@
     mIsActive = true;
     mThread = std::thread([this, enableCorrVecOutputs]() {
         while (mIsActive == true) {
-            auto measurement = Utils::getMockMeasurement(enableCorrVecOutputs);
-            this->reportMeasurement(measurement);
-
+            std::string rawMeasurementStr = "";
+            if (ReplayUtils::hasGnssDeviceFile() &&
+                ReplayUtils::isGnssRawMeasurement(
+                        rawMeasurementStr =
+                                DeviceFileReader::Instance().getGnssRawMeasurementData())) {
+                ALOGD("rawMeasurementStr(size: %zu) from device file: %s", rawMeasurementStr.size(),
+                      rawMeasurementStr.c_str());
+                auto measurement =
+                        GnssRawMeasurementParser::getMeasurementFromStrs(rawMeasurementStr);
+                if (measurement != nullptr) {
+                    this->reportMeasurement(*measurement);
+                }
+            } else {
+                auto measurement = Utils::getMockMeasurement(enableCorrVecOutputs);
+                this->reportMeasurement(measurement);
+            }
             std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMillis));
         }
     });
diff --git a/gnss/common/utils/default/Android.bp b/gnss/common/utils/default/Android.bp
index a1d3123..dda8a44 100644
--- a/gnss/common/utils/default/Android.bp
+++ b/gnss/common/utils/default/Android.bp
@@ -38,9 +38,14 @@
         "v2_1/GnssDebug.cpp",
         "v2_1/GnssMeasurement.cpp",
         "v2_1/GnssMeasurementCorrections.cpp",
+        "DeviceFileReader.cpp",
+        "FixLocationParser.cpp",
+        "GnssRawMeasurementParser.cpp",
+        "GnssReplayUtils.cpp",
         "MockLocation.cpp",
-        "Utils.cpp",
         "NmeaFixInfo.cpp",
+        "ParseUtils.cpp",
+        "Utils.cpp",
     ],
     export_include_dirs: ["include"],
     shared_libs: [
diff --git a/gnss/common/utils/default/DeviceFileReader.cpp b/gnss/common/utils/default/DeviceFileReader.cpp
new file mode 100644
index 0000000..dfc086a
--- /dev/null
+++ b/gnss/common/utils/default/DeviceFileReader.cpp
@@ -0,0 +1,109 @@
+/*
+ * 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 "DeviceFileReader.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace common {
+
+void DeviceFileReader::getDataFromDeviceFile(const std::string& command, int mMinIntervalMs) {
+    char inputBuffer[INPUT_BUFFER_SIZE];
+    std::string deviceFilePath = "";
+    if (command == CMD_GET_LOCATION) {
+        deviceFilePath = ReplayUtils::getFixedLocationPath();
+    } else if (command == CMD_GET_RAWMEASUREMENT) {
+        deviceFilePath = ReplayUtils::getGnssPath();
+    } else {
+        // Invalid command
+        return;
+    }
+
+    int mGnssFd = open(deviceFilePath.c_str(), O_RDWR | O_NONBLOCK);
+
+    if (mGnssFd == -1) {
+        return;
+    }
+
+    int bytes_write = write(mGnssFd, command.c_str(), command.size());
+    if (bytes_write <= 0) {
+        close(mGnssFd);
+        return;
+    }
+
+    struct epoll_event ev, events[1];
+    ev.data.fd = mGnssFd;
+    ev.events = EPOLLIN;
+    int epoll_fd = epoll_create1(0);
+    epoll_ctl(epoll_fd, EPOLL_CTL_ADD, mGnssFd, &ev);
+    int bytes_read = -1;
+    std::string inputStr = "";
+    int epoll_ret = epoll_wait(epoll_fd, events, 1, mMinIntervalMs);
+
+    if (epoll_ret == -1) {
+        close(mGnssFd);
+        return;
+    }
+    while (true) {
+        memset(inputBuffer, 0, INPUT_BUFFER_SIZE);
+        bytes_read = read(mGnssFd, &inputBuffer, INPUT_BUFFER_SIZE);
+        if (bytes_read <= 0) {
+            break;
+        }
+        s_buffer_ += std::string(inputBuffer, bytes_read);
+    }
+    close(mGnssFd);
+
+    // Trim end of file mark(\n\n\n\n).
+    auto pos = s_buffer_.find("\n\n\n\n");
+    if (pos != std::string::npos) {
+        inputStr = s_buffer_.substr(0, pos);
+        s_buffer_ = s_buffer_.substr(pos + 4);
+    } else {
+        return;
+    }
+
+    // Cache the injected data.
+    if (command == CMD_GET_LOCATION) {
+        // TODO validate data
+        data_[CMD_GET_LOCATION] = inputStr;
+    } else if (command == CMD_GET_RAWMEASUREMENT) {
+        if (ReplayUtils::isGnssRawMeasurement(inputStr)) {
+            data_[CMD_GET_RAWMEASUREMENT] = inputStr;
+        }
+    }
+}
+
+std::string DeviceFileReader::getLocationData() {
+    std::unique_lock<std::mutex> lock(mMutex);
+    getDataFromDeviceFile(CMD_GET_LOCATION, 20);
+    return data_[CMD_GET_LOCATION];
+}
+
+std::string DeviceFileReader::getGnssRawMeasurementData() {
+    std::unique_lock<std::mutex> lock(mMutex);
+    getDataFromDeviceFile(CMD_GET_RAWMEASUREMENT, 20);
+    return data_[CMD_GET_RAWMEASUREMENT];
+}
+
+DeviceFileReader::DeviceFileReader() {}
+
+DeviceFileReader::~DeviceFileReader() {}
+
+}  // namespace common
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
diff --git a/gnss/common/utils/default/FixLocationParser.cpp b/gnss/common/utils/default/FixLocationParser.cpp
new file mode 100644
index 0000000..f0177b4
--- /dev/null
+++ b/gnss/common/utils/default/FixLocationParser.cpp
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2022 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 "FixLocationParser.h"
+
+#include <android/hardware/gnss/1.0/IGnss.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace common {
+
+std::unique_ptr<V2_0::GnssLocation> FixLocationParser::getLocationFromInputStr(
+        const std::string& locationStr) {
+    /*
+     * Fix,Provider,LatitudeDegrees,LongitudeDegrees,AltitudeMeters,SpeedMps,
+     * AccuracyMeters,BearingDegrees,UnixTimeMillis,SpeedAccuracyMps,BearingAccuracyDegrees,
+     * elapsedRealtimeNanos
+     */
+    if (locationStr.empty()) {
+        return nullptr;
+    }
+    std::vector<std::string> locationStrRecords;
+    ParseUtils::splitStr(locationStr, LINE_SEPARATOR, locationStrRecords);
+    if (locationStrRecords.empty()) {
+        return nullptr;
+    }
+
+    std::vector<std::string> locationValues;
+    ParseUtils::splitStr(locationStrRecords[0], COMMA_SEPARATOR, locationValues);
+    if (locationValues.size() < 12) {
+        return nullptr;
+    }
+    V2_0::ElapsedRealtime elapsedRealtime = {
+            .flags = V2_0::ElapsedRealtimeFlags::HAS_TIMESTAMP_NS |
+                     V2_0::ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS,
+            .timestampNs = static_cast<uint64_t>(::android::elapsedRealtimeNano()),
+            // This is an hardcoded value indicating a 1ms of uncertainty between the two clocks.
+            // In an actual implementation provide an estimate of the synchronization uncertainty
+            // or don't set the field.
+            .timeUncertaintyNs = 1020400};
+
+    V1_0::GnssLocation locationV1 = {
+            .gnssLocationFlags = 0xFF,
+            .latitudeDegrees = ParseUtils::tryParseDouble(locationValues[2], 0),
+            .longitudeDegrees = ParseUtils::tryParseDouble(locationValues[3], 0),
+            .altitudeMeters = ParseUtils::tryParseDouble(locationValues[4], 0),
+            .speedMetersPerSec = ParseUtils::tryParsefloat(locationValues[5], 0),
+            .bearingDegrees = ParseUtils::tryParsefloat(locationValues[7], 0),
+            .horizontalAccuracyMeters = ParseUtils::tryParsefloat(locationValues[6], 0),
+            .verticalAccuracyMeters = ParseUtils::tryParsefloat(locationValues[6], 0),
+            .speedAccuracyMetersPerSecond = ParseUtils::tryParsefloat(locationValues[9], 0),
+            .bearingAccuracyDegrees = ParseUtils::tryParsefloat(locationValues[10], 0),
+            .timestamp = ParseUtils::tryParseLongLong(locationValues[8], 0)};
+
+    V2_0::GnssLocation locationV2 = {.v1_0 = locationV1, .elapsedRealtime = elapsedRealtime};
+    return std::make_unique<V2_0::GnssLocation>(locationV2);
+}
+
+}  // namespace common
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
diff --git a/gnss/common/utils/default/GnssRawMeasurementParser.cpp b/gnss/common/utils/default/GnssRawMeasurementParser.cpp
new file mode 100644
index 0000000..c066229
--- /dev/null
+++ b/gnss/common/utils/default/GnssRawMeasurementParser.cpp
@@ -0,0 +1,305 @@
+/*
+ * 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 "GnssRawMeasurementParser.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace common {
+
+using aidl::android::hardware::gnss::ElapsedRealtime;
+using aidl::android::hardware::gnss::GnssClock;
+using aidl::android::hardware::gnss::GnssConstellationType;
+using aidl::android::hardware::gnss::GnssData;
+using aidl::android::hardware::gnss::GnssMeasurement;
+using aidl::android::hardware::gnss::GnssMultipathIndicator;
+using aidl::android::hardware::gnss::GnssSignalType;
+
+using ParseUtils = ::android::hardware::gnss::common::ParseUtils;
+
+std::unordered_map<std::string, int> GnssRawMeasurementParser::getColumnIdNameMappingFromHeader(
+        const std::string& header) {
+    std::vector<std::string> columnNames;
+    std::unordered_map<std::string, int> columnNameIdMapping;
+    std::string s = header;
+    // Trim left spaces
+    s.erase(s.begin(),
+            std::find_if(s.begin(), s.end(), [](unsigned char ch) { return !std::isspace(ch); }));
+    // Trim right spaces
+    s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char ch) { return !std::isspace(ch); })
+                    .base(),
+            s.end());
+    // Remove comment symbol, start from `Raw`.
+    s = s.substr(s.find("Raw"));
+
+    ParseUtils::splitStr(s, COMMA_SEPARATOR, columnNames);
+    int columnId = 0;
+    for (auto& name : columnNames) {
+        columnNameIdMapping[name] = columnId++;
+    }
+
+    return columnNameIdMapping;
+}
+
+int GnssRawMeasurementParser::getClockFlags(
+        const std::vector<std::string>& rawMeasurementRecordValues,
+        const std::unordered_map<std::string, int>& columnNameIdMapping) {
+    int clockFlags = 0;
+    if (!rawMeasurementRecordValues[columnNameIdMapping.at("LeapSecond")].empty()) {
+        clockFlags |= GnssClock::HAS_LEAP_SECOND;
+    }
+    if (!rawMeasurementRecordValues[columnNameIdMapping.at("FullBiasNanos")].empty()) {
+        clockFlags |= GnssClock::HAS_FULL_BIAS;
+    }
+    if (!rawMeasurementRecordValues[columnNameIdMapping.at("BiasNanos")].empty()) {
+        clockFlags |= GnssClock::HAS_BIAS;
+    }
+    if (!rawMeasurementRecordValues[columnNameIdMapping.at("BiasUncertaintyNanos")].empty()) {
+        clockFlags |= GnssClock::HAS_BIAS_UNCERTAINTY;
+    }
+    if (!rawMeasurementRecordValues[columnNameIdMapping.at("DriftNanosPerSecond")].empty()) {
+        clockFlags |= GnssClock::HAS_DRIFT;
+    }
+    if (!rawMeasurementRecordValues[columnNameIdMapping.at("DriftUncertaintyNanosPerSecond")]
+                 .empty()) {
+        clockFlags |= GnssClock::HAS_DRIFT_UNCERTAINTY;
+    }
+    return clockFlags;
+}
+
+int GnssRawMeasurementParser::getElapsedRealtimeFlags(
+        const std::vector<std::string>& rawMeasurementRecordValues,
+        const std::unordered_map<std::string, int>& columnNameIdMapping) {
+    int elapsedRealtimeFlags = ElapsedRealtime::HAS_TIMESTAMP_NS;
+    if (!rawMeasurementRecordValues[columnNameIdMapping.at("TimeUncertaintyNanos")].empty()) {
+        elapsedRealtimeFlags |= ElapsedRealtime::HAS_TIME_UNCERTAINTY_NS;
+    }
+    return elapsedRealtimeFlags;
+}
+
+int GnssRawMeasurementParser::getRawMeasurementFlags(
+        const std::vector<std::string>& rawMeasurementRecordValues,
+        const std::unordered_map<std::string, int>& columnNameIdMapping) {
+    int rawMeasurementFlags = 0;
+    if (!rawMeasurementRecordValues[columnNameIdMapping.at("SnrInDb")].empty()) {
+        rawMeasurementFlags |= GnssMeasurement::HAS_SNR;
+    }
+    if (!rawMeasurementRecordValues[columnNameIdMapping.at("CarrierFrequencyHz")].empty()) {
+        rawMeasurementFlags |= GnssMeasurement::HAS_CARRIER_FREQUENCY;
+    }
+    if (!rawMeasurementRecordValues[columnNameIdMapping.at("CarrierCycles")].empty()) {
+        rawMeasurementFlags |= GnssMeasurement::HAS_CARRIER_CYCLES;
+    }
+    if (!rawMeasurementRecordValues[columnNameIdMapping.at("CarrierPhase")].empty()) {
+        rawMeasurementFlags |= GnssMeasurement::HAS_CARRIER_PHASE;
+    }
+    if (!rawMeasurementRecordValues[columnNameIdMapping.at("CarrierPhaseUncertainty")].empty()) {
+        rawMeasurementFlags |= GnssMeasurement::HAS_CARRIER_PHASE_UNCERTAINTY;
+    }
+    if (!rawMeasurementRecordValues[columnNameIdMapping.at("AgcDb")].empty()) {
+        rawMeasurementFlags |= GnssMeasurement::HAS_AUTOMATIC_GAIN_CONTROL;
+    }
+    if (!rawMeasurementRecordValues[columnNameIdMapping.at("FullInterSignalBiasNanos")].empty()) {
+        rawMeasurementFlags |= GnssMeasurement::HAS_FULL_ISB;
+    }
+    if (!rawMeasurementRecordValues[columnNameIdMapping.at("FullInterSignalBiasUncertaintyNanos")]
+                 .empty()) {
+        rawMeasurementFlags |= GnssMeasurement::HAS_FULL_ISB_UNCERTAINTY;
+    }
+    if (!rawMeasurementRecordValues[columnNameIdMapping.at("SatelliteInterSignalBiasNanos")]
+                 .empty()) {
+        rawMeasurementFlags |= GnssMeasurement::HAS_SATELLITE_ISB;
+    }
+    if (!rawMeasurementRecordValues[columnNameIdMapping.at(
+                                            "SatelliteInterSignalBiasUncertaintyNanos")]
+                 .empty()) {
+        rawMeasurementFlags |= GnssMeasurement::HAS_SATELLITE_ISB_UNCERTAINTY;
+    }
+    // HAS_SATELLITE_PVT and HAS_CORRELATION_VECTOR fields currently not in rawmeasurement
+    // output, need add them later.
+    return rawMeasurementFlags;
+}
+
+GnssConstellationType GnssRawMeasurementParser::getGnssConstellationType(int constellationType) {
+    GnssConstellationType gnssConstellationType =
+            aidl::android::hardware::gnss::GnssConstellationType::UNKNOWN;
+
+    switch (constellationType) {
+        case 1:
+            gnssConstellationType = aidl::android::hardware::gnss::GnssConstellationType::GPS;
+            break;
+        case 2:
+            gnssConstellationType = aidl::android::hardware::gnss::GnssConstellationType::SBAS;
+            break;
+        case 3:
+            gnssConstellationType = aidl::android::hardware::gnss::GnssConstellationType::GLONASS;
+            break;
+        case 4:
+            gnssConstellationType = aidl::android::hardware::gnss::GnssConstellationType::QZSS;
+            break;
+        case 5:
+            gnssConstellationType = aidl::android::hardware::gnss::GnssConstellationType::BEIDOU;
+            break;
+        case 6:
+            gnssConstellationType = aidl::android::hardware::gnss::GnssConstellationType::GALILEO;
+            break;
+        default:
+            gnssConstellationType = aidl::android::hardware::gnss::GnssConstellationType::UNKNOWN;
+    }
+
+    return gnssConstellationType;
+}
+
+std::unique_ptr<GnssData> GnssRawMeasurementParser::getMeasurementFromStrs(
+        std::string& rawMeasurementStr) {
+    /*
+     * Raw,utcTimeMillis,TimeNanos,LeapSecond,TimeUncertaintyNanos,FullBiasNanos,BiasNanos,
+     * BiasUncertaintyNanos,DriftNanosPerSecond,DriftUncertaintyNanosPerSecond,
+     * HardwareClockDiscontinuityCount,Svid,TimeOffsetNanos,State,ReceivedSvTimeNanos,
+     * ReceivedSvTimeUncertaintyNanos,Cn0DbHz,PseudorangeRateMetersPerSecond,
+     * PseudorangeRateUncertaintyMetersPerSecond,AccumulatedDeltaRangeState,
+     * AccumulatedDeltaRangeMeters,AccumulatedDeltaRangeUncertaintyMeters,CarrierFrequencyHz,
+     * CarrierCycles,CarrierPhase,CarrierPhaseUncertainty,MultipathIndicator,SnrInDb,
+     * ConstellationType,AgcDb,BasebandCn0DbHz,FullInterSignalBiasNanos,
+     * FullInterSignalBiasUncertaintyNanos,SatelliteInterSignalBiasNanos,
+     * SatelliteInterSignalBiasUncertaintyNanos,CodeType,ChipsetElapsedRealtimeNanos
+     */
+    ALOGD("Parsing %zu bytes rawMeasurementStr.", rawMeasurementStr.size());
+    if (rawMeasurementStr.empty()) {
+        return nullptr;
+    }
+    std::vector<std::string> rawMeasurementStrRecords;
+    ParseUtils::splitStr(rawMeasurementStr, LINE_SEPARATOR, rawMeasurementStrRecords);
+    if (rawMeasurementStrRecords.size() <= 1) {
+        ALOGE("Raw GNSS Measurements parser failed. (No records) ");
+        return nullptr;
+    }
+
+    // Get the column name mapping from the header.
+    std::unordered_map<std::string, int> columnNameIdMapping =
+            getColumnIdNameMappingFromHeader(rawMeasurementStrRecords[0]);
+
+    if (columnNameIdMapping.size() < 37 || !ParseUtils::isValidHeader(columnNameIdMapping)) {
+        ALOGE("Raw GNSS Measurements parser failed. (No header or missing columns.) ");
+        return nullptr;
+    }
+
+    // Set GnssClock from 1st record.
+    std::size_t pointer = 1;
+    std::vector<std::string> firstRecordValues;
+    ParseUtils::splitStr(rawMeasurementStrRecords[pointer], COMMA_SEPARATOR, firstRecordValues);
+    GnssClock clock = {
+            .gnssClockFlags = getClockFlags(firstRecordValues, columnNameIdMapping),
+            .timeNs = ParseUtils::tryParseLongLong(
+                    firstRecordValues[columnNameIdMapping.at("TimeNanos")], 0),
+            .fullBiasNs = ParseUtils::tryParseLongLong(
+                    firstRecordValues[columnNameIdMapping.at("FullBiasNanos")], 0),
+            .biasNs = ParseUtils::tryParseDouble(
+                    firstRecordValues[columnNameIdMapping.at("BiasNanos")], 0),
+            .biasUncertaintyNs = ParseUtils::tryParseDouble(
+                    firstRecordValues[columnNameIdMapping.at("BiasUncertaintyNanos")], 0),
+            .driftNsps = ParseUtils::tryParseDouble(
+                    firstRecordValues[columnNameIdMapping.at("DriftNanosPerSecond")], 0),
+            .driftUncertaintyNsps = ParseUtils::tryParseDouble(
+                    firstRecordValues[columnNameIdMapping.at("DriftNanosPerSecond")], 0),
+            .hwClockDiscontinuityCount = ParseUtils::tryParseInt(
+                    firstRecordValues[columnNameIdMapping.at("HardwareClockDiscontinuityCount")],
+                    0)};
+
+    ElapsedRealtime timestamp = {
+            .flags = getElapsedRealtimeFlags(firstRecordValues, columnNameIdMapping),
+            .timestampNs = ParseUtils::tryParseLongLong(
+                    firstRecordValues[columnNameIdMapping.at("ChipsetElapsedRealtimeNanos")]),
+            .timeUncertaintyNs = ParseUtils::tryParseDouble(
+                    firstRecordValues[columnNameIdMapping.at("TimeUncertaintyNanos")], 0)};
+
+    std::vector<GnssMeasurement> measurementsVec;
+    for (pointer = 1; pointer < rawMeasurementStrRecords.size(); pointer++) {
+        std::vector<std::string> rawMeasurementValues;
+        std::string line = rawMeasurementStrRecords[pointer];
+        ParseUtils::splitStr(line, COMMA_SEPARATOR, rawMeasurementValues);
+        GnssSignalType signalType = {
+                .constellation = getGnssConstellationType(ParseUtils::tryParseInt(
+                        rawMeasurementValues[columnNameIdMapping.at("ConstellationType")], 0)),
+                .carrierFrequencyHz = ParseUtils::tryParseDouble(
+                        rawMeasurementValues[columnNameIdMapping.at("CarrierFrequencyHz")], 0),
+                .codeType = rawMeasurementValues[columnNameIdMapping.at("CodeType")],
+        };
+        GnssMeasurement measurement = {
+                .flags = getRawMeasurementFlags(rawMeasurementValues, columnNameIdMapping),
+                .svid = ParseUtils::tryParseInt(
+                        rawMeasurementValues[columnNameIdMapping.at("Svid")], 0),
+                .signalType = signalType,
+                .receivedSvTimeInNs = ParseUtils::tryParseLongLong(
+                        rawMeasurementValues[columnNameIdMapping.at("ReceivedSvTimeNanos")], 0),
+                .receivedSvTimeUncertaintyInNs =
+                        ParseUtils::tryParseLongLong(rawMeasurementValues[columnNameIdMapping.at(
+                                                             "ReceivedSvTimeUncertaintyNanos")],
+                                                     0),
+                .antennaCN0DbHz = ParseUtils::tryParseDouble(
+                        rawMeasurementValues[columnNameIdMapping.at("Cn0DbHz")], 0),
+                .basebandCN0DbHz = ParseUtils::tryParseDouble(
+                        rawMeasurementValues[columnNameIdMapping.at("BasebandCn0DbHz")], 0),
+                .agcLevelDb = ParseUtils::tryParseDouble(
+                        rawMeasurementValues[columnNameIdMapping.at("AgcDb")], 0),
+                .pseudorangeRateMps =
+                        ParseUtils::tryParseDouble(rawMeasurementValues[columnNameIdMapping.at(
+                                                           "PseudorangeRateMetersPerSecond")],
+                                                   0),
+                .pseudorangeRateUncertaintyMps = ParseUtils::tryParseDouble(
+                        rawMeasurementValues[columnNameIdMapping.at(
+                                "PseudorangeRateUncertaintyMetersPerSecond")],
+                        0),
+                .accumulatedDeltaRangeState = ParseUtils::tryParseInt(
+                        rawMeasurementValues[columnNameIdMapping.at("AccumulatedDeltaRangeState")],
+                        0),
+                .accumulatedDeltaRangeM = ParseUtils::tryParseDouble(
+                        rawMeasurementValues[columnNameIdMapping.at("AccumulatedDeltaRangeMeters")],
+                        0),
+                .accumulatedDeltaRangeUncertaintyM = ParseUtils::tryParseDouble(
+                        rawMeasurementValues[columnNameIdMapping.at(
+                                "AccumulatedDeltaRangeUncertaintyMeters")],
+                        0),
+                .multipathIndicator = GnssMultipathIndicator::UNKNOWN,  // Not in GnssLogger yet.
+                .state = ParseUtils::tryParseInt(
+                        rawMeasurementValues[columnNameIdMapping.at("State")], 0),
+                .fullInterSignalBiasNs = ParseUtils::tryParseDouble(rawMeasurementValues[31], 0),
+                .fullInterSignalBiasUncertaintyNs = ParseUtils::tryParseDouble(
+                        rawMeasurementValues[columnNameIdMapping.at("FullInterSignalBiasNanos")],
+                        0),
+                .satelliteInterSignalBiasNs =
+                        ParseUtils::tryParseDouble(rawMeasurementValues[columnNameIdMapping.at(
+                                                           "SatelliteInterSignalBiasNanos")],
+                                                   0),
+                .satelliteInterSignalBiasUncertaintyNs = ParseUtils::tryParseDouble(
+                        rawMeasurementValues[columnNameIdMapping.at(
+                                "SatelliteInterSignalBiasUncertaintyNanos")],
+                        0),
+                .satellitePvt = {},
+                .correlationVectors = {}};
+        measurementsVec.push_back(measurement);
+    }
+
+    GnssData gnssData = {
+            .measurements = measurementsVec, .clock = clock, .elapsedRealtime = timestamp};
+    return std::make_unique<GnssData>(gnssData);
+}
+
+}  // namespace common
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
diff --git a/gnss/common/utils/default/GnssReplayUtils.cpp b/gnss/common/utils/default/GnssReplayUtils.cpp
new file mode 100644
index 0000000..d6769bd
--- /dev/null
+++ b/gnss/common/utils/default/GnssReplayUtils.cpp
@@ -0,0 +1,81 @@
+/*
+ * 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 "GnssReplayUtils.h"
+
+#include <array>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace common {
+
+std::string ReplayUtils::getGnssPath() {
+    std::array<char, PROPERTY_VALUE_MAX> devname_value;
+
+    devname_value.fill(0);
+    if (property_get("debug.location.gnss.devname", devname_value.begin(), NULL) > 0) {
+        return devname_value.begin();
+    }
+
+    devname_value.fill(0);
+    if (property_get("vendor.ser.gnss-uart", devname_value.begin(), NULL) > 0) {
+        return devname_value.begin();
+    }
+
+    return GNSS_PATH;
+}
+
+std::string ReplayUtils::getFixedLocationPath() {
+    std::array<char, PROPERTY_VALUE_MAX> devname_value;
+
+    devname_value.fill(0);
+    if (property_get("debug.location.fixedlocation.devname", devname_value.begin(), NULL) > 0) {
+        return devname_value.begin();
+    }
+
+    devname_value.fill(0);
+    if (property_get("vendor.ser.gnss-uart", devname_value.begin(), NULL) > 0) {
+        return devname_value.begin();
+    }
+
+    return FIXED_LOCATION_PATH;
+}
+
+bool ReplayUtils::hasGnssDeviceFile() {
+    struct stat sb;
+    return stat(getGnssPath().c_str(), &sb) != -1;
+}
+
+bool ReplayUtils::hasFixedLocationDeviceFile() {
+    struct stat sb;
+    return stat(getFixedLocationPath().c_str(), &sb) != -1;
+}
+
+bool ReplayUtils::isGnssRawMeasurement(const std::string& inputStr) {
+    // TODO: add more logic check to by pass invalid data.
+    return !inputStr.empty() && (inputStr.find("Raw") != std::string::npos);
+}
+
+bool ReplayUtils::isNMEA(const std::string& inputStr) {
+    return !inputStr.empty() && (inputStr.find("$GPRMC,", 0) != std::string::npos ||
+                                 inputStr.find("$GPRMA,", 0) != std::string::npos);
+}
+
+}  // namespace common
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
diff --git a/gnss/common/utils/default/ParseUtils.cpp b/gnss/common/utils/default/ParseUtils.cpp
new file mode 100644
index 0000000..648edf7
--- /dev/null
+++ b/gnss/common/utils/default/ParseUtils.cpp
@@ -0,0 +1,127 @@
+/*
+ * 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 <ParseUtils.h>
+#include <sstream>
+#include <stdexcept>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace common {
+
+int ParseUtils::tryParseInt(const std::string& s, int defaultVal) {
+    if (s.empty()) {
+        return defaultVal;
+    } else {
+        return std::stoi(s);
+    }
+}
+
+float ParseUtils::tryParsefloat(const std::string& s, float defaultVal) {
+    if (s.empty()) {
+        return defaultVal;
+    } else {
+        return std::stof(s);
+    }
+}
+
+double ParseUtils::tryParseDouble(const std::string& s, double defaultVal) {
+    if (s.empty()) {
+        return defaultVal;
+    } else {
+        return std::stod(s);
+    }
+}
+
+long ParseUtils::tryParseLong(const std::string& s, long defaultVal) {
+    if (s.empty()) {
+        return defaultVal;
+    } else {
+        return std::stol(s);
+    }
+}
+
+long long ParseUtils::tryParseLongLong(const std::string& s, long long defaultVal) {
+    if (s.empty()) {
+        return defaultVal;
+    } else {
+        return std::stoll(s);
+    }
+}
+
+void ParseUtils::splitStr(const std::string& line, const char& delimiter,
+                          std::vector<std::string>& out) {
+    std::istringstream iss(line);
+    std::string item;
+    while (std::getline(iss, item, delimiter)) {
+        out.push_back(item);
+    }
+}
+
+bool ParseUtils::isValidHeader(const std::unordered_map<std::string, int>& columnNameIdMapping) {
+    std::vector<std::string> requiredHeaderColumns = {"Raw",
+                                                      "utcTimeMillis",
+                                                      "TimeNanos",
+                                                      "LeapSecond",
+                                                      "TimeUncertaintyNanos",
+                                                      "FullBiasNanos",
+                                                      "BiasNanos",
+                                                      "BiasUncertaintyNanos",
+                                                      "DriftNanosPerSecond",
+                                                      "DriftUncertaintyNanosPerSecond",
+                                                      "HardwareClockDiscontinuityCount",
+                                                      "Svid",
+                                                      "TimeOffsetNanos",
+                                                      "State",
+                                                      "ReceivedSvTimeNanos",
+                                                      "ReceivedSvTimeUncertaintyNanos",
+                                                      "Cn0DbHz",
+                                                      "PseudorangeRateMetersPerSecond",
+                                                      "PseudorangeRateUncertaintyMetersPerSecond",
+                                                      "AccumulatedDeltaRangeState",
+                                                      "AccumulatedDeltaRangeMeters",
+                                                      "AccumulatedDeltaRangeUncertaintyMeters",
+                                                      "CarrierFrequencyHz",
+                                                      "CarrierCycles",
+                                                      "CarrierPhase",
+                                                      "CarrierPhaseUncertainty",
+                                                      "MultipathIndicator",
+                                                      "SnrInDb",
+                                                      "ConstellationType",
+                                                      "AgcDb",
+                                                      "BasebandCn0DbHz",
+                                                      "FullInterSignalBiasNanos",
+                                                      "FullInterSignalBiasUncertaintyNanos",
+                                                      "SatelliteInterSignalBiasNanos",
+                                                      "SatelliteInterSignalBiasUncertaintyNanos",
+                                                      "CodeType",
+                                                      "ChipsetElapsedRealtimeNanos"};
+
+    for (const auto& columnName : requiredHeaderColumns) {
+        if (columnNameIdMapping.find(columnName) == columnNameIdMapping.end()) {
+            ALOGE("Missing column %s in header.", columnName.c_str());
+            return false;
+        }
+    }
+
+    return true;
+}
+
+}  // namespace common
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
diff --git a/gnss/common/utils/default/include/Constants.h b/gnss/common/utils/default/include/Constants.h
index 22afee1..489413e 100644
--- a/gnss/common/utils/default/include/Constants.h
+++ b/gnss/common/utils/default/include/Constants.h
@@ -34,6 +34,19 @@
 const float kGloG1FreqHz = 1602.0 * 1e6;
 const float kIrnssL5FreqHz = 1176.45 * 1e6;
 
+// Location replay constants
+constexpr char GNSS_PATH[] = "/dev/gnss0";
+constexpr char FIXED_LOCATION_PATH[] = "/dev/gnss1";
+constexpr int INPUT_BUFFER_SIZE = 256;
+constexpr char CMD_GET_LOCATION[] = "CMD_GET_LOCATION";
+constexpr char CMD_GET_RAWMEASUREMENT[] = "CMD_GET_RAWMEASUREMENT";
+constexpr char LINE_SEPARATOR = '\n';
+constexpr char COMMA_SEPARATOR = ',';
+constexpr char GPGA_RECORD_TAG[] = "$GPGGA";
+constexpr char GPRMC_RECORD_TAG[] = "$GPRMC";
+constexpr double TIMESTAMP_EPSILON = 0.001;
+constexpr int MIN_COL_NUM = 13;
+
 }  // namespace common
 }  // namespace gnss
 }  // namespace hardware
diff --git a/gnss/common/utils/default/include/DeviceFileReader.h b/gnss/common/utils/default/include/DeviceFileReader.h
new file mode 100644
index 0000000..c2a5c5f
--- /dev/null
+++ b/gnss/common/utils/default/include/DeviceFileReader.h
@@ -0,0 +1,53 @@
+
+/*
+ * 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.
+ */
+#ifndef android_hardware_gnss_common_default_DeviceFileReader_H_
+#define android_hardware_gnss_common_default_DeviceFileReader_H_
+
+#include <log/log.h>
+#include <mutex>
+#include <string>
+#include <unordered_map>
+#include "Constants.h"
+#include "GnssReplayUtils.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace common {
+class DeviceFileReader {
+  public:
+    static DeviceFileReader& Instance() {
+        static DeviceFileReader reader;
+        return reader;
+    }
+    std::string getLocationData();
+    std::string getGnssRawMeasurementData();
+    void getDataFromDeviceFile(const std::string& command, int mMinIntervalMs);
+
+  private:
+    DeviceFileReader();
+    ~DeviceFileReader();
+    std::unordered_map<std::string, std::string> data_;
+    std::string s_buffer_;
+    std::mutex mMutex;
+};
+}  // namespace common
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
+
+#endif  // android_hardware_gnss_common_default_DeviceFileReader_H_
\ No newline at end of file
diff --git a/gnss/common/utils/default/include/FixLocationParser.h b/gnss/common/utils/default/include/FixLocationParser.h
new file mode 100644
index 0000000..19748a9
--- /dev/null
+++ b/gnss/common/utils/default/include/FixLocationParser.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef android_hardware_gnss_common_default_FixLocationParser_H_
+#define android_hardware_gnss_common_default_FixLocationParser_H_
+
+#include <android/hardware/gnss/2.0/IGnss.h>
+
+#include <utils/SystemClock.h>
+#include <string>
+#include <vector>
+
+#include <Constants.h>
+#include <Utils.h>
+#include <log/log.h>
+#include "Constants.h"
+#include "ParseUtils.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace common {
+
+struct FixLocationParser {
+  public:
+    static std::unique_ptr<V2_0::GnssLocation> getLocationFromInputStr(const std::string& inputStr);
+};
+
+}  // namespace common
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
+
+#endif  // android_hardware_gnss_common_default_FixLocationParser_H_
diff --git a/gnss/common/utils/default/include/GnssRawMeasurementParser.h b/gnss/common/utils/default/include/GnssRawMeasurementParser.h
new file mode 100644
index 0000000..7d6b4ef
--- /dev/null
+++ b/gnss/common/utils/default/include/GnssRawMeasurementParser.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef android_hardware_gnss_common_default_GnssRawMeasurementParser_H_
+#define android_hardware_gnss_common_default_GnssRawMeasurementParser_H_
+
+#include <aidl/android/hardware/gnss/BnGnss.h>
+#include <log/log.h>
+#include <utils/SystemClock.h>
+#include <string>
+#include <unordered_map>
+
+#include "Constants.h"
+#include "ParseUtils.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace common {
+
+struct GnssRawMeasurementParser {
+    static std::unique_ptr<aidl::android::hardware::gnss::GnssData> getMeasurementFromStrs(
+            std::string& rawMeasurementStr);
+    static int getClockFlags(const std::vector<std::string>& rawMeasurementRecordValues,
+                             const std::unordered_map<std::string, int>& columnNameIdMapping);
+    static int getElapsedRealtimeFlags(
+            const std::vector<std::string>& rawMeasurementRecordValues,
+            const std::unordered_map<std::string, int>& columnNameIdMapping);
+    static int getRawMeasurementFlags(
+            const std::vector<std::string>& rawMeasurementRecordValues,
+            const std::unordered_map<std::string, int>& columnNameIdMapping);
+    static std::unordered_map<std::string, int> getColumnIdNameMappingFromHeader(
+            const std::string& header);
+    static aidl::android::hardware::gnss::GnssConstellationType getGnssConstellationType(
+            int constellationType);
+};
+
+}  // namespace common
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
+
+#endif  // android_hardware_gnss_common_default_GnssRawMeasurementParser_H_
\ No newline at end of file
diff --git a/gnss/common/utils/default/include/GnssReplayUtils.h b/gnss/common/utils/default/include/GnssReplayUtils.h
new file mode 100644
index 0000000..d1bbed4
--- /dev/null
+++ b/gnss/common/utils/default/include/GnssReplayUtils.h
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ */
+
+#ifndef android_hardware_gnss_common_GnssReplayUtils_H_
+#define android_hardware_gnss_common_GnssReplayUtils_H_
+
+#include <cutils/properties.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <log/log.h>
+#include <sys/epoll.h>
+#include <sys/stat.h>
+#include <chrono>
+#include <string>
+#include <thread>
+
+#include "Constants.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace common {
+
+struct ReplayUtils {
+    static std::string getGnssPath();
+
+    static std::string getFixedLocationPath();
+
+    static std::string getDataFromDeviceFile(const std::string& command, int mMinIntervalMs);
+
+    static bool hasGnssDeviceFile();
+
+    static bool hasFixedLocationDeviceFile();
+
+    static bool isGnssRawMeasurement(const std::string& inputStr);
+
+    static bool isNMEA(const std::string& inputStr);
+};
+
+}  // namespace common
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
+
+#endif  // android_hardware_gnss_common_GnssReplayUtils_H_
diff --git a/gnss/common/utils/default/include/NmeaFixInfo.h b/gnss/common/utils/default/include/NmeaFixInfo.h
index c96eece..5c27045 100644
--- a/gnss/common/utils/default/include/NmeaFixInfo.h
+++ b/gnss/common/utils/default/include/NmeaFixInfo.h
@@ -27,13 +27,6 @@
 namespace gnss {
 namespace common {
 
-constexpr char GPGA_RECORD_TAG[] = "$GPGGA";
-constexpr char GPRMC_RECORD_TAG[] = "$GPRMC";
-constexpr char LINE_SEPARATOR = '\n';
-constexpr char COMMA_SEPARATOR = ',';
-constexpr double TIMESTAMP_EPSILON = 0.001;
-constexpr int MIN_COL_NUM = 13;
-
 /** Helper class to parse and store the GNSS fix details information. */
 class NmeaFixInfo {
   private:
diff --git a/gnss/common/utils/default/include/ParseUtils.h b/gnss/common/utils/default/include/ParseUtils.h
new file mode 100644
index 0000000..3a56313
--- /dev/null
+++ b/gnss/common/utils/default/include/ParseUtils.h
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+#ifndef android_hardware_gnss_common_default_ParseUtils_H_
+#define android_hardware_gnss_common_default_ParseUtils_H_
+
+#include <log/log.h>
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace common {
+
+struct ParseUtils {
+    static int tryParseInt(const std::string& s, int defaultVal = 0);
+    static float tryParsefloat(const std::string& s, float defaultVal = 0.0);
+    static double tryParseDouble(const std::string& s, double defaultVal = 0.0);
+    static long tryParseLong(const std::string& s, long defaultVal = 0);
+    static long long tryParseLongLong(const std::string& s, long long defaultVal = 0);
+    static void splitStr(const std::string& line, const char& delimiter,
+                         std::vector<std::string>& out);
+    static bool isValidHeader(const std::unordered_map<std::string, int>& columnNameIdMapping);
+};
+
+}  // namespace common
+}  // namespace gnss
+}  // namespace hardware
+}  // namespace android
+
+#endif  // android_hardware_gnss_common_default_ParseUtils_H_
\ No newline at end of file
diff --git a/gnss/common/utils/default/include/v2_1/GnssTemplate.h b/gnss/common/utils/default/include/v2_1/GnssTemplate.h
index 48cab99..473e587 100644
--- a/gnss/common/utils/default/include/v2_1/GnssTemplate.h
+++ b/gnss/common/utils/default/include/v2_1/GnssTemplate.h
@@ -30,13 +30,15 @@
 
 #include <cutils/properties.h>
 
+#include "DeviceFileReader.h"
+#include "FixLocationParser.h"
 #include "GnssAntennaInfo.h"
 #include "GnssConfiguration.h"
 #include "GnssDebug.h"
 #include "GnssMeasurement.h"
 #include "GnssMeasurementCorrections.h"
+#include "GnssReplayUtils.h"
 #include "MockLocation.h"
-#include "NmeaFixInfo.h"
 #include "Utils.h"
 
 namespace android::hardware::gnss::common::implementation {
@@ -159,53 +161,13 @@
 
 template <class T_IGnss>
 std::unique_ptr<V2_0::GnssLocation> GnssTemplate<T_IGnss>::getLocationFromHW() {
-    char inputBuffer[INPUT_BUFFER_SIZE];
-    if (!mHardwareModeChecked) {
-        // default using gnss0
-        const char * gnss_dev_path = GNSS_PATH;
-        char devname_value[PROPERTY_VALUE_MAX] = "";
-        if (property_get("debug.location.gnss.devname", devname_value, NULL) > 0) {
-            gnss_dev_path = devname_value;
-            ALOGD("using %s instead of the default %s", gnss_dev_path, GNSS_PATH);
-        }
-
-        mGnssFd = open(gnss_dev_path, O_RDWR | O_NONBLOCK);
-        if (mGnssFd == -1) {
-            ALOGW("Failed to open %s errno: %d", gnss_dev_path, errno);
-        }
-        mHardwareModeChecked = true;
-    }
-
-    if (mGnssFd == -1) {
+    mHardwareModeChecked = true;
+    if (!ReplayUtils::hasFixedLocationDeviceFile()) {
         return nullptr;
     }
-
-    int bytes_write = write(mGnssFd, CMD_GET_LOCATION, strlen(CMD_GET_LOCATION));
-    if (bytes_write <= 0) {
-        return nullptr;
-    }
-
-    struct epoll_event ev, events[1];
-    ev.data.fd = mGnssFd;
-    ev.events = EPOLLIN;
-    int epoll_fd = epoll_create1(0);
-    epoll_ctl(epoll_fd, EPOLL_CTL_ADD, mGnssFd, &ev);
-    int bytes_read = -1;
-    std::string inputStr = "";
-    int epoll_ret = epoll_wait(epoll_fd, events, 1, mMinIntervalMs);
-
-    if (epoll_ret == -1) {
-        return nullptr;
-    }
-    while (true) {
-        memset(inputBuffer, 0, INPUT_BUFFER_SIZE);
-        bytes_read = read(mGnssFd, &inputBuffer, INPUT_BUFFER_SIZE);
-        if (bytes_read <= 0) {
-            break;
-        }
-        inputStr += std::string(inputBuffer, bytes_read);
-    }
-    return NmeaFixInfo::getLocationFromInputStr(inputStr);
+    std::string inputStr =
+            ::android::hardware::gnss::common::DeviceFileReader::Instance().getLocationData();
+    return FixLocationParser::getLocationFromInputStr(inputStr);
 }
 
 template <class T_IGnss>
diff --git a/graphics/composer/2.1/utils/hwc2on1adapter/Android.bp b/graphics/composer/2.1/utils/hwc2on1adapter/Android.bp
index 0171dd6..3527cca 100644
--- a/graphics/composer/2.1/utils/hwc2on1adapter/Android.bp
+++ b/graphics/composer/2.1/utils/hwc2on1adapter/Android.bp
@@ -25,7 +25,6 @@
     name: "libhwc2on1adapter",
     vendor: true,
 
-    clang: true,
     cflags: [
         "-Wall",
         "-Werror",
diff --git a/graphics/composer/2.1/utils/hwc2onfbadapter/Android.bp b/graphics/composer/2.1/utils/hwc2onfbadapter/Android.bp
index 3965d12..d613ba9 100644
--- a/graphics/composer/2.1/utils/hwc2onfbadapter/Android.bp
+++ b/graphics/composer/2.1/utils/hwc2onfbadapter/Android.bp
@@ -25,7 +25,6 @@
     name: "libhwc2onfbadapter",
     vendor: true,
 
-    clang: true,
     cflags: [
         "-Wall",
         "-Wextra",
@@ -37,6 +36,9 @@
     ],
 
     header_libs: ["libhardware_headers"],
-    shared_libs: ["liblog", "libsync"],
+    shared_libs: [
+        "liblog",
+        "libsync",
+    ],
     export_include_dirs: ["include"],
 }
diff --git a/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp b/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp
index f55a6b7..61277ee 100644
--- a/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp
+++ b/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp
@@ -2001,6 +2001,11 @@
               mGralloc->set(bufferHandle, gralloc4::MetadataType_Dataspace, vec));
     ASSERT_EQ(Error::UNSUPPORTED,
               mGralloc->set(bufferHandle, gralloc4::MetadataType_BlendMode, vec));
+
+    // Keep optional metadata types below and populate the encoded metadata vec
+    // with some arbitrary different metadata because the common gralloc4::decode*()
+    // functions do not distinguish between an empty vec and bad value.
+    ASSERT_EQ(NO_ERROR, gralloc4::encodeDataspace(Dataspace::SRGB_LINEAR, &vec));
     ASSERT_EQ(Error::UNSUPPORTED,
               mGralloc->set(bufferHandle, gralloc4::MetadataType_Smpte2086, vec));
     ASSERT_EQ(Error::UNSUPPORTED,
diff --git a/health/aidl/Android.bp b/health/aidl/Android.bp
index 86bca69..4acf38a 100644
--- a/health/aidl/Android.bp
+++ b/health/aidl/Android.bp
@@ -36,11 +36,6 @@
             enabled: true,
             sdk_version: "module_current",
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
     },
 }
 
diff --git a/health/aidl/OWNERS b/health/aidl/OWNERS
index cd06415..fcad499 100644
--- a/health/aidl/OWNERS
+++ b/health/aidl/OWNERS
@@ -1,2 +1,4 @@
 # Bug component: 30545
 elsk@google.com
+smoreland@google.com
+stayfan@google.com
diff --git a/health/aidl/default/Android.bp b/health/aidl/default/Android.bp
index 8eab997..0d426da 100644
--- a/health/aidl/default/Android.bp
+++ b/health/aidl/default/Android.bp
@@ -159,3 +159,70 @@
     init_rc: ["android.hardware.health-service.example_recovery.rc"],
     overrides: ["charger.recovery"],
 }
+
+// AIDL Fuzz version of libhealth2impl.
+cc_library_static {
+    name: "fuzz_libhealth_aidl_impl",
+    defaults: [
+        "libhealth_aidl_common_defaults",
+        "libhealth_aidl_charger_defaults",
+    ],
+    recovery_available: true,
+    export_include_dirs: ["include"],
+    export_static_lib_headers: [
+        "libbatterymonitor",
+    ],
+    srcs: [
+        "ChargerUtils.cpp",
+        "health-convert.cpp",
+        "HalHealthLoop.cpp",
+        "Health.cpp",
+        "LinkedCallback.cpp",
+    ],
+    target: {
+        recovery: {
+            exclude_srcs: [
+                "ChargerUtils.cpp",
+            ],
+        },
+    },
+}
+
+cc_fuzz {
+    name: "android.hardware.health-service.aidl_fuzzer",
+    defaults: [
+        "libhealth_aidl_impl_user",
+    ],
+    static_libs: [
+        "android.hardware.health-V1-ndk",
+        "libbase",
+        "libbinder_random_parcel",
+        "libcutils",
+        "liblog",
+        "libutils",
+        "fuzz_libhealth_aidl_impl",
+    ],
+    target: {
+        android: {
+            shared_libs: [
+                "libbinder_ndk",
+                "libbinder",
+            ],
+        },
+        host: {
+            static_libs: [
+                "libbinder_ndk",
+                "libbinder",
+            ],
+        },
+        darwin: {
+            enabled: false,
+        },
+    },
+    srcs: ["fuzzer.cpp"],
+    fuzz_config: {
+        cc: [
+            "hamzeh@google.com",
+        ],
+    },
+}
diff --git a/health/aidl/default/fuzzer.cpp b/health/aidl/default/fuzzer.cpp
new file mode 100644
index 0000000..b7c6d39
--- /dev/null
+++ b/health/aidl/default/fuzzer.cpp
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2022 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 <fuzzbinder/libbinder_ndk_driver.h>
+#include <fuzzer/FuzzedDataProvider.h>
+
+#include <android-base/logging.h>
+#include <android/binder_interface_utils.h>
+#include <health-impl/Health.h>
+#include <health/utils.h>
+
+using aidl::android::hardware::health::Health;
+using android::fuzzService;
+using ndk::SharedRefBase;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    auto config = std::make_unique<healthd_config>();
+    ::android::hardware::health::InitHealthdConfig(config.get());
+    auto binder = ndk::SharedRefBase::make<Health>("default", std::move(config));
+
+    fuzzService(binder->asBinder().get(), FuzzedDataProvider(data, size));
+
+    return 0;
+}
\ No newline at end of file
diff --git a/health/storage/aidl/Android.bp b/health/storage/aidl/Android.bp
index 4cd9263..c614efb 100644
--- a/health/storage/aidl/Android.bp
+++ b/health/storage/aidl/Android.bp
@@ -33,11 +33,6 @@
         java: {
             enabled: false,
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
     },
     versions: ["1"],
 }
diff --git a/identity/aidl/Android.bp b/identity/aidl/Android.bp
index e3b8191..907a6b6 100644
--- a/identity/aidl/Android.bp
+++ b/identity/aidl/Android.bp
@@ -23,9 +23,6 @@
             platform_apis: true,
         },
         ndk: {
-            vndk: {
-                enabled: true,
-            },
             apps_enabled: false,
         },
     },
diff --git a/identity/aidl/vts/Android.bp b/identity/aidl/vts/Android.bp
index 20faeee..dc010d6 100644
--- a/identity/aidl/vts/Android.bp
+++ b/identity/aidl/vts/Android.bp
@@ -57,17 +57,5 @@
         "general-tests",
         "vts",
     ],
-}
-
-java_test_host {
-    name: "IdentityCredentialImplementedTest",
-    libs: [
-        "tradefed",
-        "vts-core-tradefed-harness",
-    ],
-    srcs: ["src/**/*.java"],
-    test_suites: [
-        "vts",
-    ],
-    test_config: "IdentityCredentialImplementedTest.xml",
+    require_root: true,
 }
diff --git a/identity/aidl/vts/AndroidTest.xml b/identity/aidl/vts/AndroidTest.xml
new file mode 100644
index 0000000..67132b0
--- /dev/null
+++ b/identity/aidl/vts/AndroidTest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2022 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 VtsHalIdentityTargetTest.">
+    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+    </target_preparer>
+
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push"
+                value="VtsHalIdentityTargetTest->/data/local/tmp/VtsHalIdentityTargetTest" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="VtsHalIdentityTargetTest" />
+        <option name="native-test-timeout" value="300000"/>
+    </test>
+</configuration>
diff --git a/identity/aidl/vts/IdentityCredentialImplementedTest.xml b/identity/aidl/vts/IdentityCredentialImplementedTest.xml
deleted file mode 100644
index 1d76a74..0000000
--- a/identity/aidl/vts/IdentityCredentialImplementedTest.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2022 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 IdentityCredentialImplementedTest">
-  <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" />
-
-  <test class="com.android.tradefed.testtype.HostTest" >
-    <option name="jar" value="IdentityCredentialImplementedTest.jar" />
-  </test>
-</configuration>
diff --git a/identity/aidl/vts/src/com/android/tests/security/identity/IdentityCredentialImplementedTest.java b/identity/aidl/vts/src/com/android/tests/security/identity/IdentityCredentialImplementedTest.java
deleted file mode 100644
index 19568af..0000000
--- a/identity/aidl/vts/src/com/android/tests/security/identity/IdentityCredentialImplementedTest.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.tests.security.identity;
-
-import static org.junit.Assert.fail;
-import static org.junit.Assume.assumeTrue;
-
-import android.platform.test.annotations.RequiresDevice;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(DeviceJUnit4ClassRunner.class)
-public class IdentityCredentialImplementedTest extends BaseHostJUnit4Test {
-    // Returns the ro.vendor.api_level or 0 if not set.
-    //
-    // Throws NumberFormatException if ill-formatted.
-    //
-    // Throws DeviceNotAvailableException if device is not available.
-    //
-    private int getVendorApiLevel() throws NumberFormatException, DeviceNotAvailableException {
-        String vendorApiLevelString =
-                getDevice().executeShellCommand("getprop ro.vendor.api_level").trim();
-        if (vendorApiLevelString.isEmpty()) {
-            return 0;
-        }
-        return Integer.parseInt(vendorApiLevelString);
-    }
-
-    // As of Android 13 (API level 32), Identity Credential is required at feature version 202201
-    // or newer.
-    //
-    @RequiresDevice
-    @Test
-    public void testIdentityCredentialIsImplemented() throws Exception {
-        int vendorApiLevel = getVendorApiLevel();
-        assumeTrue(vendorApiLevel >= 32);
-
-        final String minimumFeatureVersionNeeded = "202201";
-
-        String result = getDevice().executeShellCommand(
-                "pm has-feature android.hardware.identity_credential "
-                + minimumFeatureVersionNeeded);
-        if (!result.trim().equals("true")) {
-            fail("Identity Credential feature version " + minimumFeatureVersionNeeded
-                    + " required but not found");
-        }
-    }
-}
diff --git a/keymaster/4.0/support/fuzzer/Android.bp b/keymaster/4.0/support/fuzzer/Android.bp
index 3a3f4d5..8bc681a 100644
--- a/keymaster/4.0/support/fuzzer/Android.bp
+++ b/keymaster/4.0/support/fuzzer/Android.bp
@@ -30,12 +30,12 @@
         "libbase",
         "liblog",
         "libkeymaster4support",
-        "libutils",
     ],
     shared_libs: [
         "android.hardware.keymaster@4.0",
         "libcrypto",
         "libhidlbase",
+        "libutils",
     ],
     fuzz_config: {
         cc: [
diff --git a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
index 14c756d..fb5048a 100644
--- a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
+++ b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
@@ -27,6 +27,7 @@
 #include <openssl/mem.h>
 #include <openssl/x509.h>
 
+#include <android-base/properties.h>
 #include <cutils/properties.h>
 
 #include <keymasterV4_0/attestation_record.h>
@@ -386,6 +387,31 @@
     return property_get("ro.boot.vbmeta.device_state", value, "") != 0;
 }
 
+int get_vsr_api_level() {
+    int vendor_api_level = ::android::base::GetIntProperty("ro.vendor.api_level", -1);
+    if (vendor_api_level != -1) {
+        return vendor_api_level;
+    }
+
+    // Android S and older devices do not define ro.vendor.api_level
+    vendor_api_level = ::android::base::GetIntProperty("ro.board.api_level", -1);
+    if (vendor_api_level == -1) {
+        vendor_api_level = ::android::base::GetIntProperty("ro.board.first_api_level", -1);
+    }
+
+    int product_api_level = ::android::base::GetIntProperty("ro.product.first_api_level", -1);
+    if (product_api_level == -1) {
+        product_api_level = ::android::base::GetIntProperty("ro.build.version.sdk", -1);
+        EXPECT_NE(product_api_level, -1) << "Could not find ro.build.version.sdk";
+    }
+
+    // VSR API level is the minimum of vendor_api_level and product_api_level.
+    if (vendor_api_level == -1 || vendor_api_level > product_api_level) {
+        return product_api_level;
+    }
+    return vendor_api_level;
+}
+
 bool is_gsi() {
     char property_value[PROPERTY_VALUE_MAX] = {};
     EXPECT_NE(property_get("ro.product.system.name", property_value, ""), 0);
@@ -2866,8 +2892,8 @@
 
         EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, params));
         string plaintext;
-        ErrorCode error = Finish(message, &plaintext);
-        if (error == ErrorCode::INVALID_INPUT_LENGTH) {
+        ErrorCode error = Finish(ciphertext, &plaintext);
+        if (error == ErrorCode::INVALID_ARGUMENT) {
             // This is the expected error, we can exit the test now.
             return;
         } else {
@@ -3105,6 +3131,49 @@
 }
 
 /*
+ * EncryptionOperationsTest.AesCbcZeroInputSuccessb
+ *
+ * Verifies that keymaster generates correct output on zero-input with
+ * NonePadding mode
+ */
+TEST_P(EncryptionOperationsTest, AesCbcZeroInputSuccess) {
+    ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
+                                                 .Authorization(TAG_NO_AUTH_REQUIRED)
+                                                 .AesEncryptionKey(128)
+                                                 .BlockMode(BlockMode::CBC)
+                                                 .Padding(PaddingMode::NONE, PaddingMode::PKCS7)));
+
+    // Zero input message
+    string message = "";
+    for (auto padding : {PaddingMode::NONE, PaddingMode::PKCS7}) {
+        auto params = AuthorizationSetBuilder().BlockMode(BlockMode::CBC).Padding(padding);
+        AuthorizationSet out_params;
+        string ciphertext1 = EncryptMessage(message, params, &out_params);
+        HidlBuf iv1 = CopyIv(out_params);
+        if (padding == PaddingMode::NONE)
+            EXPECT_EQ(message.size(), ciphertext1.size()) << "PaddingMode: " << padding;
+        else
+            EXPECT_EQ(message.size(), ciphertext1.size() - 16) << "PaddingMode: " << padding;
+
+        out_params.Clear();
+
+        string ciphertext2 = EncryptMessage(message, params, &out_params);
+        HidlBuf iv2 = CopyIv(out_params);
+        if (padding == PaddingMode::NONE)
+            EXPECT_EQ(message.size(), ciphertext2.size()) << "PaddingMode: " << padding;
+        else
+            EXPECT_EQ(message.size(), ciphertext2.size() - 16) << "PaddingMode: " << padding;
+
+        // IVs should be random
+        EXPECT_NE(iv1, iv2) << "PaddingMode: " << padding;
+
+        params.push_back(TAG_NONCE, iv1);
+        string plaintext = DecryptMessage(ciphertext1, params);
+        EXPECT_EQ(message, plaintext) << "PaddingMode: " << padding;
+    }
+}
+
+/*
  * EncryptionOperationsTest.AesCallerNonce
  *
  * Verifies that AES caller-provided nonces work correctly.
@@ -4790,6 +4859,18 @@
 
 INSTANTIATE_KEYMASTER_HIDL_TEST(TransportLimitTest);
 
+using VsrRequirementTest = KeymasterHidlTest;
+
+TEST_P(VsrRequirementTest, Vsr13Test) {
+    int vsr_api_level = get_vsr_api_level();
+    if (vsr_api_level < 33) {
+        GTEST_SKIP() << "Applies only to VSR API level 33, this device is: " << vsr_api_level;
+    }
+    FAIL() << "VSR 13+ requires KeyMint version 2";
+}
+
+INSTANTIATE_KEYMASTER_HIDL_TEST(VsrRequirementTest);
+
 }  // namespace test
 }  // namespace V4_0
 }  // namespace keymaster
diff --git a/keymaster/aidl/Android.bp b/keymaster/aidl/Android.bp
index c4b6740..0fb6e4c 100644
--- a/keymaster/aidl/Android.bp
+++ b/keymaster/aidl/Android.bp
@@ -18,11 +18,6 @@
         java: {
             platform_apis: true,
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
     },
     versions: [
         "1",
diff --git a/light/aidl/Android.bp b/light/aidl/Android.bp
index c8973f3..e714212 100644
--- a/light/aidl/Android.bp
+++ b/light/aidl/Android.bp
@@ -18,11 +18,6 @@
         java: {
             sdk_version: "module_current",
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
     },
     versions: ["1"],
 }
diff --git a/light/aidl/default/Lights.cpp b/light/aidl/default/Lights.cpp
index 74747d5..9bf3b20 100644
--- a/light/aidl/default/Lights.cpp
+++ b/light/aidl/default/Lights.cpp
@@ -23,12 +23,21 @@
 namespace hardware {
 namespace light {
 
+static constexpr int kNumDefaultLights = 3;
+
 ndk::ScopedAStatus Lights::setLightState(int id, const HwLightState& state) {
     LOG(INFO) << "Lights setting state for id=" << id << " to color " << std::hex << state.color;
-    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+    if (id <= 0 || id > kNumDefaultLights) {
+        return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+    } else {
+        return ndk::ScopedAStatus::ok();
+    }
 }
 
-ndk::ScopedAStatus Lights::getLights(std::vector<HwLight>* /*lights*/) {
+ndk::ScopedAStatus Lights::getLights(std::vector<HwLight>* lights) {
+    for (int i = 1; i <= kNumDefaultLights; i++) {
+        lights->push_back({i, i});
+    }
     LOG(INFO) << "Lights reporting supported lights";
     return ndk::ScopedAStatus::ok();
 }
diff --git a/neuralnetworks/1.0/utils/src/Conversions.cpp b/neuralnetworks/1.0/utils/src/Conversions.cpp
index daa10fd..d98fef0 100644
--- a/neuralnetworks/1.0/utils/src/Conversions.cpp
+++ b/neuralnetworks/1.0/utils/src/Conversions.cpp
@@ -110,8 +110,9 @@
             return NN_ERROR() << "Unable to convert invalid ashmem memory object with "
                               << memory.handle()->numInts << " numInts, but expected 0";
         }
+        auto fd = NN_TRY(nn::dupFd(memory.handle()->data[0]));
         auto handle = nn::Memory::Ashmem{
-                .fd = NN_TRY(nn::dupFd(memory.handle()->data[0])),
+                .fd = std::move(fd),
                 .size = static_cast<size_t>(memory.size()),
         };
         return std::make_shared<const nn::Memory>(nn::Memory{.handle = std::move(handle)});
@@ -137,12 +138,13 @@
     }
 
     if (memory.name() != "hardware_buffer_blob") {
-        auto handle = nn::Memory::Unknown{
-                .handle = NN_TRY(unknownHandleFromNativeHandle(memory.handle())),
+        auto handle = NN_TRY(unknownHandleFromNativeHandle(memory.handle()));
+        auto unknown = nn::Memory::Unknown{
+                .handle = std::move(handle),
                 .size = static_cast<size_t>(memory.size()),
                 .name = memory.name(),
         };
-        return std::make_shared<const nn::Memory>(nn::Memory{.handle = std::move(handle)});
+        return std::make_shared<const nn::Memory>(nn::Memory{.handle = std::move(unknown)});
     }
 
 #ifdef __ANDROID__
@@ -245,19 +247,23 @@
 }
 
 GeneralResult<Operand> unvalidatedConvert(const hal::V1_0::Operand& operand) {
+    const auto type = NN_TRY(unvalidatedConvert(operand.type));
+    const auto lifetime = NN_TRY(unvalidatedConvert(operand.lifetime));
+    const auto location = NN_TRY(unvalidatedConvert(operand.location));
     return Operand{
-            .type = NN_TRY(unvalidatedConvert(operand.type)),
+            .type = type,
             .dimensions = operand.dimensions,
             .scale = operand.scale,
             .zeroPoint = operand.zeroPoint,
-            .lifetime = NN_TRY(unvalidatedConvert(operand.lifetime)),
-            .location = NN_TRY(unvalidatedConvert(operand.location)),
+            .lifetime = lifetime,
+            .location = location,
     };
 }
 
 GeneralResult<Operation> unvalidatedConvert(const hal::V1_0::Operation& operation) {
+    const auto type = NN_TRY(unvalidatedConvert(operation.type));
     return Operation{
-            .type = NN_TRY(unvalidatedConvert(operation.type)),
+            .type = type,
             .inputs = operation.inputs,
             .outputs = operation.outputs,
     };
@@ -298,26 +304,30 @@
         }
     }
 
+    auto operands = NN_TRY(unvalidatedConvert(model.operands));
     auto main = Model::Subgraph{
-            .operands = NN_TRY(unvalidatedConvert(model.operands)),
+            .operands = std::move(operands),
             .operations = std::move(operations),
             .inputIndexes = model.inputIndexes,
             .outputIndexes = model.outputIndexes,
     };
 
+    auto operandValues = NN_TRY(unvalidatedConvert(model.operandValues));
+    auto pools = NN_TRY(unvalidatedConvert(model.pools));
     return Model{
             .main = std::move(main),
-            .operandValues = NN_TRY(unvalidatedConvert(model.operandValues)),
-            .pools = NN_TRY(unvalidatedConvert(model.pools)),
+            .operandValues = std::move(operandValues),
+            .pools = std::move(pools),
     };
 }
 
 GeneralResult<Request::Argument> unvalidatedConvert(const hal::V1_0::RequestArgument& argument) {
     const auto lifetime = argument.hasNoValue ? Request::Argument::LifeTime::NO_VALUE
                                               : Request::Argument::LifeTime::POOL;
+    const auto location = NN_TRY(unvalidatedConvert(argument.location));
     return Request::Argument{
             .lifetime = lifetime,
-            .location = NN_TRY(unvalidatedConvert(argument.location)),
+            .location = location,
             .dimensions = argument.dimensions,
     };
 }
@@ -328,9 +338,11 @@
     pools.reserve(memories.size());
     std::move(memories.begin(), memories.end(), std::back_inserter(pools));
 
+    auto inputs = NN_TRY(unvalidatedConvert(request.inputs));
+    auto outputs = NN_TRY(unvalidatedConvert(request.outputs));
     return Request{
-            .inputs = NN_TRY(unvalidatedConvert(request.inputs)),
-            .outputs = NN_TRY(unvalidatedConvert(request.outputs)),
+            .inputs = std::move(inputs),
+            .outputs = std::move(outputs),
             .pools = std::move(pools),
     };
 }
@@ -500,11 +512,13 @@
 }
 
 nn::GeneralResult<Capabilities> unvalidatedConvert(const nn::Capabilities& capabilities) {
+    const auto float32Performance = NN_TRY(unvalidatedConvert(
+            capabilities.operandPerformance.lookup(nn::OperandType::TENSOR_FLOAT32)));
+    const auto quantized8Performance = NN_TRY(unvalidatedConvert(
+            capabilities.operandPerformance.lookup(nn::OperandType::TENSOR_QUANT8_ASYMM)));
     return Capabilities{
-            .float32Performance = NN_TRY(unvalidatedConvert(
-                    capabilities.operandPerformance.lookup(nn::OperandType::TENSOR_FLOAT32))),
-            .quantized8Performance = NN_TRY(unvalidatedConvert(
-                    capabilities.operandPerformance.lookup(nn::OperandType::TENSOR_QUANT8_ASYMM))),
+            .float32Performance = float32Performance,
+            .quantized8Performance = quantized8Performance,
     };
 }
 
@@ -517,20 +531,24 @@
 }
 
 nn::GeneralResult<Operand> unvalidatedConvert(const nn::Operand& operand) {
+    const auto type = NN_TRY(unvalidatedConvert(operand.type));
+    const auto lifetime = NN_TRY(unvalidatedConvert(operand.lifetime));
+    const auto location = NN_TRY(unvalidatedConvert(operand.location));
     return Operand{
-            .type = NN_TRY(unvalidatedConvert(operand.type)),
+            .type = type,
             .dimensions = operand.dimensions,
             .numberOfConsumers = 0,
             .scale = operand.scale,
             .zeroPoint = operand.zeroPoint,
-            .lifetime = NN_TRY(unvalidatedConvert(operand.lifetime)),
-            .location = NN_TRY(unvalidatedConvert(operand.location)),
+            .lifetime = lifetime,
+            .location = location,
     };
 }
 
 nn::GeneralResult<Operation> unvalidatedConvert(const nn::Operation& operation) {
+    const auto type = NN_TRY(unvalidatedConvert(operation.type));
     return Operation{
-            .type = NN_TRY(unvalidatedConvert(operation.type)),
+            .type = type,
             .inputs = operation.inputs,
             .outputs = operation.outputs,
     };
@@ -572,13 +590,16 @@
         operands[i].numberOfConsumers = numberOfConsumers[i];
     }
 
+    auto operations = NN_TRY(unvalidatedConvert(model.main.operations));
+    auto operandValues = NN_TRY(unvalidatedConvert(model.operandValues));
+    auto pools = NN_TRY(unvalidatedConvert(model.pools));
     return Model{
             .operands = std::move(operands),
-            .operations = NN_TRY(unvalidatedConvert(model.main.operations)),
+            .operations = std::move(operations),
             .inputIndexes = model.main.inputIndexes,
             .outputIndexes = model.main.outputIndexes,
-            .operandValues = NN_TRY(unvalidatedConvert(model.operandValues)),
-            .pools = NN_TRY(unvalidatedConvert(model.pools)),
+            .operandValues = std::move(operandValues),
+            .pools = std::move(pools),
     };
 }
 
@@ -589,9 +610,10 @@
                << "Request cannot be unvalidatedConverted because it contains pointer-based memory";
     }
     const bool hasNoValue = requestArgument.lifetime == nn::Request::Argument::LifeTime::NO_VALUE;
+    const auto location = NN_TRY(unvalidatedConvert(requestArgument.location));
     return RequestArgument{
             .hasNoValue = hasNoValue,
-            .location = NN_TRY(unvalidatedConvert(requestArgument.location)),
+            .location = location,
             .dimensions = requestArgument.dimensions,
     };
 }
@@ -606,10 +628,13 @@
                << "Request cannot be unvalidatedConverted because it contains pointer-based memory";
     }
 
+    auto inputs = NN_TRY(unvalidatedConvert(request.inputs));
+    auto outputs = NN_TRY(unvalidatedConvert(request.outputs));
+    auto pools = NN_TRY(unvalidatedConvert(request.pools));
     return Request{
-            .inputs = NN_TRY(unvalidatedConvert(request.inputs)),
-            .outputs = NN_TRY(unvalidatedConvert(request.outputs)),
-            .pools = NN_TRY(unvalidatedConvert(request.pools)),
+            .inputs = std::move(inputs),
+            .outputs = std::move(outputs),
+            .pools = std::move(pools),
     };
 }
 
diff --git a/neuralnetworks/1.0/vts/functional/Android.bp b/neuralnetworks/1.0/vts/functional/Android.bp
index 29b31d2..a41f37f 100644
--- a/neuralnetworks/1.0/vts/functional/Android.bp
+++ b/neuralnetworks/1.0/vts/functional/Android.bp
@@ -90,7 +90,6 @@
         "libneuralnetworks_headers",
     ],
     test_suites: [
-        "general-tests",
         "vts",
     ],
 }
diff --git a/neuralnetworks/1.1/utils/src/Conversions.cpp b/neuralnetworks/1.1/utils/src/Conversions.cpp
index 5bdbe31..887c8ec 100644
--- a/neuralnetworks/1.1/utils/src/Conversions.cpp
+++ b/neuralnetworks/1.1/utils/src/Conversions.cpp
@@ -88,8 +88,9 @@
 }
 
 GeneralResult<Operation> unvalidatedConvert(const hal::V1_1::Operation& operation) {
+    const auto type = NN_TRY(unvalidatedConvert(operation.type));
     return Operation{
-            .type = NN_TRY(unvalidatedConvert(operation.type)),
+            .type = type,
             .inputs = operation.inputs,
             .outputs = operation.outputs,
     };
@@ -110,17 +111,20 @@
         }
     }
 
+    auto operands = NN_TRY(unvalidatedConvert(model.operands));
     auto main = Model::Subgraph{
-            .operands = NN_TRY(unvalidatedConvert(model.operands)),
+            .operands = std::move(operands),
             .operations = std::move(operations),
             .inputIndexes = model.inputIndexes,
             .outputIndexes = model.outputIndexes,
     };
 
+    auto operandValues = NN_TRY(unvalidatedConvert(model.operandValues));
+    auto pools = NN_TRY(unvalidatedConvert(model.pools));
     return Model{
             .main = std::move(main),
-            .operandValues = NN_TRY(unvalidatedConvert(model.operandValues)),
-            .pools = NN_TRY(unvalidatedConvert(model.pools)),
+            .operandValues = std::move(operandValues),
+            .pools = std::move(pools),
             .relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16,
     };
 }
@@ -195,19 +199,23 @@
 }
 
 nn::GeneralResult<Capabilities> unvalidatedConvert(const nn::Capabilities& capabilities) {
+    const auto float32Performance = NN_TRY(unvalidatedConvert(
+            capabilities.operandPerformance.lookup(nn::OperandType::TENSOR_FLOAT32)));
+    const auto quanitized8Performance = NN_TRY(unvalidatedConvert(
+            capabilities.operandPerformance.lookup(nn::OperandType::TENSOR_QUANT8_ASYMM)));
+    const auto relaxedFloat32toFloat16Performance =
+            NN_TRY(unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceTensor));
     return Capabilities{
-            .float32Performance = NN_TRY(unvalidatedConvert(
-                    capabilities.operandPerformance.lookup(nn::OperandType::TENSOR_FLOAT32))),
-            .quantized8Performance = NN_TRY(unvalidatedConvert(
-                    capabilities.operandPerformance.lookup(nn::OperandType::TENSOR_QUANT8_ASYMM))),
-            .relaxedFloat32toFloat16Performance = NN_TRY(
-                    unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceTensor)),
+            .float32Performance = float32Performance,
+            .quantized8Performance = quanitized8Performance,
+            .relaxedFloat32toFloat16Performance = relaxedFloat32toFloat16Performance,
     };
 }
 
 nn::GeneralResult<Operation> unvalidatedConvert(const nn::Operation& operation) {
+    const auto type = NN_TRY(unvalidatedConvert(operation.type));
     return Operation{
-            .type = NN_TRY(unvalidatedConvert(operation.type)),
+            .type = type,
             .inputs = operation.inputs,
             .outputs = operation.outputs,
     };
@@ -229,13 +237,16 @@
         operands[i].numberOfConsumers = numberOfConsumers[i];
     }
 
+    auto operations = NN_TRY(unvalidatedConvert(model.main.operations));
+    auto operandValues = NN_TRY(unvalidatedConvert(model.operandValues));
+    auto pools = NN_TRY(unvalidatedConvert(model.pools));
     return Model{
             .operands = std::move(operands),
-            .operations = NN_TRY(unvalidatedConvert(model.main.operations)),
+            .operations = std::move(operations),
             .inputIndexes = model.main.inputIndexes,
             .outputIndexes = model.main.outputIndexes,
-            .operandValues = NN_TRY(unvalidatedConvert(model.operandValues)),
-            .pools = NN_TRY(unvalidatedConvert(model.pools)),
+            .operandValues = std::move(operandValues),
+            .pools = std::move(pools),
             .relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16,
     };
 }
diff --git a/neuralnetworks/1.1/vts/functional/Android.bp b/neuralnetworks/1.1/vts/functional/Android.bp
index e9d4b76..7c1c118 100644
--- a/neuralnetworks/1.1/vts/functional/Android.bp
+++ b/neuralnetworks/1.1/vts/functional/Android.bp
@@ -58,7 +58,6 @@
         "libneuralnetworks_headers",
     ],
     test_suites: [
-        "general-tests",
         "vts",
     ],
 }
diff --git a/neuralnetworks/1.2/utils/src/Conversions.cpp b/neuralnetworks/1.2/utils/src/Conversions.cpp
index 62ec2ed..78d71cf 100644
--- a/neuralnetworks/1.2/utils/src/Conversions.cpp
+++ b/neuralnetworks/1.2/utils/src/Conversions.cpp
@@ -131,15 +131,18 @@
 
 GeneralResult<Capabilities::OperandPerformance> unvalidatedConvert(
         const hal::V1_2::Capabilities::OperandPerformance& operandPerformance) {
+    const auto type = NN_TRY(unvalidatedConvert(operandPerformance.type));
+    const auto info = NN_TRY(unvalidatedConvert(operandPerformance.info));
     return Capabilities::OperandPerformance{
-            .type = NN_TRY(unvalidatedConvert(operandPerformance.type)),
-            .info = NN_TRY(unvalidatedConvert(operandPerformance.info)),
+            .type = type,
+            .info = info,
     };
 }
 
 GeneralResult<Operation> unvalidatedConvert(const hal::V1_2::Operation& operation) {
+    const auto type = NN_TRY(unvalidatedConvert(operation.type));
     return Operation{
-            .type = NN_TRY(unvalidatedConvert(operation.type)),
+            .type = type,
             .inputs = operation.inputs,
             .outputs = operation.outputs,
     };
@@ -154,14 +157,18 @@
 }
 
 GeneralResult<Operand> unvalidatedConvert(const hal::V1_2::Operand& operand) {
+    const auto type = NN_TRY(unvalidatedConvert(operand.type));
+    const auto lifetime = NN_TRY(unvalidatedConvert(operand.lifetime));
+    const auto location = NN_TRY(unvalidatedConvert(operand.location));
+    auto extraParams = NN_TRY(unvalidatedConvert(operand.extraParams));
     return Operand{
-            .type = NN_TRY(unvalidatedConvert(operand.type)),
+            .type = type,
             .dimensions = operand.dimensions,
             .scale = operand.scale,
             .zeroPoint = operand.zeroPoint,
-            .lifetime = NN_TRY(unvalidatedConvert(operand.lifetime)),
-            .location = NN_TRY(unvalidatedConvert(operand.location)),
-            .extraParams = NN_TRY(unvalidatedConvert(operand.extraParams)),
+            .lifetime = lifetime,
+            .location = location,
+            .extraParams = std::move(extraParams),
     };
 }
 
@@ -196,19 +203,23 @@
         }
     }
 
+    auto operands = NN_TRY(unvalidatedConvert(model.operands));
     auto main = Model::Subgraph{
-            .operands = NN_TRY(unvalidatedConvert(model.operands)),
+            .operands = std::move(operands),
             .operations = std::move(operations),
             .inputIndexes = model.inputIndexes,
             .outputIndexes = model.outputIndexes,
     };
 
+    auto operandValues = NN_TRY(unvalidatedConvert(model.operandValues));
+    auto pools = NN_TRY(unvalidatedConvert(model.pools));
+    auto extensionNameToPrefix = NN_TRY(unvalidatedConvert(model.extensionNameToPrefix));
     return Model{
             .main = std::move(main),
-            .operandValues = NN_TRY(unvalidatedConvert(model.operandValues)),
-            .pools = NN_TRY(unvalidatedConvert(model.pools)),
+            .operandValues = std::move(operandValues),
+            .pools = std::move(pools),
             .relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16,
-            .extensionNameToPrefix = NN_TRY(unvalidatedConvert(model.extensionNameToPrefix)),
+            .extensionNameToPrefix = std::move(extensionNameToPrefix),
     };
 }
 
@@ -248,9 +259,10 @@
 }
 
 GeneralResult<Extension> unvalidatedConvert(const hal::V1_2::Extension& extension) {
+    auto operandTypes = NN_TRY(unvalidatedConvert(extension.operandTypes));
     return Extension{
             .name = extension.name,
-            .operandTypes = NN_TRY(unvalidatedConvert(extension.operandTypes)),
+            .operandTypes = std::move(operandTypes),
     };
 }
 
@@ -406,35 +418,41 @@
 }
 
 nn::GeneralResult<Capabilities> unvalidatedConvert(const nn::Capabilities& capabilities) {
-    std::vector<nn::Capabilities::OperandPerformance> operandPerformance;
-    operandPerformance.reserve(capabilities.operandPerformance.asVector().size());
+    std::vector<nn::Capabilities::OperandPerformance> filteredOperandPerformances;
+    filteredOperandPerformances.reserve(capabilities.operandPerformance.asVector().size());
     std::copy_if(capabilities.operandPerformance.asVector().begin(),
                  capabilities.operandPerformance.asVector().end(),
-                 std::back_inserter(operandPerformance),
+                 std::back_inserter(filteredOperandPerformances),
                  [](const nn::Capabilities::OperandPerformance& operandPerformance) {
                      return compliantVersion(operandPerformance.type).has_value();
                  });
 
+    const auto relaxedFloat32toFloat16PerformanceScalar =
+            NN_TRY(unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceScalar));
+    const auto relaxedFloat32toFloat16PerformanceTensor =
+            NN_TRY(unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceTensor));
+    auto operandPerformance = NN_TRY(unvalidatedConvert(filteredOperandPerformances));
     return Capabilities{
-            .relaxedFloat32toFloat16PerformanceScalar = NN_TRY(
-                    unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceScalar)),
-            .relaxedFloat32toFloat16PerformanceTensor = NN_TRY(
-                    unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceTensor)),
-            .operandPerformance = NN_TRY(unvalidatedConvert(operandPerformance)),
+            .relaxedFloat32toFloat16PerformanceScalar = relaxedFloat32toFloat16PerformanceScalar,
+            .relaxedFloat32toFloat16PerformanceTensor = relaxedFloat32toFloat16PerformanceTensor,
+            .operandPerformance = std::move(operandPerformance),
     };
 }
 
 nn::GeneralResult<Capabilities::OperandPerformance> unvalidatedConvert(
         const nn::Capabilities::OperandPerformance& operandPerformance) {
+    const auto type = NN_TRY(unvalidatedConvert(operandPerformance.type));
+    const auto info = NN_TRY(unvalidatedConvert(operandPerformance.info));
     return Capabilities::OperandPerformance{
-            .type = NN_TRY(unvalidatedConvert(operandPerformance.type)),
-            .info = NN_TRY(unvalidatedConvert(operandPerformance.info)),
+            .type = type,
+            .info = info,
     };
 }
 
 nn::GeneralResult<Operation> unvalidatedConvert(const nn::Operation& operation) {
+    const auto type = NN_TRY(unvalidatedConvert(operation.type));
     return Operation{
-            .type = NN_TRY(unvalidatedConvert(operation.type)),
+            .type = type,
             .inputs = operation.inputs,
             .outputs = operation.outputs,
     };
@@ -449,15 +467,19 @@
 }
 
 nn::GeneralResult<Operand> unvalidatedConvert(const nn::Operand& operand) {
+    const auto type = NN_TRY(unvalidatedConvert(operand.type));
+    const auto lifetime = NN_TRY(unvalidatedConvert(operand.lifetime));
+    const auto location = NN_TRY(unvalidatedConvert(operand.location));
+    auto extraParams = NN_TRY(unvalidatedConvert(operand.extraParams));
     return Operand{
-            .type = NN_TRY(unvalidatedConvert(operand.type)),
+            .type = type,
             .dimensions = operand.dimensions,
             .numberOfConsumers = 0,
             .scale = operand.scale,
             .zeroPoint = operand.zeroPoint,
-            .lifetime = NN_TRY(unvalidatedConvert(operand.lifetime)),
-            .location = NN_TRY(unvalidatedConvert(operand.location)),
-            .extraParams = NN_TRY(unvalidatedConvert(operand.extraParams)),
+            .lifetime = lifetime,
+            .location = location,
+            .extraParams = std::move(extraParams),
     };
 }
 
@@ -482,15 +504,19 @@
         operands[i].numberOfConsumers = numberOfConsumers[i];
     }
 
+    auto operations = NN_TRY(unvalidatedConvert(model.main.operations));
+    auto operandValues = NN_TRY(unvalidatedConvert(model.operandValues));
+    auto pools = NN_TRY(unvalidatedConvert(model.pools));
+    auto extensionNameToPrefix = NN_TRY(unvalidatedConvert(model.extensionNameToPrefix));
     return Model{
             .operands = std::move(operands),
-            .operations = NN_TRY(unvalidatedConvert(model.main.operations)),
+            .operations = std::move(operations),
             .inputIndexes = model.main.inputIndexes,
             .outputIndexes = model.main.outputIndexes,
-            .operandValues = NN_TRY(unvalidatedConvert(model.operandValues)),
-            .pools = NN_TRY(unvalidatedConvert(model.pools)),
+            .operandValues = std::move(operandValues),
+            .pools = std::move(pools),
             .relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16,
-            .extensionNameToPrefix = NN_TRY(unvalidatedConvert(model.extensionNameToPrefix)),
+            .extensionNameToPrefix = std::move(extensionNameToPrefix),
     };
 }
 
@@ -524,9 +550,10 @@
 }
 
 nn::GeneralResult<Extension> unvalidatedConvert(const nn::Extension& extension) {
+    auto operandTypes = NN_TRY(unvalidatedConvert(extension.operandTypes));
     return Extension{
             .name = extension.name,
-            .operandTypes = NN_TRY(unvalidatedConvert(extension.operandTypes)),
+            .operandTypes = std::move(operandTypes),
     };
 }
 
diff --git a/neuralnetworks/1.2/vts/functional/Android.bp b/neuralnetworks/1.2/vts/functional/Android.bp
index 2177924..7e4b5bb 100644
--- a/neuralnetworks/1.2/vts/functional/Android.bp
+++ b/neuralnetworks/1.2/vts/functional/Android.bp
@@ -85,7 +85,6 @@
         "libneuralnetworks_headers",
     ],
     test_suites: [
-        "general-tests",
         "vts",
     ],
 }
diff --git a/neuralnetworks/1.2/vts/functional/CompilationCachingTests.cpp b/neuralnetworks/1.2/vts/functional/CompilationCachingTests.cpp
index 3d783d9..fe38e61 100644
--- a/neuralnetworks/1.2/vts/functional/CompilationCachingTests.cpp
+++ b/neuralnetworks/1.2/vts/functional/CompilationCachingTests.cpp
@@ -1262,7 +1262,7 @@
         FILE* pFile = fopen(filename.c_str(), "a");
         uint32_t appendLength = getRandomInt(1, 256);
         for (uint32_t i = 0; i < appendLength; i++) {
-            ASSERT_NE(fputc(getRandomInt<uint8_t>(0, 255), pFile), EOF);
+            ASSERT_NE(fputc(getRandomInt<uint16_t>(0, 255), pFile), EOF);
         }
         fclose(pFile);
         *skip = false;
diff --git a/neuralnetworks/1.3/utils/src/Conversions.cpp b/neuralnetworks/1.3/utils/src/Conversions.cpp
index 09e9d80..4eeb414 100644
--- a/neuralnetworks/1.3/utils/src/Conversions.cpp
+++ b/neuralnetworks/1.3/utils/src/Conversions.cpp
@@ -133,28 +133,35 @@
     auto table =
             NN_TRY(Capabilities::OperandPerformanceTable::create(std::move(operandPerformance)));
 
+    const auto relaxedFloat32toFloat16PerformanceScalar =
+            NN_TRY(unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceScalar));
+    const auto relaxedFloat32toFloat16PerformanceTensor =
+            NN_TRY(unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceTensor));
+    const auto ifPerformance = NN_TRY(unvalidatedConvert(capabilities.ifPerformance));
+    const auto whilePerformance = NN_TRY(unvalidatedConvert(capabilities.whilePerformance));
     return Capabilities{
-            .relaxedFloat32toFloat16PerformanceScalar = NN_TRY(
-                    unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceScalar)),
-            .relaxedFloat32toFloat16PerformanceTensor = NN_TRY(
-                    unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceTensor)),
+            .relaxedFloat32toFloat16PerformanceScalar = relaxedFloat32toFloat16PerformanceScalar,
+            .relaxedFloat32toFloat16PerformanceTensor = relaxedFloat32toFloat16PerformanceTensor,
             .operandPerformance = std::move(table),
-            .ifPerformance = NN_TRY(unvalidatedConvert(capabilities.ifPerformance)),
-            .whilePerformance = NN_TRY(unvalidatedConvert(capabilities.whilePerformance)),
+            .ifPerformance = ifPerformance,
+            .whilePerformance = whilePerformance,
     };
 }
 
 GeneralResult<Capabilities::OperandPerformance> unvalidatedConvert(
         const hal::V1_3::Capabilities::OperandPerformance& operandPerformance) {
+    const auto type = NN_TRY(unvalidatedConvert(operandPerformance.type));
+    const auto info = NN_TRY(unvalidatedConvert(operandPerformance.info));
     return Capabilities::OperandPerformance{
-            .type = NN_TRY(unvalidatedConvert(operandPerformance.type)),
-            .info = NN_TRY(unvalidatedConvert(operandPerformance.info)),
+            .type = type,
+            .info = info,
     };
 }
 
 GeneralResult<Operation> unvalidatedConvert(const hal::V1_3::Operation& operation) {
+    const auto type = NN_TRY(unvalidatedConvert(operation.type));
     return Operation{
-            .type = NN_TRY(unvalidatedConvert(operation.type)),
+            .type = type,
             .inputs = operation.inputs,
             .outputs = operation.outputs,
     };
@@ -166,25 +173,34 @@
 }
 
 GeneralResult<Operand> unvalidatedConvert(const hal::V1_3::Operand& operand) {
+    const auto type = NN_TRY(unvalidatedConvert(operand.type));
+    const auto lifetime = NN_TRY(unvalidatedConvert(operand.lifetime));
+    const auto location = NN_TRY(unvalidatedConvert(operand.location));
+    auto extraParams = NN_TRY(unvalidatedConvert(operand.extraParams));
     return Operand{
-            .type = NN_TRY(unvalidatedConvert(operand.type)),
+            .type = type,
             .dimensions = operand.dimensions,
             .scale = operand.scale,
             .zeroPoint = operand.zeroPoint,
-            .lifetime = NN_TRY(unvalidatedConvert(operand.lifetime)),
-            .location = NN_TRY(unvalidatedConvert(operand.location)),
-            .extraParams = NN_TRY(unvalidatedConvert(operand.extraParams)),
+            .lifetime = lifetime,
+            .location = location,
+            .extraParams = std::move(extraParams),
     };
 }
 
 GeneralResult<Model> unvalidatedConvert(const hal::V1_3::Model& model) {
+    auto main = NN_TRY(unvalidatedConvert(model.main));
+    auto referenced = NN_TRY(unvalidatedConvert(model.referenced));
+    auto operandValues = NN_TRY(unvalidatedConvert(model.operandValues));
+    auto pools = NN_TRY(unvalidatedConvert(model.pools));
+    auto extensionNameToPrefix = NN_TRY(unvalidatedConvert(model.extensionNameToPrefix));
     return Model{
-            .main = NN_TRY(unvalidatedConvert(model.main)),
-            .referenced = NN_TRY(unvalidatedConvert(model.referenced)),
-            .operandValues = NN_TRY(unvalidatedConvert(model.operandValues)),
-            .pools = NN_TRY(unvalidatedConvert(model.pools)),
+            .main = std::move(main),
+            .referenced = std::move(referenced),
+            .operandValues = std::move(operandValues),
+            .pools = std::move(pools),
             .relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16,
-            .extensionNameToPrefix = NN_TRY(unvalidatedConvert(model.extensionNameToPrefix)),
+            .extensionNameToPrefix = std::move(extensionNameToPrefix),
     };
 }
 
@@ -204,8 +220,9 @@
         }
     }
 
+    auto operands = NN_TRY(unvalidatedConvert(subgraph.operands));
     return Model::Subgraph{
-            .operands = NN_TRY(unvalidatedConvert(subgraph.operands)),
+            .operands = std::move(operands),
             .operations = std::move(operations),
             .inputIndexes = subgraph.inputIndexes,
             .outputIndexes = subgraph.outputIndexes,
@@ -225,10 +242,13 @@
 }
 
 GeneralResult<Request> unvalidatedConvert(const hal::V1_3::Request& request) {
+    auto inputs = NN_TRY(unvalidatedConvert(request.inputs));
+    auto outputs = NN_TRY(unvalidatedConvert(request.outputs));
+    auto pools = NN_TRY(unvalidatedConvert(request.pools));
     return Request{
-            .inputs = NN_TRY(unvalidatedConvert(request.inputs)),
-            .outputs = NN_TRY(unvalidatedConvert(request.outputs)),
-            .pools = NN_TRY(unvalidatedConvert(request.pools)),
+            .inputs = std::move(inputs),
+            .outputs = std::move(outputs),
+            .pools = std::move(pools),
     };
 }
 
@@ -463,37 +483,45 @@
 }
 
 nn::GeneralResult<Capabilities> unvalidatedConvert(const nn::Capabilities& capabilities) {
-    std::vector<nn::Capabilities::OperandPerformance> operandPerformance;
-    operandPerformance.reserve(capabilities.operandPerformance.asVector().size());
+    std::vector<nn::Capabilities::OperandPerformance> filteredOperandPerformances;
+    filteredOperandPerformances.reserve(capabilities.operandPerformance.asVector().size());
     std::copy_if(capabilities.operandPerformance.asVector().begin(),
                  capabilities.operandPerformance.asVector().end(),
-                 std::back_inserter(operandPerformance),
+                 std::back_inserter(filteredOperandPerformances),
                  [](const nn::Capabilities::OperandPerformance& operandPerformance) {
                      return compliantVersion(operandPerformance.type).has_value();
                  });
 
+    const auto relaxedFloat32toFloat16PerformanceScalar =
+            NN_TRY(unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceScalar));
+    const auto relaxedFloat32toFloat16PerformanceTensor =
+            NN_TRY(unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceTensor));
+    auto operandPerformance = NN_TRY(unvalidatedConvert(filteredOperandPerformances));
+    const auto ifPerformance = NN_TRY(unvalidatedConvert(capabilities.ifPerformance));
+    const auto whilePerformance = NN_TRY(unvalidatedConvert(capabilities.whilePerformance));
     return Capabilities{
-            .relaxedFloat32toFloat16PerformanceScalar = NN_TRY(
-                    unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceScalar)),
-            .relaxedFloat32toFloat16PerformanceTensor = NN_TRY(
-                    unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceTensor)),
-            .operandPerformance = NN_TRY(unvalidatedConvert(operandPerformance)),
-            .ifPerformance = NN_TRY(unvalidatedConvert(capabilities.ifPerformance)),
-            .whilePerformance = NN_TRY(unvalidatedConvert(capabilities.whilePerformance)),
+            .relaxedFloat32toFloat16PerformanceScalar = relaxedFloat32toFloat16PerformanceScalar,
+            .relaxedFloat32toFloat16PerformanceTensor = relaxedFloat32toFloat16PerformanceTensor,
+            .operandPerformance = std::move(operandPerformance),
+            .ifPerformance = ifPerformance,
+            .whilePerformance = whilePerformance,
     };
 }
 
 nn::GeneralResult<Capabilities::OperandPerformance> unvalidatedConvert(
         const nn::Capabilities::OperandPerformance& operandPerformance) {
+    const auto type = NN_TRY(unvalidatedConvert(operandPerformance.type));
+    const auto info = NN_TRY(unvalidatedConvert(operandPerformance.info));
     return Capabilities::OperandPerformance{
-            .type = NN_TRY(unvalidatedConvert(operandPerformance.type)),
-            .info = NN_TRY(unvalidatedConvert(operandPerformance.info)),
+            .type = type,
+            .info = info,
     };
 }
 
 nn::GeneralResult<Operation> unvalidatedConvert(const nn::Operation& operation) {
+    const auto type = NN_TRY(unvalidatedConvert(operation.type));
     return Operation{
-            .type = NN_TRY(unvalidatedConvert(operation.type)),
+            .type = type,
             .inputs = operation.inputs,
             .outputs = operation.outputs,
     };
@@ -509,15 +537,19 @@
 }
 
 nn::GeneralResult<Operand> unvalidatedConvert(const nn::Operand& operand) {
+    const auto type = NN_TRY(unvalidatedConvert(operand.type));
+    const auto lifetime = NN_TRY(unvalidatedConvert(operand.lifetime));
+    const auto location = NN_TRY(unvalidatedConvert(operand.location));
+    auto extraParams = NN_TRY(unvalidatedConvert(operand.extraParams));
     return Operand{
-            .type = NN_TRY(unvalidatedConvert(operand.type)),
+            .type = type,
             .dimensions = operand.dimensions,
             .numberOfConsumers = 0,
             .scale = operand.scale,
             .zeroPoint = operand.zeroPoint,
-            .lifetime = NN_TRY(unvalidatedConvert(operand.lifetime)),
-            .location = NN_TRY(unvalidatedConvert(operand.location)),
-            .extraParams = NN_TRY(unvalidatedConvert(operand.extraParams)),
+            .lifetime = lifetime,
+            .location = location,
+            .extraParams = std::move(extraParams),
     };
 }
 
@@ -527,13 +559,18 @@
                << "Model cannot be unvalidatedConverted because it contains pointer-based memory";
     }
 
+    auto main = NN_TRY(unvalidatedConvert(model.main));
+    auto referenced = NN_TRY(unvalidatedConvert(model.referenced));
+    auto operandValues = NN_TRY(unvalidatedConvert(model.operandValues));
+    auto pools = NN_TRY(unvalidatedConvert(model.pools));
+    auto extensionNameToPrefix = NN_TRY(unvalidatedConvert(model.extensionNameToPrefix));
     return Model{
-            .main = NN_TRY(unvalidatedConvert(model.main)),
-            .referenced = NN_TRY(unvalidatedConvert(model.referenced)),
-            .operandValues = NN_TRY(unvalidatedConvert(model.operandValues)),
-            .pools = NN_TRY(unvalidatedConvert(model.pools)),
+            .main = std::move(main),
+            .referenced = std::move(referenced),
+            .operandValues = std::move(operandValues),
+            .pools = std::move(pools),
             .relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16,
-            .extensionNameToPrefix = NN_TRY(unvalidatedConvert(model.extensionNameToPrefix)),
+            .extensionNameToPrefix = std::move(extensionNameToPrefix),
     };
 }
 
@@ -548,9 +585,10 @@
         operands[i].numberOfConsumers = numberOfConsumers[i];
     }
 
+    auto operations = NN_TRY(unvalidatedConvert(subgraph.operations));
     return Subgraph{
             .operands = std::move(operands),
-            .operations = NN_TRY(unvalidatedConvert(subgraph.operations)),
+            .operations = std::move(operations),
             .inputIndexes = subgraph.inputIndexes,
             .outputIndexes = subgraph.outputIndexes,
     };
@@ -574,10 +612,13 @@
                << "Request cannot be unvalidatedConverted because it contains pointer-based memory";
     }
 
+    auto inputs = NN_TRY(unvalidatedConvert(request.inputs));
+    auto outputs = NN_TRY(unvalidatedConvert(request.outputs));
+    auto pools = NN_TRY(unvalidatedConvert(request.pools));
     return Request{
-            .inputs = NN_TRY(unvalidatedConvert(request.inputs)),
-            .outputs = NN_TRY(unvalidatedConvert(request.outputs)),
-            .pools = NN_TRY(unvalidatedConvert(request.pools)),
+            .inputs = std::move(inputs),
+            .outputs = std::move(outputs),
+            .pools = std::move(pools),
     };
 }
 
diff --git a/neuralnetworks/1.3/vts/functional/Android.bp b/neuralnetworks/1.3/vts/functional/Android.bp
index 9fa0f0a..07071cc 100644
--- a/neuralnetworks/1.3/vts/functional/Android.bp
+++ b/neuralnetworks/1.3/vts/functional/Android.bp
@@ -92,7 +92,6 @@
         "libneuralnetworks_headers",
     ],
     test_suites: [
-        "general-tests",
         "vts",
     ],
 }
diff --git a/neuralnetworks/1.3/vts/functional/CompilationCachingTests.cpp b/neuralnetworks/1.3/vts/functional/CompilationCachingTests.cpp
index a2013ec..f2cfa3f 100644
--- a/neuralnetworks/1.3/vts/functional/CompilationCachingTests.cpp
+++ b/neuralnetworks/1.3/vts/functional/CompilationCachingTests.cpp
@@ -1253,7 +1253,7 @@
         FILE* pFile = fopen(filename.c_str(), "a");
         uint32_t appendLength = getRandomInt(1, 256);
         for (uint32_t i = 0; i < appendLength; i++) {
-            ASSERT_NE(fputc(getRandomInt<uint8_t>(0, 255), pFile), EOF);
+            ASSERT_NE(fputc(getRandomInt<uint16_t>(0, 255), pFile), EOF);
         }
         fclose(pFile);
         *skip = false;
diff --git a/neuralnetworks/TEST_MAPPING b/neuralnetworks/TEST_MAPPING
index d296828..3218206 100644
--- a/neuralnetworks/TEST_MAPPING
+++ b/neuralnetworks/TEST_MAPPING
@@ -17,54 +17,10 @@
     },
     {
       "name": "neuralnetworks_utils_hal_aidl_test"
-    },
-    {
-      "name": "VtsHalNeuralnetworksV1_0TargetTest",
-      "options": [
-        {
-          // Do not use any sample driver except sample-all in order to reduce
-          // testing time. The other sample drivers (fast-float, quant, etc.)
-          // are subsets of sample-all.
-          "include-filter": "-*sample_float_fast*:*sample_float_slow*:*sample_minimal*:*sample_quant*"
-        }
-      ]
-    },
-    {
-      "name": "VtsHalNeuralnetworksV1_1TargetTest",
-      "options": [
-        {
-          // Do not use any sample driver except sample-all in order to reduce
-          // testing time. The other sample drivers (fast-float, quant, etc.)
-          // are subsets of sample-all.
-          "include-filter": "-*sample_float_fast*:*sample_float_slow*:*sample_minimal*:*sample_quant*"
-        }
-      ]
     }
   ],
   "presubmit-large": [
     {
-      "name": "VtsHalNeuralnetworksV1_2TargetTest",
-      "options": [
-        {
-          // Do not use any sample driver except sample-all in order to reduce
-          // testing time. The other sample drivers (fast-float, quant, etc.)
-          // are subsets of sample-all.
-          "include-filter": "-*sample_float_fast*:*sample_float_slow*:*sample_minimal*:*sample_quant*"
-        }
-      ]
-    },
-    {
-      "name": "VtsHalNeuralnetworksV1_3TargetTest",
-      "options": [
-        {
-          // Do not use any sample driver except sample-all in order to reduce
-          // testing time. The other sample drivers (fast-float, quant, etc.)
-          // are subsets of sample-all.
-          "include-filter": "-*sample_float_fast*:*sample_float_slow*:*sample_minimal*:*sample_quant*"
-        }
-      ]
-    },
-    {
       "name": "VtsHalNeuralnetworksTargetTest",
       "options": [
         {
diff --git a/neuralnetworks/aidl/utils/src/Conversions.cpp b/neuralnetworks/aidl/utils/src/Conversions.cpp
index 081e3d7..47c72b4 100644
--- a/neuralnetworks/aidl/utils/src/Conversions.cpp
+++ b/neuralnetworks/aidl/utils/src/Conversions.cpp
@@ -177,22 +177,28 @@
     auto table =
             NN_TRY(Capabilities::OperandPerformanceTable::create(std::move(operandPerformance)));
 
+    const auto relaxedFloat32toFloat16PerformanceScalar =
+            NN_TRY(unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceScalar));
+    const auto relaxedFloat32toFloat16PerformanceTensor =
+            NN_TRY(unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceTensor));
+    const auto ifPerformance = NN_TRY(unvalidatedConvert(capabilities.ifPerformance));
+    const auto whilePerformance = NN_TRY(unvalidatedConvert(capabilities.whilePerformance));
     return Capabilities{
-            .relaxedFloat32toFloat16PerformanceScalar = NN_TRY(
-                    unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceScalar)),
-            .relaxedFloat32toFloat16PerformanceTensor = NN_TRY(
-                    unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceTensor)),
+            .relaxedFloat32toFloat16PerformanceScalar = relaxedFloat32toFloat16PerformanceScalar,
+            .relaxedFloat32toFloat16PerformanceTensor = relaxedFloat32toFloat16PerformanceTensor,
             .operandPerformance = std::move(table),
-            .ifPerformance = NN_TRY(unvalidatedConvert(capabilities.ifPerformance)),
-            .whilePerformance = NN_TRY(unvalidatedConvert(capabilities.whilePerformance)),
+            .ifPerformance = ifPerformance,
+            .whilePerformance = whilePerformance,
     };
 }
 
 GeneralResult<Capabilities::OperandPerformance> unvalidatedConvert(
         const aidl_hal::OperandPerformance& operandPerformance) {
+    const auto type = NN_TRY(unvalidatedConvert(operandPerformance.type));
+    const auto info = NN_TRY(unvalidatedConvert(operandPerformance.info));
     return Capabilities::OperandPerformance{
-            .type = NN_TRY(unvalidatedConvert(operandPerformance.type)),
-            .info = NN_TRY(unvalidatedConvert(operandPerformance.info)),
+            .type = type,
+            .info = info,
     };
 }
 
@@ -228,10 +234,13 @@
 }
 
 GeneralResult<Operation> unvalidatedConvert(const aidl_hal::Operation& operation) {
+    const auto type = NN_TRY(unvalidatedConvert(operation.type));
+    auto inputs = NN_TRY(toUnsigned(operation.inputs));
+    auto outputs = NN_TRY(toUnsigned(operation.outputs));
     return Operation{
-            .type = NN_TRY(unvalidatedConvert(operation.type)),
-            .inputs = NN_TRY(toUnsigned(operation.inputs)),
-            .outputs = NN_TRY(toUnsigned(operation.outputs)),
+            .type = type,
+            .inputs = std::move(inputs),
+            .outputs = std::move(outputs),
     };
 }
 
@@ -241,14 +250,19 @@
 }
 
 GeneralResult<Operand> unvalidatedConvert(const aidl_hal::Operand& operand) {
+    const auto type = NN_TRY(unvalidatedConvert(operand.type));
+    auto dimensions = NN_TRY(toUnsigned(operand.dimensions));
+    const auto lifetime = NN_TRY(unvalidatedConvert(operand.lifetime));
+    const auto location = NN_TRY(unvalidatedConvert(operand.location));
+    auto extraParams = NN_TRY(unvalidatedConvert(operand.extraParams));
     return Operand{
-            .type = NN_TRY(unvalidatedConvert(operand.type)),
-            .dimensions = NN_TRY(toUnsigned(operand.dimensions)),
+            .type = type,
+            .dimensions = std::move(dimensions),
             .scale = operand.scale,
             .zeroPoint = operand.zeroPoint,
-            .lifetime = NN_TRY(unvalidatedConvert(operand.lifetime)),
-            .location = NN_TRY(unvalidatedConvert(operand.location)),
-            .extraParams = NN_TRY(unvalidatedConvert(operand.extraParams)),
+            .lifetime = lifetime,
+            .location = location,
+            .extraParams = std::move(extraParams),
     };
 }
 
@@ -280,22 +294,31 @@
 }
 
 GeneralResult<Model> unvalidatedConvert(const aidl_hal::Model& model) {
+    auto main = NN_TRY(unvalidatedConvert(model.main));
+    auto referenced = NN_TRY(unvalidatedConvert(model.referenced));
+    auto operandValues = NN_TRY(unvalidatedConvert(model.operandValues));
+    auto pools = NN_TRY(unvalidatedConvert(model.pools));
+    auto extensionNameToPrefix = NN_TRY(unvalidatedConvert(model.extensionNameToPrefix));
     return Model{
-            .main = NN_TRY(unvalidatedConvert(model.main)),
-            .referenced = NN_TRY(unvalidatedConvert(model.referenced)),
-            .operandValues = NN_TRY(unvalidatedConvert(model.operandValues)),
-            .pools = NN_TRY(unvalidatedConvert(model.pools)),
+            .main = std::move(main),
+            .referenced = std::move(referenced),
+            .operandValues = std::move(operandValues),
+            .pools = std::move(pools),
             .relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16,
-            .extensionNameToPrefix = NN_TRY(unvalidatedConvert(model.extensionNameToPrefix)),
+            .extensionNameToPrefix = std::move(extensionNameToPrefix),
     };
 }
 
 GeneralResult<Model::Subgraph> unvalidatedConvert(const aidl_hal::Subgraph& subgraph) {
+    auto operands = NN_TRY(unvalidatedConvert(subgraph.operands));
+    auto operations = NN_TRY(unvalidatedConvert(subgraph.operations));
+    auto inputIndexes = NN_TRY(toUnsigned(subgraph.inputIndexes));
+    auto outputIndexes = NN_TRY(toUnsigned(subgraph.outputIndexes));
     return Model::Subgraph{
-            .operands = NN_TRY(unvalidatedConvert(subgraph.operands)),
-            .operations = NN_TRY(unvalidatedConvert(subgraph.operations)),
-            .inputIndexes = NN_TRY(toUnsigned(subgraph.inputIndexes)),
-            .outputIndexes = NN_TRY(toUnsigned(subgraph.outputIndexes)),
+            .operands = std::move(operands),
+            .operations = std::move(operations),
+            .inputIndexes = std::move(inputIndexes),
+            .outputIndexes = std::move(outputIndexes),
     };
 }
 
@@ -308,9 +331,10 @@
 }
 
 GeneralResult<Extension> unvalidatedConvert(const aidl_hal::Extension& extension) {
+    auto operandTypes = NN_TRY(unvalidatedConvert(extension.operandTypes));
     return Extension{
             .name = extension.name,
-            .operandTypes = NN_TRY(unvalidatedConvert(extension.operandTypes)),
+            .operandTypes = std::move(operandTypes),
     };
 }
 
@@ -326,8 +350,9 @@
 }
 
 GeneralResult<OutputShape> unvalidatedConvert(const aidl_hal::OutputShape& outputShape) {
+    auto dimensions = NN_TRY(toUnsigned(outputShape.dimensions));
     return OutputShape{
-            .dimensions = NN_TRY(toUnsigned(outputShape.dimensions)),
+            .dimensions = std::move(dimensions),
             .isSufficient = outputShape.isSufficient,
     };
 }
@@ -346,8 +371,9 @@
                 return NN_ERROR() << "Memory: size must be <= std::numeric_limits<size_t>::max()";
             }
 
+            auto fd = NN_TRY(dupFd(ashmem.fd.get()));
             auto handle = Memory::Ashmem{
-                    .fd = NN_TRY(dupFd(ashmem.fd.get())),
+                    .fd = std::move(fd),
                     .size = static_cast<size_t>(ashmem.size),
             };
             return std::make_shared<const Memory>(Memory{.handle = std::move(handle)});
@@ -426,7 +452,8 @@
 }
 
 GeneralResult<BufferDesc> unvalidatedConvert(const aidl_hal::BufferDesc& bufferDesc) {
-    return BufferDesc{.dimensions = NN_TRY(toUnsigned(bufferDesc.dimensions))};
+    auto dimensions = NN_TRY(toUnsigned(bufferDesc.dimensions));
+    return BufferDesc{.dimensions = std::move(dimensions)};
 }
 
 GeneralResult<BufferRole> unvalidatedConvert(const aidl_hal::BufferRole& bufferRole) {
@@ -440,20 +467,25 @@
 }
 
 GeneralResult<Request> unvalidatedConvert(const aidl_hal::Request& request) {
+    auto inputs = NN_TRY(unvalidatedConvert(request.inputs));
+    auto outputs = NN_TRY(unvalidatedConvert(request.outputs));
+    auto pools = NN_TRY(unvalidatedConvert(request.pools));
     return Request{
-            .inputs = NN_TRY(unvalidatedConvert(request.inputs)),
-            .outputs = NN_TRY(unvalidatedConvert(request.outputs)),
-            .pools = NN_TRY(unvalidatedConvert(request.pools)),
+            .inputs = std::move(inputs),
+            .outputs = std::move(outputs),
+            .pools = std::move(pools),
     };
 }
 
 GeneralResult<Request::Argument> unvalidatedConvert(const aidl_hal::RequestArgument& argument) {
     const auto lifetime = argument.hasNoValue ? Request::Argument::LifeTime::NO_VALUE
                                               : Request::Argument::LifeTime::POOL;
+    const auto location = NN_TRY(unvalidatedConvert(argument.location));
+    auto dimensions = NN_TRY(toUnsigned(argument.dimensions));
     return Request::Argument{
             .lifetime = lifetime,
-            .location = NN_TRY(unvalidatedConvert(argument.location)),
-            .dimensions = NN_TRY(toUnsigned(argument.dimensions)),
+            .location = location,
+            .dimensions = std::move(dimensions),
     };
 }
 
@@ -720,8 +752,9 @@
 
 nn::GeneralResult<OperandPerformance> unvalidatedConvert(
         const nn::Capabilities::OperandPerformance& operandPerformance) {
-    return OperandPerformance{.type = NN_TRY(unvalidatedConvert(operandPerformance.type)),
-                              .info = NN_TRY(unvalidatedConvert(operandPerformance.info))};
+    const auto type = NN_TRY(unvalidatedConvert(operandPerformance.type));
+    const auto info = NN_TRY(unvalidatedConvert(operandPerformance.info));
+    return OperandPerformance{.type = type, .info = info};
 }
 
 nn::GeneralResult<std::vector<OperandPerformance>> unvalidatedConvert(
@@ -788,7 +821,8 @@
 }
 
 nn::GeneralResult<BufferDesc> unvalidatedConvert(const nn::BufferDesc& bufferDesc) {
-    return BufferDesc{.dimensions = NN_TRY(toSigned(bufferDesc.dimensions))};
+    auto dimensions = NN_TRY(toSigned(bufferDesc.dimensions));
+    return BufferDesc{.dimensions = std::move(dimensions)};
 }
 
 nn::GeneralResult<BufferRole> unvalidatedConvert(const nn::BufferRole& bufferRole) {
@@ -847,7 +881,8 @@
 }
 
 nn::GeneralResult<OutputShape> unvalidatedConvert(const nn::OutputShape& outputShape) {
-    return OutputShape{.dimensions = NN_TRY(toSigned(outputShape.dimensions)),
+    auto dimensions = NN_TRY(toSigned(outputShape.dimensions));
+    return OutputShape{.dimensions = std::move(dimensions),
                        .isSufficient = outputShape.isSufficient};
 }
 
@@ -915,14 +950,19 @@
 }
 
 nn::GeneralResult<Operand> unvalidatedConvert(const nn::Operand& operand) {
+    const auto type = NN_TRY(unvalidatedConvert(operand.type));
+    auto dimensions = NN_TRY(toSigned(operand.dimensions));
+    const auto lifetime = NN_TRY(unvalidatedConvert(operand.lifetime));
+    const auto location = NN_TRY(unvalidatedConvert(operand.location));
+    auto extraParams = NN_TRY(unvalidatedConvert(operand.extraParams));
     return Operand{
-            .type = NN_TRY(unvalidatedConvert(operand.type)),
-            .dimensions = NN_TRY(toSigned(operand.dimensions)),
+            .type = type,
+            .dimensions = std::move(dimensions),
             .scale = operand.scale,
             .zeroPoint = operand.zeroPoint,
-            .lifetime = NN_TRY(unvalidatedConvert(operand.lifetime)),
-            .location = NN_TRY(unvalidatedConvert(operand.location)),
-            .extraParams = NN_TRY(unvalidatedConvert(operand.extraParams)),
+            .lifetime = lifetime,
+            .location = location,
+            .extraParams = std::move(extraParams),
     };
 }
 
@@ -934,19 +974,26 @@
 }
 
 nn::GeneralResult<Operation> unvalidatedConvert(const nn::Operation& operation) {
+    const auto type = NN_TRY(unvalidatedConvert(operation.type));
+    auto inputs = NN_TRY(toSigned(operation.inputs));
+    auto outputs = NN_TRY(toSigned(operation.outputs));
     return Operation{
-            .type = NN_TRY(unvalidatedConvert(operation.type)),
-            .inputs = NN_TRY(toSigned(operation.inputs)),
-            .outputs = NN_TRY(toSigned(operation.outputs)),
+            .type = type,
+            .inputs = std::move(inputs),
+            .outputs = std::move(outputs),
     };
 }
 
 nn::GeneralResult<Subgraph> unvalidatedConvert(const nn::Model::Subgraph& subgraph) {
+    auto operands = NN_TRY(unvalidatedConvert(subgraph.operands));
+    auto operations = NN_TRY(unvalidatedConvert(subgraph.operations));
+    auto inputIndexes = NN_TRY(toSigned(subgraph.inputIndexes));
+    auto outputIndexes = NN_TRY(toSigned(subgraph.outputIndexes));
     return Subgraph{
-            .operands = NN_TRY(unvalidatedConvert(subgraph.operands)),
-            .operations = NN_TRY(unvalidatedConvert(subgraph.operations)),
-            .inputIndexes = NN_TRY(toSigned(subgraph.inputIndexes)),
-            .outputIndexes = NN_TRY(toSigned(subgraph.outputIndexes)),
+            .operands = std::move(operands),
+            .operations = std::move(operations),
+            .inputIndexes = std::move(inputIndexes),
+            .outputIndexes = std::move(outputIndexes),
     };
 }
 
@@ -969,13 +1016,18 @@
                << "Model cannot be unvalidatedConverted because it contains pointer-based memory";
     }
 
+    auto main = NN_TRY(unvalidatedConvert(model.main));
+    auto referenced = NN_TRY(unvalidatedConvert(model.referenced));
+    auto operandValues = NN_TRY(unvalidatedConvert(model.operandValues));
+    auto pools = NN_TRY(unvalidatedConvert(model.pools));
+    auto extensionNameToPrefix = NN_TRY(unvalidatedConvert(model.extensionNameToPrefix));
     return Model{
-            .main = NN_TRY(unvalidatedConvert(model.main)),
-            .referenced = NN_TRY(unvalidatedConvert(model.referenced)),
-            .operandValues = NN_TRY(unvalidatedConvert(model.operandValues)),
-            .pools = NN_TRY(unvalidatedConvert(model.pools)),
+            .main = std::move(main),
+            .referenced = std::move(referenced),
+            .operandValues = std::move(operandValues),
+            .pools = std::move(pools),
             .relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16,
-            .extensionNameToPrefix = NN_TRY(unvalidatedConvert(model.extensionNameToPrefix)),
+            .extensionNameToPrefix = std::move(extensionNameToPrefix),
     };
 }
 
@@ -989,10 +1041,13 @@
                << "Request cannot be unvalidatedConverted because it contains pointer-based memory";
     }
 
+    auto inputs = NN_TRY(unvalidatedConvert(request.inputs));
+    auto outputs = NN_TRY(unvalidatedConvert(request.outputs));
+    auto pools = NN_TRY(unvalidatedConvert(request.pools));
     return Request{
-            .inputs = NN_TRY(unvalidatedConvert(request.inputs)),
-            .outputs = NN_TRY(unvalidatedConvert(request.outputs)),
-            .pools = NN_TRY(unvalidatedConvert(request.pools)),
+            .inputs = std::move(inputs),
+            .outputs = std::move(outputs),
+            .pools = std::move(pools),
     };
 }
 
@@ -1003,10 +1058,12 @@
                << "Request cannot be unvalidatedConverted because it contains pointer-based memory";
     }
     const bool hasNoValue = requestArgument.lifetime == nn::Request::Argument::LifeTime::NO_VALUE;
+    const auto location = NN_TRY(unvalidatedConvert(requestArgument.location));
+    auto dimensions = NN_TRY(toSigned(requestArgument.dimensions));
     return RequestArgument{
             .hasNoValue = hasNoValue,
-            .location = NN_TRY(unvalidatedConvert(requestArgument.location)),
-            .dimensions = NN_TRY(toSigned(requestArgument.dimensions)),
+            .location = location,
+            .dimensions = std::move(dimensions),
     };
 }
 
@@ -1033,9 +1090,11 @@
 }
 
 nn::GeneralResult<Timing> unvalidatedConvert(const nn::Timing& timing) {
+    const auto timeOnDeviceNs = NN_TRY(unvalidatedConvert(timing.timeOnDevice));
+    const auto timeInDriverNs = NN_TRY(unvalidatedConvert(timing.timeInDriver));
     return Timing{
-            .timeOnDeviceNs = NN_TRY(unvalidatedConvert(timing.timeOnDevice)),
-            .timeInDriverNs = NN_TRY(unvalidatedConvert(timing.timeInDriver)),
+            .timeOnDeviceNs = timeOnDeviceNs,
+            .timeInDriverNs = timeInDriverNs,
     };
 }
 
@@ -1064,20 +1123,25 @@
 }
 
 nn::GeneralResult<Capabilities> unvalidatedConvert(const nn::Capabilities& capabilities) {
+    const auto relaxedFloat32toFloat16PerformanceTensor =
+            NN_TRY(unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceTensor));
+    const auto relaxedFloat32toFloat16PerformanceScalar =
+            NN_TRY(unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceScalar));
+    auto operandPerformance = NN_TRY(unvalidatedConvert(capabilities.operandPerformance));
+    const auto ifPerformance = NN_TRY(unvalidatedConvert(capabilities.ifPerformance));
+    const auto whilePerformance = NN_TRY(unvalidatedConvert(capabilities.whilePerformance));
     return Capabilities{
-            .relaxedFloat32toFloat16PerformanceTensor = NN_TRY(
-                    unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceTensor)),
-            .relaxedFloat32toFloat16PerformanceScalar = NN_TRY(
-                    unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceScalar)),
-            .operandPerformance = NN_TRY(unvalidatedConvert(capabilities.operandPerformance)),
-            .ifPerformance = NN_TRY(unvalidatedConvert(capabilities.ifPerformance)),
-            .whilePerformance = NN_TRY(unvalidatedConvert(capabilities.whilePerformance)),
+            .relaxedFloat32toFloat16PerformanceTensor = relaxedFloat32toFloat16PerformanceTensor,
+            .relaxedFloat32toFloat16PerformanceScalar = relaxedFloat32toFloat16PerformanceScalar,
+            .operandPerformance = std::move(operandPerformance),
+            .ifPerformance = ifPerformance,
+            .whilePerformance = whilePerformance,
     };
 }
 
 nn::GeneralResult<Extension> unvalidatedConvert(const nn::Extension& extension) {
-    return Extension{.name = extension.name,
-                     .operandTypes = NN_TRY(unvalidatedConvert(extension.operandTypes))};
+    auto operandTypes = NN_TRY(unvalidatedConvert(extension.operandTypes));
+    return Extension{.name = extension.name, .operandTypes = std::move(operandTypes)};
 }
 #ifdef NN_AIDL_V4_OR_ABOVE
 nn::GeneralResult<TokenValuePair> unvalidatedConvert(const nn::TokenValuePair& tokenValuePair) {
diff --git a/neuralnetworks/aidl/utils/src/Utils.cpp b/neuralnetworks/aidl/utils/src/Utils.cpp
index 76a0b07..f9b4f6e 100644
--- a/neuralnetworks/aidl/utils/src/Utils.cpp
+++ b/neuralnetworks/aidl/utils/src/Utils.cpp
@@ -51,8 +51,9 @@
 }
 
 nn::GeneralResult<common::NativeHandle> clone(const common::NativeHandle& handle) {
+    auto fds = NN_TRY(cloneVec(handle.fds));
     return common::NativeHandle{
-            .fds = NN_TRY(cloneVec(handle.fds)),
+            .fds = std::move(fds),
             .ints = handle.ints,
     };
 }
@@ -63,29 +64,32 @@
     switch (memory.getTag()) {
         case Memory::Tag::ashmem: {
             const auto& ashmem = memory.get<Memory::Tag::ashmem>();
+            auto fd = NN_TRY(clone(ashmem.fd));
             auto handle = common::Ashmem{
-                    .fd = NN_TRY(clone(ashmem.fd)),
+                    .fd = std::move(fd),
                     .size = ashmem.size,
             };
             return Memory::make<Memory::Tag::ashmem>(std::move(handle));
         }
         case Memory::Tag::mappableFile: {
             const auto& memFd = memory.get<Memory::Tag::mappableFile>();
+            auto fd = NN_TRY(clone(memFd.fd));
             auto handle = common::MappableFile{
                     .length = memFd.length,
                     .prot = memFd.prot,
-                    .fd = NN_TRY(clone(memFd.fd)),
+                    .fd = std::move(fd),
                     .offset = memFd.offset,
             };
             return Memory::make<Memory::Tag::mappableFile>(std::move(handle));
         }
         case Memory::Tag::hardwareBuffer: {
             const auto& hardwareBuffer = memory.get<Memory::Tag::hardwareBuffer>();
-            auto handle = graphics::common::HardwareBuffer{
+            auto handle = NN_TRY(clone(hardwareBuffer.handle));
+            auto ahwbHandle = graphics::common::HardwareBuffer{
                     .description = hardwareBuffer.description,
-                    .handle = NN_TRY(clone(hardwareBuffer.handle)),
+                    .handle = std::move(handle),
             };
-            return Memory::make<Memory::Tag::hardwareBuffer>(std::move(handle));
+            return Memory::make<Memory::Tag::hardwareBuffer>(std::move(ahwbHandle));
         }
     }
     return (NN_ERROR() << "Unrecognized Memory::Tag: " << underlyingType(memory.getTag()))
@@ -109,19 +113,21 @@
 }
 
 nn::GeneralResult<Request> clone(const Request& request) {
+    auto pools = NN_TRY(clone(request.pools));
     return Request{
             .inputs = request.inputs,
             .outputs = request.outputs,
-            .pools = NN_TRY(clone(request.pools)),
+            .pools = std::move(pools),
     };
 }
 
 nn::GeneralResult<Model> clone(const Model& model) {
+    auto pools = NN_TRY(clone(model.pools));
     return Model{
             .main = model.main,
             .referenced = model.referenced,
             .operandValues = model.operandValues,
-            .pools = NN_TRY(clone(model.pools)),
+            .pools = std::move(pools),
             .relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16,
             .extensionNameToPrefix = model.extensionNameToPrefix,
     };
diff --git a/neuralnetworks/aidl/vts/functional/CompilationCachingTests.cpp b/neuralnetworks/aidl/vts/functional/CompilationCachingTests.cpp
index 7451f7e..da0fe64 100644
--- a/neuralnetworks/aidl/vts/functional/CompilationCachingTests.cpp
+++ b/neuralnetworks/aidl/vts/functional/CompilationCachingTests.cpp
@@ -1068,7 +1068,7 @@
         FILE* pFile = fopen(filename.c_str(), "a");
         uint32_t appendLength = getRandomInt(1, 256);
         for (uint32_t i = 0; i < appendLength; i++) {
-            ASSERT_NE(fputc(getRandomInt<uint8_t>(0, 255), pFile), EOF);
+            ASSERT_NE(fputc(getRandomInt<uint16_t>(0, 255), pFile), EOF);
         }
         fclose(pFile);
         *skip = false;
diff --git a/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp b/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp
index 40f6cd1..dcf8451 100644
--- a/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp
+++ b/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp
@@ -659,6 +659,7 @@
                 ASSERT_NE(nullptr, burst.get());
 
                 // associate a unique slot with each memory pool
+                constexpr int64_t kIgnoreSlot = -1;
                 int64_t currentSlot = 0;
                 std::vector<int64_t> slots;
                 slots.reserve(request.pools.size());
@@ -667,7 +668,7 @@
                         slots.push_back(currentSlot++);
                     } else {
                         EXPECT_EQ(pool.getTag(), RequestMemoryPool::Tag::token);
-                        slots.push_back(-1);
+                        slots.push_back(kIgnoreSlot);
                     }
                 }
 
@@ -698,8 +699,10 @@
                 // Mark each slot as unused after the execution. This is unnecessary because the
                 // burst is freed after this scope ends, but this is here to test the functionality.
                 for (int64_t slot : slots) {
-                    ret = burst->releaseMemoryResource(slot);
-                    ASSERT_TRUE(ret.isOk()) << ret.getDescription();
+                    if (slot != kIgnoreSlot) {
+                        ret = burst->releaseMemoryResource(slot);
+                        ASSERT_TRUE(ret.isOk()) << ret.getDescription();
+                    }
                 }
 
                 break;
diff --git a/neuralnetworks/utils/adapter/aidl/src/Device.cpp b/neuralnetworks/utils/adapter/aidl/src/Device.cpp
index 1b90a1a..453ec9b 100644
--- a/neuralnetworks/utils/adapter/aidl/src/Device.cpp
+++ b/neuralnetworks/utils/adapter/aidl/src/Device.cpp
@@ -135,16 +135,26 @@
     return ndk::SharedRefBase::make<PreparedModel>(std::move(preparedModel));
 }
 
+void notify(IPreparedModelCallback* callback, ErrorStatus status,
+            const std::shared_ptr<IPreparedModel>& preparedModel) {
+    if (callback != nullptr) {
+        const auto ret = callback->notify(status, preparedModel);
+        if (!ret.isOk()) {
+            LOG(ERROR) << "IPreparedModelCallback::notify failed with " << ret.getDescription();
+        }
+    }
+}
+
 void notify(IPreparedModelCallback* callback, PrepareModelResult result) {
     if (!result.has_value()) {
         const auto& [message, status] = result.error();
         LOG(ERROR) << message;
         const auto aidlCode = utils::convert(status).value_or(ErrorStatus::GENERAL_FAILURE);
-        callback->notify(aidlCode, nullptr);
+        notify(callback, aidlCode, nullptr);
     } else {
         auto preparedModel = std::move(result).value();
         auto aidlPreparedModel = adaptPreparedModel(std::move(preparedModel));
-        callback->notify(ErrorStatus::NONE, std::move(aidlPreparedModel));
+        notify(callback, ErrorStatus::NONE, std::move(aidlPreparedModel));
     }
 }
 
@@ -284,7 +294,7 @@
     if (!result.has_value()) {
         const auto& [message, code] = result.error();
         const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE);
-        callback->notify(aidlCode, nullptr);
+        notify(callback.get(), aidlCode, nullptr);
         return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
                 static_cast<int32_t>(aidlCode), message.c_str());
     }
@@ -300,7 +310,7 @@
     if (!result.has_value()) {
         const auto& [message, code] = result.error();
         const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE);
-        callback->notify(aidlCode, nullptr);
+        notify(callback.get(), aidlCode, nullptr);
         return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
                 static_cast<int32_t>(aidlCode), message.c_str());
     }
@@ -317,7 +327,7 @@
     if (!result.has_value()) {
         const auto& [message, code] = result.error();
         const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE);
-        callback->notify(aidlCode, nullptr);
+        notify(callback.get(), aidlCode, nullptr);
         return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
                 static_cast<int32_t>(aidlCode), message.c_str());
     }
diff --git a/nfc/aidl/Android.bp b/nfc/aidl/Android.bp
index 30365f6..a2422b1 100644
--- a/nfc/aidl/Android.bp
+++ b/nfc/aidl/Android.bp
@@ -34,10 +34,5 @@
             sdk_version: "module_current",
             enabled: false,
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
     },
 }
diff --git a/oemlock/aidl/Android.bp b/oemlock/aidl/Android.bp
index d1930f9..1c19bb1 100644
--- a/oemlock/aidl/Android.bp
+++ b/oemlock/aidl/Android.bp
@@ -16,11 +16,6 @@
         java: {
             platform_apis: true,
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
     },
     versions: ["1"],
 }
diff --git a/power/aidl/Android.bp b/power/aidl/Android.bp
index c722795..63a40ed 100644
--- a/power/aidl/Android.bp
+++ b/power/aidl/Android.bp
@@ -35,11 +35,6 @@
         java: {
             platform_apis: true,
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
     },
     versions: [
         "1",
diff --git a/power/stats/aidl/Android.bp b/power/stats/aidl/Android.bp
index 48d3c51..b1b2515 100644
--- a/power/stats/aidl/Android.bp
+++ b/power/stats/aidl/Android.bp
@@ -32,11 +32,6 @@
         java: {
             platform_apis: true,
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
         cpp: {
             enabled: true,
         },
diff --git a/radio/aidl/Android.bp b/radio/aidl/Android.bp
index e1808af..cfd6ebf 100644
--- a/radio/aidl/Android.bp
+++ b/radio/aidl/Android.bp
@@ -20,11 +20,6 @@
         java: {
             sdk_version: "module_current",
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
     },
 }
 
@@ -42,11 +37,6 @@
         java: {
             sdk_version: "module_current",
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
     },
 }
 
@@ -64,11 +54,6 @@
         java: {
             sdk_version: "module_current",
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
     },
 }
 
@@ -86,11 +71,6 @@
         java: {
             sdk_version: "module_current",
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
     },
 }
 
@@ -108,11 +88,6 @@
         java: {
             sdk_version: "module_current",
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
     },
 }
 
@@ -130,11 +105,6 @@
         java: {
             sdk_version: "module_current",
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
     },
 }
 
@@ -155,11 +125,6 @@
         java: {
             sdk_version: "module_current",
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
     },
 }
 
@@ -177,10 +142,5 @@
         java: {
             sdk_version: "module_current",
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
     },
 }
diff --git a/radio/aidl/vts/radio_config_test.cpp b/radio/aidl/vts/radio_config_test.cpp
index 5e1c811..258b172 100644
--- a/radio/aidl/vts/radio_config_test.cpp
+++ b/radio/aidl/vts/radio_config_test.cpp
@@ -59,6 +59,7 @@
     serial = GetRandomSerialNumber();
     ndk::ScopedAStatus res = radio_config->getHalDeviceCapabilities(serial);
     ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
     ALOGI("getHalDeviceCapabilities, rspInfo.error = %s\n",
           toString(radioRsp_config->rspInfo.error).c_str());
 }
@@ -70,6 +71,7 @@
     serial = GetRandomSerialNumber();
     ndk::ScopedAStatus res = radio_config->getSimSlotsStatus(serial);
     ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
     ALOGI("getSimSlotsStatus, rspInfo.error = %s\n",
           toString(radioRsp_config->rspInfo.error).c_str());
 }
@@ -166,31 +168,60 @@
  * Test IRadioConfig.setSimSlotsMapping() for the response returned.
  */
 TEST_P(RadioConfigTest, setSimSlotsMapping) {
-    serial = GetRandomSerialNumber();
-    SlotPortMapping slotPortMapping;
-    slotPortMapping.physicalSlotId = 0;
-    slotPortMapping.portId = 0;
-    std::vector<SlotPortMapping> slotPortMappingList = {slotPortMapping};
-    if (isDsDsEnabled()) {
-        slotPortMapping.physicalSlotId = 1;
-        slotPortMappingList.push_back(slotPortMapping);
-    } else if (isTsTsEnabled()) {
-        slotPortMapping.physicalSlotId = 1;
-        slotPortMappingList.push_back(slotPortMapping);
-        slotPortMapping.physicalSlotId = 2;
-        slotPortMappingList.push_back(slotPortMapping);
-    }
-    ndk::ScopedAStatus res = radio_config->setSimSlotsMapping(serial, slotPortMappingList);
-    ASSERT_OK(res);
-    EXPECT_EQ(std::cv_status::no_timeout, wait());
-    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_config->rspInfo.type);
-    EXPECT_EQ(serial, radioRsp_config->rspInfo.serial);
-    ALOGI("setSimSlotsMapping, rspInfo.error = %s\n",
-          toString(radioRsp_config->rspInfo.error).c_str());
-    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_config->rspInfo.error, {RadioError::NONE}));
+    // get slot status and set SIM slots mapping based on the result.
+    updateSimSlotStatus();
+    if (radioRsp_config->rspInfo.error == RadioError::NONE) {
+        SlotPortMapping slotPortMapping;
+        // put invalid value at first and adjust by slotStatusResponse.
+        slotPortMapping.physicalSlotId = -1;
+        slotPortMapping.portId = -1;
+        std::vector<SlotPortMapping> slotPortMappingList = {slotPortMapping};
+        if (isDsDsEnabled()) {
+            slotPortMappingList.push_back(slotPortMapping);
+        } else if (isTsTsEnabled()) {
+            slotPortMappingList.push_back(slotPortMapping);
+            slotPortMappingList.push_back(slotPortMapping);
+        }
+        for (size_t i = 0; i < radioRsp_config->simSlotStatus.size(); i++) {
+            ASSERT_TRUE(radioRsp_config->simSlotStatus[i].portInfo.size() > 0);
+            for (size_t j = 0; j < radioRsp_config->simSlotStatus[i].portInfo.size(); j++) {
+                if (radioRsp_config->simSlotStatus[i].portInfo[j].portActive) {
+                    int32_t logicalSlotId =
+                            radioRsp_config->simSlotStatus[i].portInfo[j].logicalSlotId;
+                    // logicalSlotId should be 0 or positive numbers if the port
+                    // is active.
+                    EXPECT_GE(logicalSlotId, 0);
+                    // logicalSlotId should be less than the maximum number of
+                    // supported SIM slots.
+                    EXPECT_LT(logicalSlotId, slotPortMappingList.size());
+                    if (logicalSlotId >= 0 && logicalSlotId < slotPortMappingList.size()) {
+                        slotPortMappingList[logicalSlotId].physicalSlotId = i;
+                        slotPortMappingList[logicalSlotId].portId = j;
+                    }
+                }
+            }
+        }
 
-    // Give some time for modem to fully switch SIM configuration
-    sleep(MODEM_SET_SIM_SLOT_MAPPING_DELAY_IN_SECONDS);
+        // set SIM slots mapping
+        for (size_t i = 0; i < slotPortMappingList.size(); i++) {
+            // physicalSlotId and portId should be 0 or positive numbers for the
+            // input of setSimSlotsMapping.
+            EXPECT_GE(slotPortMappingList[i].physicalSlotId, 0);
+            EXPECT_GE(slotPortMappingList[i].portId, 0);
+        }
+        serial = GetRandomSerialNumber();
+        ndk::ScopedAStatus res = radio_config->setSimSlotsMapping(serial, slotPortMappingList);
+        ASSERT_OK(res);
+        EXPECT_EQ(std::cv_status::no_timeout, wait());
+        EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_config->rspInfo.type);
+        EXPECT_EQ(serial, radioRsp_config->rspInfo.serial);
+        ALOGI("setSimSlotsMapping, rspInfo.error = %s\n",
+              toString(radioRsp_config->rspInfo.error).c_str());
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_config->rspInfo.error, {RadioError::NONE}));
+
+        // Give some time for modem to fully switch SIM configuration
+        sleep(MODEM_SET_SIM_SLOT_MAPPING_DELAY_IN_SECONDS);
+    }
 }
 
 /*
@@ -207,12 +238,24 @@
     EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_config->rspInfo.type);
     EXPECT_EQ(serial, radioRsp_config->rspInfo.serial);
     if (radioRsp_config->rspInfo.error == RadioError::NONE) {
+        uint8_t simCount = 0;
         // check if cardState is present, portInfo size should be more than 0
         for (const SimSlotStatus& slotStatusResponse : radioRsp_config->simSlotStatus) {
             if (slotStatusResponse.cardState == CardStatus::STATE_PRESENT) {
                 ASSERT_TRUE(slotStatusResponse.portInfo.size() > 0);
-                ASSERT_TRUE(slotStatusResponse.portInfo[0].portActive);
+                for (const SimPortInfo& simPortInfo : slotStatusResponse.portInfo) {
+                    if (simPortInfo.portActive) {
+                        simCount++;
+                    }
+                }
             }
         }
+        if (isSsSsEnabled()) {
+            EXPECT_EQ(1, simCount);
+        } else if (isDsDsEnabled()) {
+            EXPECT_EQ(2, simCount);
+        } else if (isTsTsEnabled()) {
+            EXPECT_EQ(3, simCount);
+        }
     }
 }
diff --git a/radio/aidl/vts/radio_modem_response.cpp b/radio/aidl/vts/radio_modem_response.cpp
index d2715a8..20b44c5 100644
--- a/radio/aidl/vts/radio_modem_response.cpp
+++ b/radio/aidl/vts/radio_modem_response.cpp
@@ -24,6 +24,7 @@
 
 ndk::ScopedAStatus RadioModemResponse::enableModemResponse(const RadioResponseInfo& info) {
     rspInfo = info;
+    enableModemResponseToggle = !enableModemResponseToggle;
     parent_modem.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
diff --git a/radio/aidl/vts/radio_modem_utils.h b/radio/aidl/vts/radio_modem_utils.h
index 8779e0c..49e1891 100644
--- a/radio/aidl/vts/radio_modem_utils.h
+++ b/radio/aidl/vts/radio_modem_utils.h
@@ -37,7 +37,7 @@
 
     RadioResponseInfo rspInfo;
     bool isModemEnabled;
-    bool enableModemResponseToggle;
+    bool enableModemResponseToggle = false;
 
     virtual ndk::ScopedAStatus acknowledgeRequest(int32_t serial) override;
 
diff --git a/radio/aidl/vts/radio_network_response.cpp b/radio/aidl/vts/radio_network_response.cpp
index 666d617..2292c54 100644
--- a/radio/aidl/vts/radio_network_response.cpp
+++ b/radio/aidl/vts/radio_network_response.cpp
@@ -109,8 +109,9 @@
 }
 
 ndk::ScopedAStatus RadioNetworkResponse::getSystemSelectionChannelsResponse(
-        const RadioResponseInfo& info, const std::vector<RadioAccessSpecifier>& /*specifier*/) {
+        const RadioResponseInfo& info, const std::vector<RadioAccessSpecifier>& specifiers) {
     rspInfo = info;
+    this->specifiers = specifiers;
     parent_network.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
diff --git a/radio/aidl/vts/radio_network_test.cpp b/radio/aidl/vts/radio_network_test.cpp
index e1d508d..c83571e 100644
--- a/radio/aidl/vts/radio_network_test.cpp
+++ b/radio/aidl/vts/radio_network_test.cpp
@@ -592,6 +592,89 @@
 }
 
 /*
+ * Test IRadioNetwork.setSignalStrengthReportingCriteria() for multi-RANs per request
+ */
+TEST_P(RadioNetworkTest, setSignalStrengthReportingCriteria_multiRansPerRequest) {
+    SignalThresholdInfo signalThresholdInfoGeran;
+    signalThresholdInfoGeran.signalMeasurement = SignalThresholdInfo::SIGNAL_MEASUREMENT_TYPE_RSSI;
+    signalThresholdInfoGeran.hysteresisMs = 5000;
+    signalThresholdInfoGeran.hysteresisDb = 2;
+    signalThresholdInfoGeran.thresholds = {-109, -103, -97, -89};
+    signalThresholdInfoGeran.isEnabled = true;
+    signalThresholdInfoGeran.ran = AccessNetwork::GERAN;
+
+    SignalThresholdInfo signalThresholdInfoUtran;
+    signalThresholdInfoUtran.signalMeasurement = SignalThresholdInfo::SIGNAL_MEASUREMENT_TYPE_RSCP;
+    signalThresholdInfoUtran.hysteresisMs = 5000;
+    signalThresholdInfoUtran.hysteresisDb = 2;
+    signalThresholdInfoUtran.thresholds = {-110, -97, -73, -49, -25};
+    signalThresholdInfoUtran.isEnabled = true;
+    signalThresholdInfoUtran.ran = AccessNetwork::UTRAN;
+
+    SignalThresholdInfo signalThresholdInfoEutran;
+    signalThresholdInfoEutran.signalMeasurement = SignalThresholdInfo::SIGNAL_MEASUREMENT_TYPE_RSRP;
+    signalThresholdInfoEutran.hysteresisMs = 5000;
+    signalThresholdInfoEutran.hysteresisDb = 2;
+    signalThresholdInfoEutran.thresholds = {-128, -108, -88, -68};
+    signalThresholdInfoEutran.isEnabled = true;
+    signalThresholdInfoEutran.ran = AccessNetwork::EUTRAN;
+
+    SignalThresholdInfo signalThresholdInfoCdma2000;
+    signalThresholdInfoCdma2000.signalMeasurement =
+            SignalThresholdInfo::SIGNAL_MEASUREMENT_TYPE_RSSI;
+    signalThresholdInfoCdma2000.hysteresisMs = 5000;
+    signalThresholdInfoCdma2000.hysteresisDb = 2;
+    signalThresholdInfoCdma2000.thresholds = {-105, -90, -75, -65};
+    signalThresholdInfoCdma2000.isEnabled = true;
+    signalThresholdInfoCdma2000.ran = AccessNetwork::CDMA2000;
+
+    SignalThresholdInfo signalThresholdInfoNgran;
+    signalThresholdInfoNgran.signalMeasurement =
+            SignalThresholdInfo::SIGNAL_MEASUREMENT_TYPE_SSRSRP;
+    signalThresholdInfoNgran.hysteresisMs = 5000;
+    signalThresholdInfoNgran.hysteresisDb = 0;
+    signalThresholdInfoNgran.thresholds = {-105, -90, -75, -65};
+    signalThresholdInfoNgran.isEnabled = true;
+    signalThresholdInfoNgran.ran = AccessNetwork::NGRAN;
+
+    const static std::vector<SignalThresholdInfo> candidateSignalThresholdInfos = {
+            signalThresholdInfoGeran, signalThresholdInfoUtran, signalThresholdInfoEutran,
+            signalThresholdInfoCdma2000, signalThresholdInfoNgran};
+
+    std::vector<SignalThresholdInfo> supportedSignalThresholdInfos;
+    for (size_t i = 0; i < candidateSignalThresholdInfos.size(); i++) {
+        serial = GetRandomSerialNumber();
+        ndk::ScopedAStatus res = radio_network->setSignalStrengthReportingCriteria(
+                serial, {candidateSignalThresholdInfos[i]});
+        ASSERT_OK(res);
+        EXPECT_EQ(std::cv_status::no_timeout, wait());
+        if (radioRsp_network->rspInfo.error == RadioError::NONE) {
+            supportedSignalThresholdInfos.push_back(signalThresholdInfoGeran);
+        } else {
+            // Refer to IRadioNetworkResponse#setSignalStrengthReportingCriteriaResponse
+            ASSERT_TRUE(CheckAnyOfErrors(
+                    radioRsp_network->rspInfo.error,
+                    {RadioError::INVALID_ARGUMENTS, RadioError::RADIO_NOT_AVAILABLE}));
+        }
+    }
+
+    ASSERT_FALSE(supportedSignalThresholdInfos.empty());
+
+    serial = GetRandomSerialNumber();
+    ndk::ScopedAStatus res = radio_network->setSignalStrengthReportingCriteria(
+            serial, supportedSignalThresholdInfos);
+    ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+    ALOGI("setSignalStrengthReportingCriteria_multiRansPerRequest, rspInfo.error = %s\n",
+          toString(radioRsp_network->rspInfo.error).c_str());
+
+    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, {RadioError::NONE}));
+}
+
+/*
  * Test IRadioNetwork.setLinkCapacityReportingCriteria() invalid hysteresisDlKbps
  */
 TEST_P(RadioNetworkTest, setLinkCapacityReportingCriteria_invalidHysteresisDlKbps) {
@@ -686,6 +769,16 @@
  */
 TEST_P(RadioNetworkTest, setSystemSelectionChannels) {
     serial = GetRandomSerialNumber();
+    ndk::ScopedAStatus res = radio_network->getSystemSelectionChannels(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+    if (radioRsp_network->specifiers.size() == 0) {
+        // TODO (b/189255895): Throw an error once getSystemSelectionChannels is functional.
+        ALOGI("Skipped the test due to empty system selection channels.");
+        GTEST_SKIP();
+    }
+    std::vector<RadioAccessSpecifier> originalSpecifiers = radioRsp_network->specifiers;
 
     RadioAccessSpecifierBands bandP900 =
             RadioAccessSpecifierBands::make<RadioAccessSpecifierBands::geranBands>(
@@ -698,8 +791,8 @@
     RadioAccessSpecifier specifier850 = {
             .accessNetwork = AccessNetwork::GERAN, .bands = band850, .channels = {128, 129}};
 
-    ndk::ScopedAStatus res =
-            radio_network->setSystemSelectionChannels(serial, true, {specifierP900, specifier850});
+    serial = GetRandomSerialNumber();
+    res = radio_network->setSystemSelectionChannels(serial, true, {specifierP900, specifier850});
     ASSERT_OK(res);
     EXPECT_EQ(std::cv_status::no_timeout, wait());
     EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
@@ -712,8 +805,8 @@
 
     if (radioRsp_network->rspInfo.error == RadioError::NONE) {
         serial = GetRandomSerialNumber();
-        ndk::ScopedAStatus res = radio_network->setSystemSelectionChannels(
-                serial, false, {specifierP900, specifier850});
+        res = radio_network->setSystemSelectionChannels(serial, false,
+                                                        {specifierP900, specifier850});
         ASSERT_OK(res);
         EXPECT_EQ(std::cv_status::no_timeout, wait());
         EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
@@ -722,6 +815,12 @@
               toString(radioRsp_network->rspInfo.error).c_str());
         EXPECT_EQ(RadioError::NONE, radioRsp_network->rspInfo.error);
     }
+
+    serial = GetRandomSerialNumber();
+    res = radio_network->setSystemSelectionChannels(serial, true, originalSpecifiers);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
 }
 
 /*
diff --git a/radio/aidl/vts/radio_network_utils.h b/radio/aidl/vts/radio_network_utils.h
index 29ba2f2..29f20e8 100644
--- a/radio/aidl/vts/radio_network_utils.h
+++ b/radio/aidl/vts/radio_network_utils.h
@@ -45,6 +45,7 @@
     CellIdentity barringCellIdentity;
     std::vector<BarringInfo> barringInfoList;
     UsageSetting usageSetting;
+    std::vector<RadioAccessSpecifier> specifiers;
 
     virtual ndk::ScopedAStatus acknowledgeRequest(int32_t serial) override;
 
diff --git a/rebootescrow/aidl/Android.bp b/rebootescrow/aidl/Android.bp
index c764f86..39aaa07 100644
--- a/rebootescrow/aidl/Android.bp
+++ b/rebootescrow/aidl/Android.bp
@@ -18,11 +18,6 @@
         java: {
             platform_apis: true,
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
     },
     versions: ["1"],
 }
diff --git a/security/OWNERS b/security/OWNERS
index 54d820a..f061cd6 100644
--- a/security/OWNERS
+++ b/security/OWNERS
@@ -1,5 +1,7 @@
+# Please assign all bugs related to /hardware/interfaces/security to the team alias,
+# android-hardware-security@google.com.  This will get them auto-assigned to the on-call triage
+# engineer, ensuring quickest response.
 drysdale@google.com
 jbires@google.com
-jdanis@google.com
 seleneh@google.com
 swillden@google.com
diff --git a/security/dice/aidl/Android.bp b/security/dice/aidl/Android.bp
index 8c31e26..48c3e7e 100644
--- a/security/dice/aidl/Android.bp
+++ b/security/dice/aidl/Android.bp
@@ -34,9 +34,6 @@
             platform_apis: false,
         },
         ndk: {
-            vndk: {
-                enabled: true,
-            },
             apps_enabled: false,
             apex_available: [
                 "//apex_available:platform",
diff --git a/security/keymint/RKP_CHANGELOG.md b/security/keymint/RKP_CHANGELOG.md
new file mode 100644
index 0000000..67d68d4
--- /dev/null
+++ b/security/keymint/RKP_CHANGELOG.md
@@ -0,0 +1,18 @@
+# Remote Provisioning Changelog
+
+This document provides an exact description of which changes have occurred in the
+`IRemotelyProvisionedComponent` HAL interface in each Android release.
+
+## Releases
+* **Android S (12):** IRemotelyProvisionedComponent v1
+* **Android T (13):** IRemotelyProvisionedComponent v2
+
+## IRemotelyProvisionedComponent 1 -> 2
+* DeviceInfo
+ * Most entries are no longer optional.
+ * `att_id_state` is now `fused`. `fused` is used to indicate if SecureBoot is enabled.
+ * `version` is now `2`.
+ * `board` has been removed.
+ * `device` has been added.
+* RpcHardwareInfo
+ * `uniqueId` String added as a field in order to differentiate IRPC instances on device.
\ No newline at end of file
diff --git a/security/keymint/RKP_README.md b/security/keymint/RKP_README.md
new file mode 100644
index 0000000..89a2598
--- /dev/null
+++ b/security/keymint/RKP_README.md
@@ -0,0 +1,374 @@
+# Remote Provisioning HAL
+
+## Objective
+
+Design a HAL to support over-the-air provisioning of certificates for asymmetric
+keys. The HAL must interact effectively with Keystore (and other daemons) and
+protect device privacy and security.
+
+Note that this API is designed for KeyMint, but with the intention that it
+should be usable for other HALs that require certificate provisioning.
+Throughout this document we'll refer to the Keystore and KeyMint (formerly
+called Keymaster) components, but only for concreteness and convenience; those
+labels could be replaced with the names of any system and secure area
+components, respectively, that need certificates provisioned.
+
+## Key design decisions
+
+### General approach
+
+To more securely and reliably get keys and certificates to Android devices, we
+need to create a system where no party outside of the device's secure components
+is responsible for managing private keys. The strategy we've chosen is to
+deliver certificates over the air, using an asymmetric key pair created
+on-device in the factory as a root of trust to create an authenticated, secure
+channel. In this document we refer to this device-unique asymmetric key pair as
+Device Key (DK), its public half DK\_pub, its private half DK\_priv and a Device
+Key Certificate containing DK\_pub is denoted DKC.
+
+In order for the provisioning service to use DK (or a key authenticated by DK),
+it must know whether a given DK\_pub is known and trusted. To prove trust, we
+ask device OEMs to use one of two mechanisms:
+
+1.  (Preferred, recommended) The device OEM extracts DK\_pub from each device it
+    manufactures and uploads the public keys to a backend server.
+
+1.  The device OEM signs the DK\_pub to produce DKC and stores it on the device.
+    This has the advantage that they don't need to upload a DK\_pub for every
+    device immediately, but the disadvantage that they have to manage their
+    private signing keys, which means they have to have HSMs, configure and
+    secure them correctly, etc. Some backend providers may also require that the
+    OEM passes a factory security audit, and additionally promises to upload the
+    keys eventually as well.
+
+Note that in the full elaboration of this plan, DK\_pub is not the key used to
+establish a secure channel. Instead, DK\_pub is just the first public key in a
+chain of public keys which ends with the KeyMint public key, KM\_pub. All keys
+in the chain are device-unique and are joined in a certificate chain called the
+_Boot Certificate Chain_ (BCC), because in phases 2 and 3 of the remote
+provisioning project it is a chain of certificates corresponding to boot phases.
+We speak of the BCC even for phase 1, though in phase 1 it contains only a
+single self-signed DKC. This is described in more depth in the Phases section
+below.
+
+The BCC is authenticated by DK\_pub. To authenticate DK\_pub, we may have
+additional DKCs, from the SoC vendor, the device OEM, or both. Those are not
+part of the BCC but included as optional fields in the certificate request
+structure.
+
+The format of the the DK and BCC is specified within [Open Profile for DICE]
+(https://pigweed.googlesource.com/open-dice/+/HEAD/docs/specification.md).  To
+map phrases within this document to their equivalent terminology in the DICE
+specification, read the terms as follows: the DK corresponds to the UDS-derived
+key pair, DKC corresponds to the UDS certificate, and the BCC entries between
+DK\_pub and KM\_pub correspond to a chain of CDI certificates.
+
+Note: In addition to allowing 32 byte hash values for fields in the BCC payload,
+this spec additionally constrains some of the choices allowed in open-DICE.
+Specifically, these include which entries are required and which are optional in
+the BCC payload, and which algorithms are acceptable for use.
+
+### Phases
+
+RKP will be deployed in three phases, in terms of managing the root of trust
+binding between the device and the backend. To briefly describe them:
+
+* Phase 1: In phase 1 there is only one entry in the BCC; DK_pub and KM_pub are
+  the same key and the certificate is self-signed.
+* Phase 2: This is identical to phase 1, except it leverages the hardware root
+  of trust process described by DICE. Instead of trust being rooted in the TEE,
+  it is now rooted in the ROM by key material blown into fuses which are only
+  accessible to the ROM code.
+* Phase 3: This is identical to Phase 2, except the SoC vendor also does the
+  public key extraction or certification in their facilities, along with the OEM
+  doing it in the factory. This tightens up the "supply chain" and aims to make
+  key upload management more secure.
+
+### Privacy considerations
+
+Because DK and the DKCs are unique, immutable, unspoofable hardware-bound
+identifiers for the device, we must limit access to them to the absolute minimum
+possible. We do this in two ways:
+
+1.  We require KeyMint (which knows the BCC and either knows or at least has the
+ability to use KM\_priv) to refuse to ever divulge the BCC or additional
+signatures in plaintext. Instead, KeyMint requires the caller to provide an
+_Endpoint Encryption Key_ (EEK), with which it will encrypt the data before
+returning it. When provisioning production keys, the EEK must be signed by an
+approved authority whose public key is embedded in KeyMint. When certifying test
+keys, KeyMint will accept any EEK without checking the signature, but will
+encrypt and return a test BCC, rather than the real one.  The result is that
+only an entity in possession of an Trusted EEK (TEEK) private key can discover
+the plaintext of the production BCC.
+1.  Having thus limited access to the public keys to the trusted party only, we
+need to prevent the entity from abusing this unique device identifier.  The
+approach and mechanisms for doing that are beyond the scope of this document
+(they must be addressed in the server design), but generally involve taking care
+to ensure that we do not create any links between user IDs, IP addresses or
+issued certificates and the device pubkey.
+
+Although the details of the mechanisms for preventing the entity from abusing
+the BCC are, as stated, beyond the scope of this document, there is a subtle
+design decision here made specifically to enable abuse prevention. Specifically
+the `CertificateRequest` message sent to the server is (in
+[CDDL](https://tools.ietf.org/html/rfc8610)):
+
+```
+cddl
+CertificateRequest = [
+    DeviceInfo,
+    challenge : bstr,
+    ProtectedData,
+    MacedKeysToSign
+]
+```
+
+The public keys to be attested by the server are in `MacedKeysToSign`, which is
+a COSE\_Mac0 structure, MACed with a key that is found in `ProtectedData`. The
+MAC key is signed by DK\_pub.
+
+This structure allows the backend component that has access to EEK\_priv to
+decrypt `ProtectedData`, validate that the request is from an authorized device,
+check that the request is fresh and verify and extract the MAC key. That backend
+component never sees any data related to the keys to be signed, but can provide
+the MAC key to another backend component that can verify `MacedKeysToSign` and
+proceed to generate the certificates.
+
+In this way, we can partition the provisioning server into one component that
+knows the device identity, as represented by DK\_pub, but never sees the keys to
+be certified or certificates generated, and another component that sees the keys
+to be certified and certificates generated but does not know the device
+identity.
+
+### Key and cryptographic message formatting
+
+For simplicity of generation and parsing, compactness of wire representation,
+and flexibility and standardization, we've settled on using the CBOR Object
+Signing and Encryption (COSE) standard, defined in [RFC
+8152](https://tools.ietf.org/html/rfc8152). COSE provides compact and reasonably
+simple, yet easily-extensible, wire formats for:
+
+*   Keys,
+*   MACed messages,
+*   Signed messages, and
+*   Encrypted messages
+
+COSE enables easy layering of these message formats, such as using a COSE\_Sign
+structure to contain a COSE\_Key with a public key in it. We call this a
+"certificate".
+
+Due to the complexity of the standard, we'll spell out the COSE structures
+completely in this document and in the HAL and other documentation, so that
+although implementors will need to understand CBOR and the CBOR Data Definition
+Language ([CDDL, defined in RFC 8610](https://tools.ietf.org/html/rfc8610)),
+they shouldn't need to understand COSE.
+
+Note, however, that the certificate chains returned from the provisioning server
+are standard X.509 certificates.
+
+### Algorithm choices
+
+This document uses:
+
+*   ECDSA P-256 for attestation signing keys;
+*   Remote provisioning protocol signing keys:
+  *  Ed25519 / P-256
+*   ECDH keys:
+  *  X25519 / P-256
+*   AES-GCM for all encryption;
+*   SHA-256 for all message digesting;
+*   HMAC-SHA-256 for all MACing; and
+*   HKDF-SHA-256 for all key derivation.
+
+We believe that Curve25519 offers the best tradeoff in terms of security,
+efficiency and global trustworthiness, and that it is now sufficiently
+widely-used and widely-implemented to make it a practical choice.
+
+However, since Secure Elements (SE) do not currently offer support for curve
+25519, we are allowing implementations to instead make use of EC P-256 for
+signing and ECDH. To put it simply, the device unique key pair will be a P-256
+key pair for ECDSA instead of Ed25519, and the ProtectedData COSE\_Encrypt
+message will have its payload encrypted with P-256 ECDH key exchange instead of
+X25519.
+
+The CDDL in the rest of the document will use the '/' operator to show areas
+where either curve 25519 or P-256 may be used. Since there is no easy way to
+bind choices across different CDDL groups, it is important that the implementor
+stays consistent in which type is chosen. E.g. taking ES256 as the choice for
+algorithm implies the implementor should also choose the P256 public key group
+further down in the COSE structure.
+
+### Testability
+
+It's critical that the remote provisioning implementation be testable, to
+minimize the probability that broken devices are sold to end users. To support
+testing, the remote provisioning HAL methods take a `testMode` argument. Keys
+created in test mode are tagged to indicate this. The provisioning server will
+check for the test mode tag and issue test certificates that do not chain back
+to a trusted public key. In test mode, any EEK will be accepted, enabling
+testing tools to use EEKs for which they have the private key so they can
+validate the content of certificate requests. The BCC included in the
+`CertificateRequest` must contain freshly-generated keys, not the real BCC keys.
+
+Keystore (or similar) will need to be able to handle both testMode keys and
+production keys and keep them distinct, generating test certificate requests
+when asked with a test EEK and production certificate requests when asked with a
+production EEK. Likewise, the interface used to instruct Keystore to create keys
+will need to be able to specify whether test or production keys are desired.
+
+## Design
+
+### Certificate provisioning flow
+
+TODO(jbires): Replace this with a `.png` containing a sequence diagram.  The
+provisioning flow looks something like this:
+
+Provisioner -> Keystore: Prepare N keys
+Keystore -> KeyMint: generateKeyPair
+KeyMint -> KeyMint: Generate  key pair
+KeyMint --> Keystore: key\_blob,pubkey
+Keystore -> Keystore: Store key\_blob,pubkey
+Provisioner -> Server: Get TEEK
+Server --> Provisioner: TEEK
+Provisioner -> Keystore: genCertReq(N, TEEK)
+Keystore -> KeyMint: genCertReq(pubkeys, TEEK)
+KeyMint -> KeyMint: Sign pubkeys & encrypt BCC
+KeyMint --> Keystore: signature, encrypted BCC
+Keystore -> Keystore: Construct cert\_request
+Keystore --> Provisioner: cert\_request
+Provisioner --> Server: cert\_request
+Server -> Server: Validate cert\_request
+Server -> Server: Generate certificates
+Server --> Provisioner: certificates
+Provisioner -> Keystore: certificates
+Keystore -> Keystore: Store certificates
+
+The actors in the above diagram are:
+
+*   **Server** is the backend certificate provisioning server. It has access to
+    the uploaded device public keys and is responsible for providing encryption
+    keys, decrypting and validating requests, and generating certificates in
+    response to requests.
+*   **Provisioner** is an application that is responsible for communicating with
+    the server and all of the system components that require key certificates
+    from the server. It also implements the policy that defines how many key
+    pairs each client should keep in their pool.
+*   **Keystore** is the [Android keystore
+    daemon](https://developer.android.com/training/articles/keystore) (or, more
+    generally, whatever system component manages communications with a
+    particular secure aread component).
+*   **KeyMint** is the secure area component that manages cryptographic keys and
+    performs attestations (or perhaps some other secure area component).
+
+### `BCC`
+
+The _Boot Certificate Chain_ (BCC) is the chain of certificates that contains
+DK\_pub as well as other often device-unique certificates. The BCC is
+represented as a COSE\_Key containing DK\_pub followed by an array of
+COSE\_Sign1 "certificates" containing public keys and optional additional
+information, ordered from root to leaf, with each certificate signing the next.
+The first certificate in the array is signed by DK\_pub, the last certificate
+has the KeyMint (or whatever) signing key's public key, KM\_pub. In phase 1
+there is only one entry; DK\_pub and KM\_pub are the same key and the
+certificate is self-signed.
+
+Each COSE\_Sign1 certificate is a CBOR Web Token (CWT) as described in [RFC
+8392](https://tools.ietf.org/html/rfc8392) with additional fields as described
+in the Open Profile for DICE. Of these additional fields, only the
+_subjectPublicKey_ and _keyUsage_ fields are expected to be present for the
+KM\_pub entry (that is, the last entry) in a BCC, but all fields required by the
+Open Profile for DICE are expected for other entries (each of which corresponds
+to a particular firmware component or boot stage). The CWT fields _iss_ and
+_sub_ identify the issuer and subject of the certificate and are consistent
+along the BCC entries; the issuer of a given entry matches the subject of the
+previous entry.
+
+The BCC is designed to be constructed using the Open Profile for DICE. In this
+case the DK key pair is derived from the UDS as described by that profile and
+all BCC entries before the leaf are CBOR CDI certificates chained from DK\_pub.
+The KM key pair is not part of the derived DICE chain. It is generated (not
+derived) by the KeyMint module, certified by the last key in the DICE chain, and
+added as the leaf BCC entry. The key usage field in this leaf certificate must
+indicate the key is not used to sign certificates. If a UDS certificate is
+available on the device it should appear in the certificate request as the leaf
+of a DKCertChain in AdditionalDKSignatures (see
+[CertificateRequest](#certificaterequest)).
+
+The Open Profile for DICE allows for an arbitrary configuration descriptor. For
+BCC entries, this configuration descriptor is a CBOR map with the following
+optional fields. If no fields are relevant, an empty map should be encoded.
+Additional implementation-specific fields may be added using key values not in
+the range \[-70000, -70999\] (these are reserved for future additions here).
+
+```
+| Name              | Key    | Value type | Meaning                           |
+| ----------------- | ------ | ---------- | ----------------------------------|
+| Component name    | -70002 | tstr       | Name of firmware component / boot |
+:                   :        :            : stage                             :
+| Component version | -70003 | int        | Version of firmware component /   |
+:                   :        :            : boot stage                        :
+| Resettable        | -70004 | null       | If present, key changes on factory|
+:                   :        :            : reset                             :
+```
+
+Please see
+[ProtectedData.aidl](https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl)
+for a full CDDL definition of the BCC.
+
+### `CertificateRequest`
+
+The full CBOR message that will be sent to the server to request certificates
+is:
+
+```cddl
+CertificateRequest = [
+    DeviceInfo,
+    challenge : bstr,       // Provided by the server
+    ProtectedData,          // See ProtectedData.aidl
+    MacedKeysToSign         // See IRemotelyProvisionedComponent.aidl
+]
+
+DeviceInfo = [
+    VerifiedDeviceInfo,     // See DeviceInfo.aidl
+    UnverifiedDeviceInfo
+]
+
+// Unverified info is anything provided by the HLOS. Subject to change out of
+// step with the HAL.
+UnverifiedDeviceInfo = {
+    ? "fingerprint" : tstr,
+}
+
+```
+
+It will be the responsibility of Keystore and the Provisioner to construct the
+`CertificateRequest`. The HAL provides a method to generate the elements that
+need to be constructed on the secure side, which are the tag field of
+`MacedKeysToSign`, `VerifiedDeviceInfo`, and the ciphertext field of
+`ProtectedData`.
+
+### HAL
+
+The remote provisioning HAL provides a simple interface that can be implemented
+by multiple secure components that require remote provisioning. It would be
+slightly simpler to extend the KeyMint API, but that approach would only serve
+the needs of KeyMint, this is more general.
+
+NOTE the data structures defined in this HAL may look a little bloated and
+complex. This is because the COSE data structures are fully spelled-out; we
+could make it much more compact by not re-specifying the standardized elements
+and instead just referencing the standard, but it seems better to fully specify
+them. If the apparent complexity seems daunting, consider what the same would
+look like if traditional ASN.1 DER-based structures from X.509 and related
+standards were used and also fully elaborated.
+
+Please see the related HAL documentation directly in the source code at the
+following links:
+
+*   [IRemotelyProvisionedComponent
+    HAL](https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/keymint/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl)
+*   [ProtectedData](https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl)
+*   [MacedPublicKey](https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/keymint/aidl/android/hardware/security/keymint/MacedPublicKey.aidl)
+*   [RpcHardwareInfo](https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/keymint/aidl/android/hardware/security/keymint/RpcHardwareInfo.aidl)
+*   [DeviceInfo](https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/keymint/aidl/android/hardware/security/keymint/DeviceInfo.aidl)
+
diff --git a/security/keymint/aidl/Android.bp b/security/keymint/aidl/Android.bp
index c9ee1b3..73c7b97 100644
--- a/security/keymint/aidl/Android.bp
+++ b/security/keymint/aidl/Android.bp
@@ -22,9 +22,6 @@
             platform_apis: true,
         },
         ndk: {
-            vndk: {
-                enabled: true,
-            },
             apps_enabled: false,
         },
         rust: {
diff --git a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
index da02d54..926d105 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
@@ -196,12 +196,12 @@
  * derive a key that is used to encrypt the private/secret key material.
  *
  * The root of trust consists of a bitstring that must be derived from the public key used by
- * Verified Boot to verify the signature on the boot image and from the lock state of the
- * device.  If the public key is changed to allow a different system image to be used or if the
- * lock state is changed, then all of the IKeyMintDevice-protected keys created by the previous
- * system state must be unusable, unless the previous state is restored.  The goal is to increase
- * the value of the software-enforced key access controls by making it impossible for an attacker-
- * installed operating system to use IKeyMintDevice keys.
+ * Verified Boot to verify the signature on the boot image, from the lock state and from the
+ * Verified Boot state of the device.  If the public key is changed to allow a different system
+ * image to be used or if the lock state is changed, then all of the IKeyMintDevice-protected keys
+ * created by the previous system state must be unusable, unless the previous state is restored.
+ * The goal is to increase the value of the software-enforced key access controls by making it
+ * impossible for an attacker-installed operating system to use IKeyMintDevice keys.
  *
  * == Version Binding ==
  *
@@ -336,6 +336,17 @@
      * Only Tag::KEY_SIZE is required to generate an 3DES key, and its value must be 168.  If
      * omitted, generateKey must return ErrorCode::UNSUPPORTED_KEY_SIZE.
      *
+     * == HMAC Keys ==
+     *
+     * Tag::KEY_SIZE must be provided to generate an HMAC key, and its value must be >= 64 and a
+     * multiple of 8.  All devices must support key sizes up to 512 bits, but StrongBox devices must
+     * not support key sizes larger than 512 bits.  If omitted or invalid, generateKey() must return
+     * ErrorCode::UNSUPPORTED_KEY_SIZE.
+     *
+     * Tag::MIN_MAC_LENGTH must be provided, and must be a multiple of 8 in the range 64 to 512
+     * bits (inclusive). If omitted, generateKey must return ErrorCode::MISSING_MIN_MAC_LENGTH; if
+     * invalid, generateKey must return ErrorCode::UNSUPPORTED_MIN_MAC_LENGTH.
+     *
      * @param keyParams Key generation parameters are defined as KeyMintDevice tag/value pairs,
      *        provided in params.  See above for detailed specifications of which tags are required
      *        for which types of keys.
@@ -661,19 +672,19 @@
      *   structure, because it cannot add the DigestInfo structure.  Instead, the IKeyMintDevice
      *   must construct 0x00 || 0x01 || PS || 0x00 || M, where M is the provided message and PS is a
      *   random padding string at least eight bytes in length.  The size of the RSA key has to be at
-     *   least 11 bytes larger than the message, otherwise begin() must return
+     *   least 11 bytes larger than the message, otherwise finish() must return
      *   ErrorCode::INVALID_INPUT_LENGTH.
      *
      * o PaddingMode::RSA_PKCS1_1_1_5_ENCRYPT padding does not require a digest.
      *
-     * o PaddingMode::RSA_PSS padding requires a digest, which must match one of the padding values
+     * o PaddingMode::RSA_PSS padding requires a digest, which must match one of the digest values
      *   in the key authorizations, and which may not be Digest::NONE.  begin() must return
      *   ErrorCode::INCOMPATIBLE_DIGEST if this is not the case.  In addition, the size of the RSA
-     *   key must be at least 2 + D bytes larger than the output size of the digest, where D is the
-     *   size of the digest, in bytes.  Otherwise begin() must return
-     *   ErrorCode::INCOMPATIBLE_DIGEST.  The salt size must be D.
+     *   key must be at least (D + S + 9) bits, where D is the size of the digest (in bits) and
+     *   S is the size of the salt (in bits).  The salt size S must equal D, so the RSA key must
+     *   be at least (2*D + 9) bits. Otherwise begin() must return ErrorCode::INCOMPATIBLE_DIGEST.
      *
-     * o PaddingMode::RSA_OAEP padding requires a digest, which must match one of the padding values
+     * o PaddingMode::RSA_OAEP padding requires a digest, which must match one of the digest values
      *   in the key authorizations, and which may not be Digest::NONE.  begin() must return
      *   ErrorCode::INCOMPATIBLE_DIGEST if this is not the case.  RSA_OAEP padding also requires an
      *   MGF1 digest, specified with Tag::RSA_OAEP_MGF_DIGEST, which must match one of the MGF1
@@ -683,9 +694,9 @@
      *
      * -- EC Keys --
      *
-     * Private key operations (KeyPurpose::SIGN) need authorization of digest and padding, which
-     * means that the key authorizations must contain the specified values.  If not, begin() must
-     * return ErrorCode::INCOMPATIBLE_DIGEST.
+     * Private key operations (KeyPurpose::SIGN) need authorization of digest, which means that the
+     * key authorizations must contain the specified values.  If not, begin() must return
+     * ErrorCode::INCOMPATIBLE_DIGEST.
      *
      * -- AES Keys --
      *
@@ -804,7 +815,7 @@
     /**
      * Called by client to notify the IKeyMintDevice that the device has left the early boot
      * state, and that keys with the EARLY_BOOT_ONLY tag may no longer be used.  All attempts to use
-     * an EARLY_BOOT_ONLY key after this method is called must fail with Error::INVALID_KEY_BLOB.
+     * an EARLY_BOOT_ONLY key after this method is called must fail with Error::EARLY_BOOT_ENDED.
      */
     void earlyBootEnded();
 
@@ -873,7 +884,7 @@
      * The returned data is an encoded COSE_Mac0 structure, denoted MacedRootOfTrust in the
      * following CDDL schema.  Note that K_mac is the shared HMAC key used for auth tokens, etc.:
      *
-     *     MacedRootOfTrust = [               ; COSE_Mac0 (untagged)
+     *     MacedRootOfTrust = #6.17 [         ; COSE_Mac0 (tagged)
      *         protected: bstr .cbor {
      *             1 : 5,                     ; Algorithm : HMAC-256
      *         },
@@ -891,7 +902,7 @@
      *         payload : bstr .cbor RootOfTrust,
      *     ]
      *
-     *     RootOfTrust = [
+     *     RootOfTrust = #6.40001 [           ; Tag 40001 indicates RoT v1.
      *         verifiedBootKey : bstr .size 32,
      *         deviceLocked : bool,
      *         verifiedBootState : &VerifiedBootState,
diff --git a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl
index ca89555..c30c183 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl
@@ -242,7 +242,8 @@
      *   not a multiple of the AES block size, finish() must return
      *   ErrorCode::INVALID_INPUT_LENGTH.  If padding is PaddingMode::PKCS7, pad the data per the
      *   PKCS#7 specification, including adding an additional padding block if the data is a
-     *   multiple of the block length.
+     *   multiple of the block length.  If padding is PaddingMode::PKCS7 and decryption does not
+     *   result in valid padding, return ErrorCode::INVALID_ARGUMENT.
      *
      * o BlockMode::GCM.  During encryption, after processing all plaintext, compute the tag
      *   (Tag::MAC_LENGTH bytes) and append it to the returned ciphertext.  During decryption,
diff --git a/security/keymint/aidl/android/hardware/security/keymint/KeyCreationResult.aidl b/security/keymint/aidl/android/hardware/security/keymint/KeyCreationResult.aidl
index 57285a3..ae75579 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/KeyCreationResult.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/KeyCreationResult.aidl
@@ -99,8 +99,7 @@
      * X.509 certificates ordered such that each certificate is signed by the subsequent one, up to
      * the root which must be self-signed (or contain a fake signature in the case of case 4 above).
      * The first certificate in the chain signs the public key info of the newly-generated or
-     * newly-imported key pair.  In the attestation cases (1 and 2 above), the first certificate
-     * must also satisfy some other requirements:
+     * newly-imported key pair.  The first certificate must also satisfy some other requirements:
      *
      * o It must have the serial number provided in Tag::CERTIFICATE_SERIAL, or default to 1 if the
      *   tag is not provided.
@@ -119,7 +118,8 @@
      *    - the keyAgreement bit set iff the attested key has KeyPurpose::AGREE_KEY, and
      *    - the keyCertSignBit set iff the attested key has KeyPurpose::ATTEST_KEY.
      *
-     * o it must contain a KeyDescription attestation extension with OID 1.3.6.1.4.1.11129.2.1.17.
+     * In the attestation cases (1 and 2 above), the first certificate must contain a
+     * KeyDescription attestation extension with OID 1.3.6.1.4.1.11129.2.1.17.
      *
      * The KeyDescription content is defined by the following ASN.1 schema, which is mostly a
      * straightforward translation of the KeyMint tag/value parameter lists to ASN.1.
diff --git a/security/keymint/aidl/android/hardware/security/keymint/KeyPurpose.aidl b/security/keymint/aidl/android/hardware/security/keymint/KeyPurpose.aidl
index fd103ef..32e71a7 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/KeyPurpose.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/KeyPurpose.aidl
@@ -23,7 +23,7 @@
 @VintfStability
 @Backing(type="int")
 enum KeyPurpose {
-    /* Usable with RSA, 3DES and AES keys. */
+    /* Usable with 3DES and AES keys. */
     ENCRYPT = 0,
 
     /* Usable with RSA, 3DES and AES keys. */
@@ -32,7 +32,7 @@
     /* Usable with RSA, EC and HMAC keys. */
     SIGN = 2,
 
-    /* Usable with RSA, EC and HMAC keys. */
+    /* Usable with HMAC keys. */
     VERIFY = 3,
 
     /* 4 is reserved */
diff --git a/security/keymint/aidl/android/hardware/security/keymint/PaddingMode.aidl b/security/keymint/aidl/android/hardware/security/keymint/PaddingMode.aidl
index e71a9c9..6ff4b29 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/PaddingMode.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/PaddingMode.aidl
@@ -26,7 +26,7 @@
 @VintfStability
 @Backing(type="int")
 enum PaddingMode {
-    NONE = 1, /* deprecated */
+    NONE = 1,
     RSA_OAEP = 2,
     RSA_PSS = 3,
     RSA_PKCS1_1_5_ENCRYPT = 4,
diff --git a/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl b/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl
index 5024400..8b3875b 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl
@@ -18,13 +18,20 @@
 
 /**
  * ProtectedData contains the encrypted BCC and the ephemeral MAC key used to
- * authenticate the keysToSign (see keysToSignMac output argument).
+ * authenticate the keysToSign (see keysToSignMac output argument of
+ * IRemotelyProvisionedComponent.generateCertificateRequest).
  * @hide
  */
 @VintfStability
 parcelable ProtectedData {
     /**
-     * ProtectedData is a COSE_Encrypt structure, specified by the following CDDL
+     * ProtectedData is a COSE_Encrypt structure, encrypted with an AES key that is agreed upon
+     * using Elliptic-curve Diffie-Hellman. The contents of the structure are specified by the
+     * following CDDL [RFC8610].
+     *
+     * Notes:
+     *   - None of the CBOR in ProtectedData uses CBOR tags. If an implementation includes
+     *     tags, parsers may reject the data.
      *
      *     ProtectedData = [               // COSE_Encrypt
      *         protected: bstr .cbor {
@@ -34,13 +41,18 @@
      *             5 : bstr .size 12       // IV
      *         },
      *         ciphertext: bstr,           // AES-GCM-256(K, .cbor ProtectedDataPayload)
+     *                                     // Where the encryption key 'K' is derived as follows:
+     *                                     // ikm = ECDH(EEK_pub, Ephemeral_priv)
+     *                                     // salt = null
+     *                                     // info = .cbor Context (see below)
+     *                                     // K = HKDF-SHA-256(ikm, salt, info)
      *         recipients : [
      *             [                       // COSE_Recipient
      *                 protected : bstr .cbor {
      *                     1 : -25         // Algorithm : ECDH-ES + HKDF-256
      *                 },
      *                 unprotected : {
-     *                     -1 : PubKeyX25519 / PubKeyEcdhP256  // Of the sender
+     *                     -1 : PubKeyX25519 / PubKeyEcdhP256  // Ephemeral_pub
      *                     4 : bstr,       // KID : EEK ID
      *                 },
      *                 ciphertext : nil
@@ -48,14 +60,14 @@
      *         ]
      *     ]
      *
-     *     K = HKDF-256(ECDH(EEK_pub, Ephemeral_priv), Context)
-     *
-     *     Context = [                     // COSE_KDF_Context
+     *     // The COSE_KDF_Context that is used to derive the ProtectedData encryption key with
+     *     // HKDF. See details on use in ProtectedData comments above.
+     *     Context = [
      *         AlgorithmID : 3             // AES-GCM 256
      *         PartyUInfo : [
      *             identity : bstr "client"
      *             nonce : bstr .size 0,
-     *             other : bstr            // Ephemeral pubkey
+     *             other : bstr            // Ephemeral_pub
      *         ],
      *         PartyVInfo : [
      *             identity : bstr "server",
@@ -68,76 +80,106 @@
      *         ]
      *     ]
      *
+     *     // The data that is encrypted and included in ProtectedData ciphertext (see above).
      *     ProtectedDataPayload [
      *         SignedMac,
      *         Bcc,
      *         ? AdditionalDKSignatures,
      *     ]
+     *
+     *     // AdditionalDKSignatures allows the platform to provide additional certifications
+     *     // for the DK_pub. For example, this could be provided by the hardware vendor, who
+     *     // certifies all of their devices. The SignerName is a free-form string describing
+     *     // who generated the signature.
      *     AdditionalDKSignatures = {
      *         + SignerName => DKCertChain
      *     }
      *
+     *     // SignerName is a string identifier that indicates both the signing authority as
+     *     // well as the format of the DKCertChain
      *     SignerName = tstr
      *
      *     DKCertChain = [
-     *         2* Certificate                      // Root -> Leaf.  Root is the vendor
-     *                                             // self-signed cert, leaf contains DK_pub
+     *         2* X509Certificate       // Root -> ... -> Leaf. "Root" is the vendor self-signed
+     *                                  // cert, "Leaf" contains DK_pub. There may also be
+     *                                  // intermediate certificates between Root and Leaf.
      *     ]
      *
-     *     Certificate = COSE_Sign1 of a public key
+     *     // A bstr containing a DER-encoded X.509 certificate (RSA, NIST P-curve, or edDSA)
+     *     X509Certificate = bstr
      *
-     *     SignedMac = [                                  // COSE_Sign1
-     *         bstr .cbor {                               // Protected params
-     *             1 : AlgorithmEdDSA / AlgorithmES256,   // Algorithm
+     *     // The SignedMac, which authenticates the MAC key that is used to authenticate the
+     *     // keysToSign.
+     *     SignedMac = [                                // COSE_Sign1
+     *         bstr .cbor {                             // Protected params
+     *             1 : AlgorithmEdDSA / AlgorithmES256, // Algorithm
      *         },
-     *         {},                   // Unprotected params
-     *         bstr .size 32,                  // MAC key
+     *         {},                                      // Unprotected params
+     *         bstr .size 32,                           // Payload: MAC key
      *         bstr // PureEd25519(KM_priv, bstr .cbor SignedMac_structure) /
      *              // ECDSA(KM_priv, bstr .cbor SignedMac_structure)
      *     ]
      *
-     *     SignedMac_structure = [
+     *     SignedMac_structure = [                      //  COSE Sig_structure
      *         "Signature1",
-     *         bstr .cbor {                               // Protected params
-     *             1 : AlgorithmEdDSA / AlgorithmES256,   // Algorithm
+     *         bstr .cbor {                             // Protected params
+     *             1 : AlgorithmEdDSA / AlgorithmES256, // Algorithm
      *         },
-     *         bstr .cbor SignedMacAad
-     *         bstr .size 32                              // MAC key
+     *         bstr .cbor SignedMacAad,
+     *         bstr .size 32                            // MAC key
      *     ]
      *
      *     SignedMacAad = [
-     *         challenge : bstr,
+     *         challenge : bstr .size (32..64),   // Size between 32 - 64
+     *                                            // bytes inclusive
      *         VerifiedDeviceInfo,
      *         tag: bstr                 // This is the tag from COSE_Mac0 of
      *                                   // KeysToCertify, to tie the key set to
      *                                   // the signature.
      *     ]
      *
+     *     VerifiedDeviceInfo = DeviceInfo  // See DeviceInfo.aidl
+     *
+     *     // The BCC is the boot certificate chain, containing measurements about the device
+     *     // boot chain. The BCC generally follows the Open Profile for DICE specification at
+     *     // https://pigweed.googlesource.com/open-dice/+/HEAD/docs/specification.md.
+     *     //
+     *     // The first entry in the Bcc is the DK_pub, encoded as a COSE_key. All entries after
+     *     // the first describe a link in the boot chain (e.g. bootloaders: BL1, BL2, ... BLN).
+     *     // Note that there is no BccEntry for DK_pub, only a "bare" COSE_key.
      *     Bcc = [
      *         PubKeyEd25519 / PubKeyECDSA256, // DK_pub
      *         + BccEntry,                     // Root -> leaf (KM_pub)
      *     ]
      *
-     *     BccPayload = {                     // CWT
-     *         1 : tstr,                      // Issuer
-     *         2 : tstr,                      // Subject
-     *         // See the Open Profile for DICE for details on these fields.
-     *         ? -4670545 : bstr,             // Code Hash
-     *         ? -4670546 : bstr,             // Code Descriptor
-     *         ? -4670547 : bstr,             // Configuration Hash
-     *         ? -4670548 : bstr .cbor {      // Configuration Descriptor
-     *             ? -70002 : tstr,           // Component name
-     *             ? -70003 : int,            // Firmware version
-     *             ? -70004 : null,           // Resettable
-     *         },
-     *         ? -4670549 : bstr,             // Authority Hash
-     *         ? -4670550 : bstr,             // Authority Descriptor
-     *         ? -4670551 : bstr,             // Mode
+     *     // This is the signed payload for each entry in the Bcc. Note that the "Configuration
+     *     // Input Values" described by the Open Profile are not used here. Instead, the Bcc
+     *     // defines its own configuration values for the Configuration Descriptor field. See
+     *     // the Open Profile for DICE for more details on the fields. All hashes are SHA256.
+     *     BccPayload = {                               // CWT [RFC8392]
+     *         1 : tstr,                                // Issuer
+     *         2 : tstr,                                // Subject
      *         -4670552 : bstr .cbor PubKeyEd25519 /
-     *                    bstr .cbor PubKeyECDSA256   // Subject Public Key
-     *         -4670553 : bstr                // Key Usage
+     *                    bstr .cbor PubKeyECDSA256,    // Subject Public Key
+     *         -4670553 : bstr                          // Key Usage
+     *
+     *         // NOTE: All of the following fields may be omitted for a "Degenerate BCC", as
+     *         //       described by IRemotelyProvisionedComponent.aidl.
+     *         -4670545 : bstr,                         // Code Hash
+     *         ? -4670546 : bstr,                       // Code Descriptor
+     *         ? -4670547 : bstr,                       // Configuration Hash
+     *         -4670548 : bstr .cbor {                  // Configuration Descriptor
+     *             ? -70002 : tstr,                         // Component name
+     *             ? -70003 : int,                          // Firmware version
+     *             ? -70004 : null,                         // Resettable
+     *         },
+     *         -4670549 : bstr,                         // Authority Hash
+     *         ? -4670550 : bstr,                       // Authority Descriptor
+     *         -4670551 : bstr,                         // Mode
      *     }
      *
+     *     // Each entry in the Bcc is a BccPayload signed by the key from the previous entry
+     *     // in the Bcc array.
      *     BccEntry = [                                  // COSE_Sign1 (untagged)
      *         protected : bstr .cbor {
      *             1 : AlgorithmEdDSA / AlgorithmES256,  // Algorithm
@@ -158,8 +200,8 @@
      *         payload: bstr .cbor BccPayload
      *     ]
      *
-     *     VerifiedDeviceInfo = DeviceInfo  // See DeviceInfo.aidl
-     *
+     *     // The following section defines some types that are reused throughout the above
+     *     // data structures.
      *     PubKeyX25519 = {                 // COSE_Key
      *          1 : 1,                      // Key type : Octet Key Pair
      *         -1 : 4,                      // Curve : X25519
@@ -167,25 +209,25 @@
      *     }
      *
      *     PubKeyEd25519 = {                // COSE_Key
-     *         1 : 1,                         // Key type : octet key pair
-     *         3 : AlgorithmEdDSA,            // Algorithm : EdDSA
-     *         -1 : 6,                        // Curve : Ed25519
-     *         -2 : bstr                      // X coordinate, little-endian
+     *         1 : 1,                       // Key type : octet key pair
+     *         3 : AlgorithmEdDSA,          // Algorithm : EdDSA
+     *         -1 : 6,                      // Curve : Ed25519
+     *         -2 : bstr                    // X coordinate, little-endian
      *     }
      *
-     *     PubKeyEcdhP256 = {              // COSE_Key
-     *          1 : 2,      // Key type : EC2
-     *          -1 : 1,     // Curve : P256
-     *          -2 : bstr   // Sender X coordinate
-     *          -3 : bstr   // Sender Y coordinate
+     *     PubKeyEcdhP256 = {               // COSE_Key
+     *          1 : 2,                      // Key type : EC2
+     *          -1 : 1,                     // Curve : P256
+     *          -2 : bstr                   // Sender X coordinate
+     *          -3 : bstr                   // Sender Y coordinate
      *     }
      *
-     *     PubKeyECDSA256 = {                 // COSE_Key
-     *         1 : 2,                         // Key type : EC2
-     *         3 : AlgorithmES256,            // Algorithm : ECDSA w/ SHA-256
-     *         -1 : 1,                        // Curve: P256
-     *         -2 : bstr,                     // X coordinate
-     *         -3 : bstr                      // Y coordinate
+     *     PubKeyECDSA256 = {               // COSE_Key
+     *         1 : 2,                       // Key type : EC2
+     *         3 : AlgorithmES256,          // Algorithm : ECDSA w/ SHA-256
+     *         -1 : 1,                      // Curve: P256
+     *         -2 : bstr,                   // X coordinate
+     *         -3 : bstr                    // Y coordinate
      *     }
      *
      *     AlgorithmES256 = -7
diff --git a/security/keymint/aidl/android/hardware/security/keymint/RpcHardwareInfo.aidl b/security/keymint/aidl/android/hardware/security/keymint/RpcHardwareInfo.aidl
index 3a4c233..0cb33ce 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/RpcHardwareInfo.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/RpcHardwareInfo.aidl
@@ -59,13 +59,17 @@
      * client should NOT interpret the content of the identifier in any way. The client can only
      * compare identifiers to determine if two IRemotelyProvisionedComponents share the same
      * implementation. Each IRemotelyProvisionedComponent implementation must have a distinct
-     * identifier from all other implementations on the same device.
+     * identifier from all other implementations, and it must be consistent across all devices.
+     * It's critical that this identifier not be usable to uniquely identify a specific device.
      *
      * This identifier must be consistent across reboots, as it is used to store and track
      * provisioned keys in a persistent, on-device database.
      *
      * uniqueId may not be empty, and must not be any longer than 32 characters.
      *
+     * A recommended construction for this value is "[Vendor] [Component Name] [Major Version]",
+     * e.g. "Google Trusty KeyMint 1".
+     *
      * This field was added in API version 2.
      *
      */
diff --git a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl
index b28ebcb..871a1ac 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl
@@ -186,10 +186,16 @@
      * Tag::RSA_OAEP_MGF_DIGEST specifies the MGF1 digest algorithms that may be used with RSA
      * encryption/decryption with OAEP padding.  Possible values are defined by the Digest enum.
      *
-     * This tag is repeatable for key generation/import.  RSA cipher operations with OAEP padding
-     * must specify an MGF1 digest in the params argument of begin(). If this tag is missing or the
-     * specified digest is not in the MGF1 digests associated with the key then begin operation must
-     * fail with ErrorCode::INCOMPATIBLE_MGF_DIGEST.
+     * This tag is repeatable for key generation/import.
+     *
+     * If the caller specifies an MGF1 digest in the params argument of begin(), that digest must be
+     * present as an RSA_OAEP_MGF_DIGEST value in the key characteristics (or the begin() operation
+     * must fail with ErrorCode::INCOMPATIBLE_MGF_DIGEST).
+     *
+     * If the caller does not specify an MGF1 digest in the params argument of begin(), a default
+     * MGF1 digest of SHA1 is used.  If the key characteristics have any explicitly specified values
+     * for RSA_OAEP_MGF_DIGEST, then SHA1 must be included (or the begin() operation must fail with
+     * ErrorCode::INCOMPATIBLE_MGF_DIGEST).
      *
      * Must be hardware-enforced.
      */
@@ -504,7 +510,9 @@
      * that is necessary during all uses of the key.  In particular, calls to exportKey() and
      * getKeyCharacteristics() must provide the same value to the clientId parameter, and calls to
      * begin() must provide this tag and the same associated data as part of the inParams set.  If
-     * the correct data is not provided, the method must return ErrorCode::INVALID_KEY_BLOB.
+     * the correct data is not provided, the method must return ErrorCode::INVALID_KEY_BLOB.  Note
+     * that a key with a zero-length APPLICATION_ID cannot have its key characteristics retrieved
+     * using getKeyCharacteristics() due to a historical limitation of the API.
      *
      * The content of this tag must be bound to the key cryptographically, meaning it must not be
      * possible for an adversary who has access to all of the secure world secrets but does not have
@@ -525,7 +533,9 @@
      * that is necessary during all uses of the key.  In particular, calls to begin() and
      * exportKey() must provide the same value to the appData parameter, and calls to begin must
      * provide this tag and the same associated data as part of the inParams set.  If the correct
-     * data is not provided, the method must return ErrorCode::INVALID_KEY_BLOB.
+     * data is not provided, the method must return ErrorCode::INVALID_KEY_BLOB.  Note that a key
+     * with a zero-length APPLICATION_DATA cannot have its key characteristics retrieved using
+     * getKeyCharacteristics() due to a historical limitation of the API.
      *
      * The content of this tag must be bound to the key cryptographically, meaning it must not be
      * possible for an adversary who has access to all of the secure world secrets but does not have
diff --git a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
index 5cdea93..ca517ac 100644
--- a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
+++ b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
@@ -16,6 +16,7 @@
 
 #define LOG_TAG "keymint_1_attest_key_test"
 #include <cutils/log.h>
+#include <cutils/properties.h>
 
 #include <keymint_support/key_param_output.h>
 #include <keymint_support/openssl_utils.h>
@@ -33,7 +34,33 @@
 
 }  // namespace
 
-using AttestKeyTest = KeyMintAidlTestBase;
+class AttestKeyTest : public KeyMintAidlTestBase {
+  protected:
+    ErrorCode GenerateAttestKey(const AuthorizationSet& key_desc,
+                                const optional<AttestationKey>& attest_key,
+                                vector<uint8_t>* key_blob,
+                                vector<KeyCharacteristics>* key_characteristics,
+                                vector<Certificate>* cert_chain) {
+        // The original specification for KeyMint v1 required ATTEST_KEY not be combined
+        // with any other key purpose, but the original VTS tests incorrectly did exactly that.
+        // This means that a device that launched prior to Android T (API level 33) may
+        // accept or even require KeyPurpose::SIGN too.
+        if (property_get_int32("ro.board.first_api_level", 0) < 33) {
+            AuthorizationSet key_desc_plus_sign = key_desc;
+            key_desc_plus_sign.push_back(TAG_PURPOSE, KeyPurpose::SIGN);
+
+            auto result = GenerateKey(key_desc_plus_sign, attest_key, key_blob, key_characteristics,
+                                      cert_chain);
+            if (result == ErrorCode::OK) {
+                return result;
+            }
+            // If the key generation failed, it may be because the device is (correctly)
+            // rejecting the combination of ATTEST_KEY+SIGN.  Fall through to try again with
+            // just ATTEST_KEY.
+        }
+        return GenerateKey(key_desc, attest_key, key_blob, key_characteristics, cert_chain);
+    }
+};
 
 /*
  * AttestKeyTest.AllRsaSizes
@@ -49,12 +76,13 @@
         AttestationKey attest_key;
         vector<KeyCharacteristics> attest_key_characteristics;
         vector<Certificate> attest_key_cert_chain;
-        ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
-                                                     .RsaKey(size, 65537)
-                                                     .AttestKey()
-                                                     .SetDefaultValidity(),
-                                             {} /* attestation signing key */, &attest_key.keyBlob,
-                                             &attest_key_characteristics, &attest_key_cert_chain));
+        ASSERT_EQ(ErrorCode::OK,
+                  GenerateAttestKey(AuthorizationSetBuilder()
+                                            .RsaKey(size, 65537)
+                                            .AttestKey()
+                                            .SetDefaultValidity(),
+                                    {} /* attestation signing key */, &attest_key.keyBlob,
+                                    &attest_key_characteristics, &attest_key_cert_chain));
 
         ASSERT_GT(attest_key_cert_chain.size(), 0);
         EXPECT_EQ(attest_key_cert_chain.size(), 1);
@@ -227,17 +255,17 @@
     AttestationKey attest_key;
     vector<KeyCharacteristics> attest_key_characteristics;
     vector<Certificate> attest_key_cert_chain;
-    auto result = GenerateKey(AuthorizationSetBuilder()
-                                      .RsaKey(2048, 65537)
-                                      .AttestKey()
-                                      .AttestationChallenge(challenge)
-                                      .AttestationApplicationId(app_id)
-                                      .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
-                                      .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
-                                      .Authorization(TAG_NO_AUTH_REQUIRED)
-                                      .SetDefaultValidity(),
-                              {} /* attestation signing key */, &attest_key.keyBlob,
-                              &attest_key_characteristics, &attest_key_cert_chain);
+    auto result = GenerateAttestKey(AuthorizationSetBuilder()
+                                            .RsaKey(2048, 65537)
+                                            .AttestKey()
+                                            .AttestationChallenge(challenge)
+                                            .AttestationApplicationId(app_id)
+                                            .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
+                                            .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
+                                            .Authorization(TAG_NO_AUTH_REQUIRED)
+                                            .SetDefaultValidity(),
+                                    {} /* attestation signing key */, &attest_key.keyBlob,
+                                    &attest_key_characteristics, &attest_key_cert_chain);
     // Strongbox may not support factory provisioned attestation key.
     if (SecLevel() == SecurityLevel::STRONGBOX) {
         if (result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) return;
@@ -331,17 +359,17 @@
             attest_key_opt = attest_key;
         }
 
-        auto result = GenerateKey(AuthorizationSetBuilder()
-                                          .RsaKey(2048, 65537)
-                                          .AttestKey()
-                                          .AttestationChallenge("foo")
-                                          .AttestationApplicationId("bar")
-                                          .Authorization(TAG_NO_AUTH_REQUIRED)
-                                          .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
-                                          .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
-                                          .SetDefaultValidity(),
-                                  attest_key_opt, &key_blob_list[i], &attested_key_characteristics,
-                                  &cert_chain_list[i]);
+        auto result = GenerateAttestKey(AuthorizationSetBuilder()
+                                                .RsaKey(2048, 65537)
+                                                .AttestKey()
+                                                .AttestationChallenge("foo")
+                                                .AttestationApplicationId("bar")
+                                                .Authorization(TAG_NO_AUTH_REQUIRED)
+                                                .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
+                                                .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
+                                                .SetDefaultValidity(),
+                                        attest_key_opt, &key_blob_list[i],
+                                        &attested_key_characteristics, &cert_chain_list[i]);
         // Strongbox may not support factory provisioned attestation key.
         if (SecLevel() == SecurityLevel::STRONGBOX) {
             if (result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) return;
@@ -408,17 +436,17 @@
             attest_key_opt = attest_key;
         }
 
-        auto result = GenerateKey(AuthorizationSetBuilder()
-                                          .EcdsaKey(EcCurve::P_256)
-                                          .AttestKey()
-                                          .AttestationChallenge("foo")
-                                          .AttestationApplicationId("bar")
-                                          .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
-                                          .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
-                                          .Authorization(TAG_NO_AUTH_REQUIRED)
-                                          .SetDefaultValidity(),
-                                  attest_key_opt, &key_blob_list[i], &attested_key_characteristics,
-                                  &cert_chain_list[i]);
+        auto result = GenerateAttestKey(AuthorizationSetBuilder()
+                                                .EcdsaKey(EcCurve::P_256)
+                                                .AttestKey()
+                                                .AttestationChallenge("foo")
+                                                .AttestationApplicationId("bar")
+                                                .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
+                                                .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
+                                                .Authorization(TAG_NO_AUTH_REQUIRED)
+                                                .SetDefaultValidity(),
+                                        attest_key_opt, &key_blob_list[i],
+                                        &attested_key_characteristics, &cert_chain_list[i]);
         // Strongbox may not support factory provisioned attestation key.
         if (SecLevel() == SecurityLevel::STRONGBOX) {
             if (result == ErrorCode::ATTESTATION_KEYS_NOT_PROVISIONED) return;
@@ -513,29 +541,29 @@
         }
         ErrorCode result;
         if ((i & 0x1) == 1) {
-            result = GenerateKey(AuthorizationSetBuilder()
-                                         .EcdsaKey(EcCurve::P_256)
-                                         .AttestKey()
-                                         .AttestationChallenge("foo")
-                                         .AttestationApplicationId("bar")
-                                         .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
-                                         .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
-                                         .Authorization(TAG_NO_AUTH_REQUIRED)
-                                         .SetDefaultValidity(),
-                                 attest_key_opt, &key_blob_list[i], &attested_key_characteristics,
-                                 &cert_chain_list[i]);
+            result = GenerateAttestKey(AuthorizationSetBuilder()
+                                               .EcdsaKey(EcCurve::P_256)
+                                               .AttestKey()
+                                               .AttestationChallenge("foo")
+                                               .AttestationApplicationId("bar")
+                                               .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
+                                               .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
+                                               .Authorization(TAG_NO_AUTH_REQUIRED)
+                                               .SetDefaultValidity(),
+                                       attest_key_opt, &key_blob_list[i],
+                                       &attested_key_characteristics, &cert_chain_list[i]);
         } else {
-            result = GenerateKey(AuthorizationSetBuilder()
-                                         .RsaKey(2048, 65537)
-                                         .AttestKey()
-                                         .AttestationChallenge("foo")
-                                         .AttestationApplicationId("bar")
-                                         .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
-                                         .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
-                                         .Authorization(TAG_NO_AUTH_REQUIRED)
-                                         .SetDefaultValidity(),
-                                 attest_key_opt, &key_blob_list[i], &attested_key_characteristics,
-                                 &cert_chain_list[i]);
+            result = GenerateAttestKey(AuthorizationSetBuilder()
+                                               .RsaKey(2048, 65537)
+                                               .AttestKey()
+                                               .AttestationChallenge("foo")
+                                               .AttestationApplicationId("bar")
+                                               .Authorization(TAG_CERTIFICATE_SERIAL, serial_blob)
+                                               .Authorization(TAG_CERTIFICATE_SUBJECT, subject_der)
+                                               .Authorization(TAG_NO_AUTH_REQUIRED)
+                                               .SetDefaultValidity(),
+                                       attest_key_opt, &key_blob_list[i],
+                                       &attested_key_characteristics, &cert_chain_list[i]);
         }
         // Strongbox may not support factory provisioned attestation key.
         if (SecLevel() == SecurityLevel::STRONGBOX) {
@@ -581,12 +609,13 @@
         AttestationKey attest_key;
         vector<KeyCharacteristics> attest_key_characteristics;
         vector<Certificate> attest_key_cert_chain;
-        ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
-                                                     .RsaKey(size, 65537)
-                                                     .AttestKey()
-                                                     .SetDefaultValidity(),
-                                             {} /* attestation signing key */, &attest_key.keyBlob,
-                                             &attest_key_characteristics, &attest_key_cert_chain));
+        ASSERT_EQ(ErrorCode::OK,
+                  GenerateAttestKey(AuthorizationSetBuilder()
+                                            .RsaKey(size, 65537)
+                                            .AttestKey()
+                                            .SetDefaultValidity(),
+                                    {} /* attestation signing key */, &attest_key.keyBlob,
+                                    &attest_key_characteristics, &attest_key_cert_chain));
 
         EXPECT_EQ(attest_key_cert_chain.size(), 1);
         EXPECT_TRUE(IsSelfSigned(attest_key_cert_chain)) << "Failed on size " << size;
@@ -630,7 +659,7 @@
         vector<Certificate> attest_key_cert_chain;
         ASSERT_EQ(
                 ErrorCode::OK,
-                GenerateKey(
+                GenerateAttestKey(
                         AuthorizationSetBuilder().EcdsaKey(curve).AttestKey().SetDefaultValidity(),
                         {} /* attestation signing key */, &attest_key.keyBlob,
                         &attest_key_characteristics, &attest_key_cert_chain));
@@ -743,16 +772,22 @@
 }
 
 TEST_P(AttestKeyTest, EcdsaAttestationID) {
+    if (is_gsi_image()) {
+        // GSI sets up a standard set of device identifiers that may not match
+        // the device identifiers held by the device.
+        GTEST_SKIP() << "Test not applicable under GSI";
+    }
     // Create attestation key.
     AttestationKey attest_key;
     vector<KeyCharacteristics> attest_key_characteristics;
     vector<Certificate> attest_key_cert_chain;
-    ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
-                                                 .EcdsaKey(EcCurve::P_256)
-                                                 .AttestKey()
-                                                 .SetDefaultValidity(),
-                                         {} /* attestation signing key */, &attest_key.keyBlob,
-                                         &attest_key_characteristics, &attest_key_cert_chain));
+    ASSERT_EQ(ErrorCode::OK,
+              GenerateAttestKey(AuthorizationSetBuilder()
+                                        .EcdsaKey(EcCurve::P_256)
+                                        .AttestKey()
+                                        .SetDefaultValidity(),
+                                {} /* attestation signing key */, &attest_key.keyBlob,
+                                &attest_key_characteristics, &attest_key_cert_chain));
     attest_key.issuerSubjectName = make_name_from_str("Android Keystore Key");
     ASSERT_GT(attest_key_cert_chain.size(), 0);
     EXPECT_EQ(attest_key_cert_chain.size(), 1);
@@ -811,12 +846,13 @@
     AttestationKey attest_key;
     vector<KeyCharacteristics> attest_key_characteristics;
     vector<Certificate> attest_key_cert_chain;
-    ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
-                                                 .EcdsaKey(EcCurve::P_256)
-                                                 .AttestKey()
-                                                 .SetDefaultValidity(),
-                                         {} /* attestation signing key */, &attest_key.keyBlob,
-                                         &attest_key_characteristics, &attest_key_cert_chain));
+    ASSERT_EQ(ErrorCode::OK,
+              GenerateAttestKey(AuthorizationSetBuilder()
+                                        .EcdsaKey(EcCurve::P_256)
+                                        .AttestKey()
+                                        .SetDefaultValidity(),
+                                {} /* attestation signing key */, &attest_key.keyBlob,
+                                &attest_key_characteristics, &attest_key_cert_chain));
     attest_key.issuerSubjectName = make_name_from_str("Android Keystore Key");
     ASSERT_GT(attest_key_cert_chain.size(), 0);
     EXPECT_EQ(attest_key_cert_chain.size(), 1);
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
index 943c692..1caf8bc 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
@@ -17,6 +17,7 @@
 #include "KeyMintAidlTestBase.h"
 
 #include <chrono>
+#include <fstream>
 #include <unordered_set>
 #include <vector>
 
@@ -30,7 +31,6 @@
 #include <remote_prov/remote_prov_utils.h>
 
 #include <keymaster/cppcose/cppcose.h>
-#include <keymint_support/attestation_record.h>
 #include <keymint_support/key_param_output.h>
 #include <keymint_support/keymint_utils.h>
 #include <keymint_support/openssl_utils.h>
@@ -772,6 +772,100 @@
     }
 }
 
+void KeyMintAidlTestBase::AesCheckEncryptOneByteAtATime(const string& key, BlockMode block_mode,
+                                                        PaddingMode padding_mode, const string& iv,
+                                                        const string& plaintext,
+                                                        const string& exp_cipher_text) {
+    bool is_authenticated_cipher = (block_mode == BlockMode::GCM);
+    auto auth_set = AuthorizationSetBuilder()
+                            .Authorization(TAG_NO_AUTH_REQUIRED)
+                            .AesEncryptionKey(key.size() * 8)
+                            .BlockMode(block_mode)
+                            .Padding(padding_mode);
+    if (iv.size() > 0) auth_set.Authorization(TAG_CALLER_NONCE);
+    if (is_authenticated_cipher) auth_set.Authorization(TAG_MIN_MAC_LENGTH, 128);
+    ASSERT_EQ(ErrorCode::OK, ImportKey(auth_set, KeyFormat::RAW, key));
+
+    CheckEncryptOneByteAtATime(block_mode, 16 /*block_size*/, padding_mode, iv, plaintext,
+                               exp_cipher_text);
+}
+
+void KeyMintAidlTestBase::CheckEncryptOneByteAtATime(BlockMode block_mode, const int block_size,
+                                                     PaddingMode padding_mode, const string& iv,
+                                                     const string& plaintext,
+                                                     const string& exp_cipher_text) {
+    bool is_stream_cipher = (block_mode == BlockMode::CTR || block_mode == BlockMode::GCM);
+    bool is_authenticated_cipher = (block_mode == BlockMode::GCM);
+    auto params = AuthorizationSetBuilder().BlockMode(block_mode).Padding(padding_mode);
+    if (iv.size() > 0) params.Authorization(TAG_NONCE, iv.data(), iv.size());
+    if (is_authenticated_cipher) params.Authorization(TAG_MAC_LENGTH, 128);
+
+    AuthorizationSet output_params;
+    EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params, &output_params));
+
+    string actual_ciphertext;
+    if (is_stream_cipher) {
+        // Assert that a 1 byte of output is produced for 1 byte of input.
+        // Every input byte produces an output byte.
+        for (int plaintext_index = 0; plaintext_index < plaintext.size(); plaintext_index++) {
+            string ciphertext;
+            EXPECT_EQ(ErrorCode::OK, Update(plaintext.substr(plaintext_index, 1), &ciphertext));
+            // Some StrongBox implementations cannot support 1:1 input:output lengths, so
+            // we relax this API restriction for them.
+            if (SecLevel() != SecurityLevel::STRONGBOX) {
+                EXPECT_EQ(1, ciphertext.size()) << "plaintext index: " << plaintext_index;
+            }
+            actual_ciphertext.append(ciphertext);
+        }
+        string ciphertext;
+        EXPECT_EQ(ErrorCode::OK, Finish(&ciphertext));
+        if (SecLevel() != SecurityLevel::STRONGBOX) {
+            string expected_final_output;
+            if (is_authenticated_cipher) {
+                expected_final_output = exp_cipher_text.substr(plaintext.size());
+            }
+            EXPECT_EQ(expected_final_output, ciphertext);
+        }
+        actual_ciphertext.append(ciphertext);
+    } else {
+        // Assert that a block of output is produced once a full block of input is provided.
+        // Every input block produces an output block.
+        bool compare_output = true;
+        string additional_information;
+        int vendor_api_level = property_get_int32("ro.vendor.api_level", 0);
+        if (SecLevel() == SecurityLevel::STRONGBOX) {
+            // This is known to be broken on older vendor implementations.
+            if (vendor_api_level < 33) {
+                compare_output = false;
+            } else {
+                additional_information = " (b/194134359) ";
+            }
+        }
+        for (int plaintext_index = 0; plaintext_index < plaintext.size(); plaintext_index++) {
+            string ciphertext;
+            EXPECT_EQ(ErrorCode::OK, Update(plaintext.substr(plaintext_index, 1), &ciphertext));
+            if (compare_output) {
+                if ((plaintext_index % block_size) == block_size - 1) {
+                    // Update is expected to have output a new block
+                    EXPECT_EQ(block_size, ciphertext.size())
+                            << "plaintext index: " << plaintext_index << additional_information;
+                } else {
+                    // Update is expected to have produced no output
+                    EXPECT_EQ(0, ciphertext.size())
+                            << "plaintext index: " << plaintext_index << additional_information;
+                }
+            }
+            actual_ciphertext.append(ciphertext);
+        }
+        string ciphertext;
+        EXPECT_EQ(ErrorCode::OK, Finish(&ciphertext));
+        actual_ciphertext.append(ciphertext);
+    }
+    // Regardless of how the completed ciphertext got accumulated, it should match the expected
+    // ciphertext.
+    EXPECT_EQ(exp_cipher_text, actual_ciphertext);
+}
+
 void KeyMintAidlTestBase::CheckHmacTestVector(const string& key, const string& message,
                                               Digest digest, const string& expected_mac) {
     SCOPED_TRACE("CheckHmacTestVector");
@@ -981,7 +1075,7 @@
 
     // Retrieve relevant tags.
     Digest digest = Digest::NONE;
-    Digest mgf_digest = Digest::NONE;
+    Digest mgf_digest = Digest::SHA1;
     PaddingMode padding = PaddingMode::NONE;
 
     auto digest_tag = params.GetTagValue(TAG_DIGEST);
@@ -1460,6 +1554,36 @@
     OPENSSL_free(cert_issuer);
 }
 
+int get_vsr_api_level() {
+    int vendor_api_level = ::android::base::GetIntProperty("ro.vendor.api_level", -1);
+    if (vendor_api_level != -1) {
+        return vendor_api_level;
+    }
+
+    // Android S and older devices do not define ro.vendor.api_level
+    vendor_api_level = ::android::base::GetIntProperty("ro.board.api_level", -1);
+    if (vendor_api_level == -1) {
+        vendor_api_level = ::android::base::GetIntProperty("ro.board.first_api_level", -1);
+    }
+
+    int product_api_level = ::android::base::GetIntProperty("ro.product.first_api_level", -1);
+    if (product_api_level == -1) {
+        product_api_level = ::android::base::GetIntProperty("ro.build.version.sdk", -1);
+        EXPECT_NE(product_api_level, -1) << "Could not find ro.build.version.sdk";
+    }
+
+    // VSR API level is the minimum of vendor_api_level and product_api_level.
+    if (vendor_api_level == -1 || vendor_api_level > product_api_level) {
+        return product_api_level;
+    }
+    return vendor_api_level;
+}
+
+bool is_gsi_image() {
+    std::ifstream ifs("/system/system_ext/etc/init/init.gsi.rc");
+    return ifs.good();
+}
+
 vector<uint8_t> build_serial_blob(const uint64_t serial_int) {
     BIGNUM_Ptr serial(BN_new());
     EXPECT_TRUE(BN_set_u64(serial.get(), serial_int));
@@ -1491,6 +1615,60 @@
     verify_subject(cert.get(), subject, self_signed);
 }
 
+void verify_root_of_trust(const vector<uint8_t>& verified_boot_key, bool device_locked,
+                          VerifiedBoot verified_boot_state,
+                          const vector<uint8_t>& verified_boot_hash) {
+    char property_value[PROPERTY_VALUE_MAX] = {};
+
+    if (avb_verification_enabled()) {
+        EXPECT_NE(property_get("ro.boot.vbmeta.digest", property_value, ""), 0);
+        string prop_string(property_value);
+        EXPECT_EQ(prop_string.size(), 64);
+        EXPECT_EQ(prop_string, bin2hex(verified_boot_hash));
+
+        EXPECT_NE(property_get("ro.boot.vbmeta.device_state", property_value, ""), 0);
+        if (!strcmp(property_value, "unlocked")) {
+            EXPECT_FALSE(device_locked);
+        } else {
+            EXPECT_TRUE(device_locked);
+        }
+
+        // Check that the device is locked if not debuggable, e.g., user build
+        // images in CTS. For VTS, debuggable images are used to allow adb root
+        // and the device is unlocked.
+        if (!property_get_bool("ro.debuggable", false)) {
+            EXPECT_TRUE(device_locked);
+        } else {
+            EXPECT_FALSE(device_locked);
+        }
+    }
+
+    // Verified boot key should be all 0's if the boot state is not verified or self signed
+    std::string empty_boot_key(32, '\0');
+    std::string verified_boot_key_str((const char*)verified_boot_key.data(),
+                                      verified_boot_key.size());
+    EXPECT_NE(property_get("ro.boot.verifiedbootstate", property_value, ""), 0);
+    if (!strcmp(property_value, "green")) {
+        EXPECT_EQ(verified_boot_state, VerifiedBoot::VERIFIED);
+        EXPECT_NE(0, memcmp(verified_boot_key.data(), empty_boot_key.data(),
+                            verified_boot_key.size()));
+    } else if (!strcmp(property_value, "yellow")) {
+        EXPECT_EQ(verified_boot_state, VerifiedBoot::SELF_SIGNED);
+        EXPECT_NE(0, memcmp(verified_boot_key.data(), empty_boot_key.data(),
+                            verified_boot_key.size()));
+    } else if (!strcmp(property_value, "orange")) {
+        EXPECT_EQ(verified_boot_state, VerifiedBoot::UNVERIFIED);
+        EXPECT_EQ(0, memcmp(verified_boot_key.data(), empty_boot_key.data(),
+                            verified_boot_key.size()));
+    } else if (!strcmp(property_value, "red")) {
+        EXPECT_EQ(verified_boot_state, VerifiedBoot::FAILED);
+    } else {
+        EXPECT_EQ(verified_boot_state, VerifiedBoot::UNVERIFIED);
+        EXPECT_EQ(0, memcmp(verified_boot_key.data(), empty_boot_key.data(),
+                            verified_boot_key.size()));
+    }
+}
+
 bool verify_attestation_record(int32_t aidl_version,                   //
                                const string& challenge,                //
                                const string& app_id,                   //
@@ -1545,8 +1723,6 @@
     EXPECT_EQ(security_level, att_keymint_security_level);
     EXPECT_EQ(security_level, att_attestation_security_level);
 
-
-    char property_value[PROPERTY_VALUE_MAX] = {};
     // TODO(b/136282179): When running under VTS-on-GSI the TEE-backed
     // keymint implementation will report YYYYMM dates instead of YYYYMMDD
     // for the BOOT_PATCH_LEVEL.
@@ -1606,54 +1782,7 @@
     error = parse_root_of_trust(attest_rec->data, attest_rec->length, &verified_boot_key,
                                 &verified_boot_state, &device_locked, &verified_boot_hash);
     EXPECT_EQ(ErrorCode::OK, error);
-
-    if (avb_verification_enabled()) {
-        EXPECT_NE(property_get("ro.boot.vbmeta.digest", property_value, ""), 0);
-        string prop_string(property_value);
-        EXPECT_EQ(prop_string.size(), 64);
-        EXPECT_EQ(prop_string, bin2hex(verified_boot_hash));
-
-        EXPECT_NE(property_get("ro.boot.vbmeta.device_state", property_value, ""), 0);
-        if (!strcmp(property_value, "unlocked")) {
-            EXPECT_FALSE(device_locked);
-        } else {
-            EXPECT_TRUE(device_locked);
-        }
-
-        // Check that the device is locked if not debuggable, e.g., user build
-        // images in CTS. For VTS, debuggable images are used to allow adb root
-        // and the device is unlocked.
-        if (!property_get_bool("ro.debuggable", false)) {
-            EXPECT_TRUE(device_locked);
-        } else {
-            EXPECT_FALSE(device_locked);
-        }
-    }
-
-    // Verified boot key should be all 0's if the boot state is not verified or self signed
-    std::string empty_boot_key(32, '\0');
-    std::string verified_boot_key_str((const char*)verified_boot_key.data(),
-                                      verified_boot_key.size());
-    EXPECT_NE(property_get("ro.boot.verifiedbootstate", property_value, ""), 0);
-    if (!strcmp(property_value, "green")) {
-        EXPECT_EQ(verified_boot_state, VerifiedBoot::VERIFIED);
-        EXPECT_NE(0, memcmp(verified_boot_key.data(), empty_boot_key.data(),
-                            verified_boot_key.size()));
-    } else if (!strcmp(property_value, "yellow")) {
-        EXPECT_EQ(verified_boot_state, VerifiedBoot::SELF_SIGNED);
-        EXPECT_NE(0, memcmp(verified_boot_key.data(), empty_boot_key.data(),
-                            verified_boot_key.size()));
-    } else if (!strcmp(property_value, "orange")) {
-        EXPECT_EQ(verified_boot_state, VerifiedBoot::UNVERIFIED);
-        EXPECT_EQ(0, memcmp(verified_boot_key.data(), empty_boot_key.data(),
-                            verified_boot_key.size()));
-    } else if (!strcmp(property_value, "red")) {
-        EXPECT_EQ(verified_boot_state, VerifiedBoot::FAILED);
-    } else {
-        EXPECT_EQ(verified_boot_state, VerifiedBoot::UNVERIFIED);
-        EXPECT_EQ(0, memcmp(verified_boot_key.data(), empty_boot_key.data(),
-                            verified_boot_key.size()));
-    }
+    verify_root_of_trust(verified_boot_key, device_locked, verified_boot_state, verified_boot_hash);
 
     att_sw_enforced.Sort();
     expected_sw_enforced.Sort();
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
index 7279c95..67e8b21 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
@@ -31,6 +31,7 @@
 #include <aidl/android/hardware/security/keymint/IKeyMintDevice.h>
 #include <aidl/android/hardware/security/keymint/MacedPublicKey.h>
 
+#include <keymint_support/attestation_record.h>
 #include <keymint_support/authorization_set.h>
 #include <keymint_support/openssl_utils.h>
 
@@ -187,6 +188,10 @@
 
     void CheckAesIncrementalEncryptOperation(BlockMode block_mode, int message_size);
 
+    void AesCheckEncryptOneByteAtATime(const string& key, BlockMode block_mode,
+                                       PaddingMode padding_mode, const string& iv,
+                                       const string& plaintext, const string& exp_cipher_text);
+
     void CheckHmacTestVector(const string& key, const string& message, Digest digest,
                              const string& expected_mac);
 
@@ -342,6 +347,11 @@
     string name_;
     string author_;
     long challenge_;
+
+  private:
+    void CheckEncryptOneByteAtATime(BlockMode block_mode, const int block_size,
+                                    PaddingMode padding_mode, const string& iv,
+                                    const string& plaintext, const string& exp_cipher_text);
 };
 
 // If the given property is available, add it to the tag set under the given tag ID.
@@ -354,13 +364,22 @@
     }
 }
 
+// Return the VSR API level for this device.
+int get_vsr_api_level();
+
+// Indicate whether the test is running on a GSI image.
+bool is_gsi_image();
+
 vector<uint8_t> build_serial_blob(const uint64_t serial_int);
 void verify_subject(const X509* cert, const string& subject, bool self_signed);
 void verify_serial(X509* cert, const uint64_t expected_serial);
 void verify_subject_and_serial(const Certificate& certificate,  //
                                const uint64_t expected_serial,  //
                                const string& subject, bool self_signed);
-
+void verify_root_of_trust(const vector<uint8_t>& verified_boot_key,  //
+                          bool device_locked,                        //
+                          VerifiedBoot verified_boot_state,          //
+                          const vector<uint8_t>& verified_boot_hash);
 bool verify_attestation_record(int aidl_version,                       //
                                const string& challenge,                //
                                const string& app_id,                   //
diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
index 3b75c50..fa7dccb 100644
--- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
@@ -613,7 +613,7 @@
 class NewKeyGenerationTest : public KeyMintAidlTestBase {
   protected:
     void CheckBaseParams(const vector<KeyCharacteristics>& keyCharacteristics) {
-        AuthorizationSet auths = CheckCommonParams(keyCharacteristics);
+        AuthorizationSet auths = CheckCommonParams(keyCharacteristics, KeyOrigin::GENERATED);
         EXPECT_TRUE(auths.Contains(TAG_PURPOSE, KeyPurpose::SIGN));
 
         // Check that some unexpected tags/values are NOT present.
@@ -622,20 +622,21 @@
     }
 
     void CheckSymmetricParams(const vector<KeyCharacteristics>& keyCharacteristics) {
-        AuthorizationSet auths = CheckCommonParams(keyCharacteristics);
+        AuthorizationSet auths = CheckCommonParams(keyCharacteristics, KeyOrigin::GENERATED);
         EXPECT_TRUE(auths.Contains(TAG_PURPOSE, KeyPurpose::ENCRYPT));
         EXPECT_TRUE(auths.Contains(TAG_PURPOSE, KeyPurpose::DECRYPT));
 
         EXPECT_FALSE(auths.Contains(TAG_PURPOSE, KeyPurpose::SIGN));
     }
 
-    AuthorizationSet CheckCommonParams(const vector<KeyCharacteristics>& keyCharacteristics) {
+    AuthorizationSet CheckCommonParams(const vector<KeyCharacteristics>& keyCharacteristics,
+                                       const KeyOrigin expectedKeyOrigin) {
         // TODO(swillden): Distinguish which params should be in which auth list.
         AuthorizationSet auths;
         for (auto& entry : keyCharacteristics) {
             auths.push_back(AuthorizationSet(entry.authorizations));
         }
-        EXPECT_TRUE(auths.Contains(TAG_ORIGIN, KeyOrigin::GENERATED));
+        EXPECT_TRUE(auths.Contains(TAG_ORIGIN, expectedKeyOrigin));
 
         // Verify that App data, ROT and auth timeout are NOT included.
         EXPECT_FALSE(auths.Contains(TAG_ROOT_OF_TRUST));
@@ -1102,9 +1103,9 @@
                 << "Key size " << key_size << "missing";
         EXPECT_TRUE(crypto_params.Contains(TAG_RSA_PUBLIC_EXPONENT, 65537U));
 
+        ASSERT_GT(cert_chain_.size(), 0);
         verify_subject_and_serial(cert_chain_[0], serial_int, subject, false);
         EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
-        ASSERT_GT(cert_chain_.size(), 0);
 
         AuthorizationSet hw_enforced = HwEnforcedAuthorizations(key_characteristics);
         AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics);
@@ -1178,6 +1179,7 @@
         EXPECT_FALSE(ChainSignaturesAreValid(cert_chain_));
 
         // The signature over the attested key should correspond to the P256 public key.
+        ASSERT_GT(cert_chain_.size(), 0);
         X509_Ptr key_cert(parse_cert_blob(cert_chain_[0].encodedCertificate));
         ASSERT_TRUE(key_cert.get());
         EVP_PKEY_Ptr signing_pubkey;
@@ -1265,9 +1267,9 @@
             << "Key size " << key_size << "missing";
     EXPECT_TRUE(crypto_params.Contains(TAG_RSA_PUBLIC_EXPONENT, 65537U));
 
+    ASSERT_GT(cert_chain_.size(), 0);
     verify_subject_and_serial(cert_chain_[0], serial_int, subject, false);
     EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
-    ASSERT_GT(cert_chain_.size(), 0);
 
     AuthorizationSet hw_enforced = HwEnforcedAuthorizations(key_characteristics);
     AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics);
@@ -1317,9 +1319,9 @@
                 << "Key size " << key_size << "missing";
         EXPECT_TRUE(crypto_params.Contains(TAG_RSA_PUBLIC_EXPONENT, 65537U));
 
+        ASSERT_EQ(cert_chain_.size(), 1);
         verify_subject_and_serial(cert_chain_[0], serial_int, subject, false);
         EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
-        ASSERT_EQ(cert_chain_.size(), 1);
 
         CheckedDeleteKey(&key_blob);
     }
@@ -1398,6 +1400,7 @@
             << "Key size " << key_size << "missing";
     EXPECT_TRUE(crypto_params.Contains(TAG_RSA_PUBLIC_EXPONENT, 65537U));
 
+    ASSERT_GT(cert_chain_.size(), 0);
     verify_subject_and_serial(cert_chain_[0], serial_int, subject, false);
     EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
     ASSERT_EQ(cert_chain_.size(), 1);
@@ -1949,6 +1952,11 @@
  * attestation extension.
  */
 TEST_P(NewKeyGenerationTest, EcdsaAttestationIdTags) {
+    if (is_gsi_image()) {
+        // GSI sets up a standard set of device identifiers that may not match
+        // the device identifiers held by the device.
+        GTEST_SKIP() << "Test not applicable under GSI";
+    }
     auto challenge = "hello";
     auto app_id = "foo";
     auto subject = "cert subj 2";
@@ -2223,8 +2231,8 @@
         EXPECT_TRUE(crypto_params.Contains(TAG_EC_CURVE, curve)) << "Curve " << curve << "missing";
 
         EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_));
-        verify_subject_and_serial(cert_chain_[0], serial_int, subject, false);
         ASSERT_EQ(cert_chain_.size(), 1);
+        verify_subject_and_serial(cert_chain_[0], serial_int, subject, false);
 
         AuthorizationSet hw_enforced = HwEnforcedAuthorizations(key_characteristics);
         AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics);
@@ -2443,6 +2451,29 @@
 }
 
 /*
+ * NewKeyGenerationTest.EcdsaMissingCurve
+ *
+ * Verifies that EC key generation fails if EC_CURVE not specified after KeyMint V2.
+ */
+TEST_P(NewKeyGenerationTest, EcdsaMissingCurve) {
+    if (AidlVersion() < 2) {
+        /*
+         * The KeyMint V1 spec required that EC_CURVE be specified for EC keys.
+         * However, this was not checked at the time so we can only be strict about checking this
+         * for implementations of KeyMint version 2 and above.
+         */
+        GTEST_SKIP() << "Requiring EC_CURVE only strict since KeyMint v2";
+    }
+    /* If EC_CURVE not provided, generateKey
+     * must return ErrorCode::UNSUPPORTED_KEY_SIZE or ErrorCode::UNSUPPORTED_EC_CURVE.
+     */
+    auto result = GenerateKey(
+            AuthorizationSetBuilder().EcdsaKey(256).Digest(Digest::NONE).SetDefaultValidity());
+    ASSERT_TRUE(result == ErrorCode::UNSUPPORTED_KEY_SIZE ||
+                result == ErrorCode::UNSUPPORTED_EC_CURVE);
+}
+
+/*
  * NewKeyGenerationTest.EcdsaMismatchKeySize
  *
  * Verifies that specifying mismatched key size and curve for EC key generation returns
@@ -3771,7 +3802,7 @@
 // TODO(seleneh) add ExportKey to GenerateKey
 // check result
 
-class ImportKeyTest : public KeyMintAidlTestBase {
+class ImportKeyTest : public NewKeyGenerationTest {
   public:
     template <TagType tag_type, Tag tag, typename ValueT>
     void CheckCryptoParam(TypedTag<tag_type, tag> ttag, ValueT expected) {
@@ -4481,6 +4512,65 @@
     VerifyMessage(message, signature, AuthorizationSetBuilder().Digest(Digest::SHA_2_256));
 }
 
+/*
+ * ImportKeyTest.GetKeyCharacteristics
+ *
+ * Verifies that imported keys have the correct characteristics.
+ */
+TEST_P(ImportKeyTest, GetKeyCharacteristics) {
+    vector<uint8_t> key_blob;
+    vector<KeyCharacteristics> key_characteristics;
+    auto base_builder = AuthorizationSetBuilder()
+                                .Padding(PaddingMode::NONE)
+                                .Authorization(TAG_NO_AUTH_REQUIRED)
+                                .SetDefaultValidity();
+    vector<Algorithm> algorithms = {Algorithm::RSA, Algorithm::EC, Algorithm::HMAC, Algorithm::AES,
+                                    Algorithm::TRIPLE_DES};
+    ErrorCode result;
+    string symKey = hex2str("a49d7564199e97cb529d2c9d97bf2f98");                   // 128 bits
+    string tdesKey = hex2str("a49d7564199e97cb529d2c9d97bf2f98d35edf57ba1f7358");  // 192 bits
+    for (auto alg : algorithms) {
+        SCOPED_TRACE(testing::Message() << "Algorithm-" << alg);
+        AuthorizationSetBuilder builder(base_builder);
+        switch (alg) {
+            case Algorithm::RSA:
+                builder.RsaSigningKey(2048, 65537).Digest(Digest::NONE);
+
+                result = ImportKey(builder, KeyFormat::PKCS8, rsa_2048_key, &key_blob,
+                                   &key_characteristics);
+                break;
+            case Algorithm::EC:
+                builder.EcdsaSigningKey(EcCurve::P_256).Digest(Digest::NONE);
+                result = ImportKey(builder, KeyFormat::PKCS8, ec_256_key, &key_blob,
+                                   &key_characteristics);
+                break;
+            case Algorithm::HMAC:
+                builder.HmacKey(128)
+                        .Digest(Digest::SHA_2_256)
+                        .Authorization(TAG_MIN_MAC_LENGTH, 128);
+                result =
+                        ImportKey(builder, KeyFormat::RAW, symKey, &key_blob, &key_characteristics);
+                break;
+            case Algorithm::AES:
+                builder.AesEncryptionKey(128).BlockMode(BlockMode::ECB);
+                result =
+                        ImportKey(builder, KeyFormat::RAW, symKey, &key_blob, &key_characteristics);
+                break;
+            case Algorithm::TRIPLE_DES:
+                builder.TripleDesEncryptionKey(168).BlockMode(BlockMode::ECB);
+                result = ImportKey(builder, KeyFormat::RAW, tdesKey, &key_blob,
+                                   &key_characteristics);
+                break;
+            default:
+                ADD_FAILURE() << "Invalid Algorithm " << uint32_t(alg);
+                continue;
+        }
+        ASSERT_EQ(ErrorCode::OK, result);
+        CheckCharacteristics(key_blob, key_characteristics);
+        CheckCommonParams(key_characteristics, KeyOrigin::IMPORTED);
+    }
+}
+
 INSTANTIATE_KEYMINT_AIDL_TEST(ImportKeyTest);
 
 auto wrapped_key = hex2str(
@@ -5079,6 +5169,79 @@
 }
 
 /*
+ * EncryptionOperationsTest.RsaOaepMGFDigestDefaultSuccess
+ *
+ * Verifies that RSA-OAEP decryption operations work when no MGF digest is
+ * specified, defaulting to SHA-1.
+ */
+TEST_P(EncryptionOperationsTest, RsaOaepMGFDigestDefaultSuccess) {
+    size_t key_size = 2048;
+    ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
+                                                 .Authorization(TAG_NO_AUTH_REQUIRED)
+                                                 .RsaEncryptionKey(key_size, 65537)
+                                                 .Padding(PaddingMode::RSA_OAEP)
+                                                 .Digest(Digest::SHA_2_256)
+                                                 .SetDefaultValidity()));
+
+    // Do local RSA encryption using the default MGF digest of SHA-1.
+    string message = "Hello";
+    auto params =
+            AuthorizationSetBuilder().Digest(Digest::SHA_2_256).Padding(PaddingMode::RSA_OAEP);
+    string ciphertext = LocalRsaEncryptMessage(message, params);
+    EXPECT_EQ(key_size / 8, ciphertext.size());
+
+    // Do KeyMint RSA decryption also using the default MGF digest of SHA-1.
+    string plaintext = DecryptMessage(ciphertext, params);
+    EXPECT_EQ(message, plaintext) << "RSA-OAEP failed with default digest";
+
+    // Decrypting corrupted ciphertext should fail.
+    size_t offset_to_corrupt = random() % ciphertext.size();
+    char corrupt_byte;
+    do {
+        corrupt_byte = static_cast<char>(random() % 256);
+    } while (corrupt_byte == ciphertext[offset_to_corrupt]);
+    ciphertext[offset_to_corrupt] = corrupt_byte;
+
+    EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, params));
+    string result;
+    EXPECT_EQ(ErrorCode::UNKNOWN_ERROR, Finish(ciphertext, &result));
+    EXPECT_EQ(0U, result.size());
+}
+
+/*
+ * EncryptionOperationsTest.RsaOaepMGFDigestDefaultFail
+ *
+ * Verifies that RSA-OAEP decryption operations fail when no MGF digest is
+ * specified on begin (thus defaulting to SHA-1), but the key characteristics
+ * has an explicit set of values for MGF_DIGEST that do not contain SHA-1.
+ */
+TEST_P(EncryptionOperationsTest, RsaOaepMGFDigestDefaultFail) {
+    size_t key_size = 2048;
+    ASSERT_EQ(ErrorCode::OK,
+              GenerateKey(AuthorizationSetBuilder()
+                                  .Authorization(TAG_NO_AUTH_REQUIRED)
+                                  .Authorization(TAG_RSA_OAEP_MGF_DIGEST, Digest::SHA_2_256)
+                                  .RsaEncryptionKey(key_size, 65537)
+                                  .Padding(PaddingMode::RSA_OAEP)
+                                  .Digest(Digest::SHA_2_256)
+                                  .SetDefaultValidity()));
+
+    // Do local RSA encryption using the default MGF digest of SHA-1.
+    string message = "Hello";
+    auto params =
+            AuthorizationSetBuilder().Digest(Digest::SHA_2_256).Padding(PaddingMode::RSA_OAEP);
+    string ciphertext = LocalRsaEncryptMessage(message, params);
+    EXPECT_EQ(key_size / 8, ciphertext.size());
+
+    // begin() params do not include MGF_DIGEST, so a default of SHA1 is assumed.
+    // Key characteristics *do* include values for MGF_DIGEST, so the SHA1 value
+    // is checked against those values, and found absent.
+    auto result = Begin(KeyPurpose::DECRYPT, params);
+    EXPECT_TRUE(result == ErrorCode::UNSUPPORTED_MGF_DIGEST ||
+                result == ErrorCode::INCOMPATIBLE_MGF_DIGEST);
+}
+
+/*
  * EncryptionOperationsTest.RsaOaepWithMGFIncompatibleDigest
  *
  * Verifies that RSA-OAEP decryption operations fail in the correct way when asked to operate
@@ -5481,18 +5644,45 @@
 
         EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, params));
         string plaintext;
-        ErrorCode error = Finish(message, &plaintext);
-        if (error == ErrorCode::INVALID_INPUT_LENGTH) {
+        ErrorCode error = Finish(ciphertext, &plaintext);
+        if (error == ErrorCode::INVALID_ARGUMENT) {
             // This is the expected error, we can exit the test now.
             return;
         } else {
             // Very small chance we got valid decryption, so try again.
-            ASSERT_EQ(error, ErrorCode::OK);
+            ASSERT_EQ(error, ErrorCode::OK)
+                    << "Expected INVALID_ARGUMENT or (rarely) OK, got " << error;
         }
     }
     FAIL() << "Corrupt ciphertext should have failed to decrypt by now.";
 }
 
+/*
+ * EncryptionOperationsTest.AesEcbPkcs7CiphertextTooShort
+ *
+ * Verifies that AES decryption fails in the correct way when the padding is corrupted.
+ */
+TEST_P(EncryptionOperationsTest, AesEcbPkcs7CiphertextTooShort) {
+    ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
+                                                 .Authorization(TAG_NO_AUTH_REQUIRED)
+                                                 .AesEncryptionKey(128)
+                                                 .Authorization(TAG_BLOCK_MODE, BlockMode::ECB)
+                                                 .Padding(PaddingMode::PKCS7)));
+
+    auto params = AuthorizationSetBuilder().BlockMode(BlockMode::ECB).Padding(PaddingMode::PKCS7);
+
+    string message = "a";
+    string ciphertext = EncryptMessage(message, params);
+    EXPECT_EQ(16U, ciphertext.size());
+    EXPECT_NE(ciphertext, message);
+
+    // Shorten the ciphertext.
+    ciphertext.resize(ciphertext.size() - 1);
+    EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, params));
+    string plaintext;
+    EXPECT_EQ(ErrorCode::INVALID_INPUT_LENGTH, Finish(ciphertext, &plaintext));
+}
+
 vector<uint8_t> CopyIv(const AuthorizationSet& set) {
     auto iv = set.GetTagValue(TAG_NONCE);
     EXPECT_TRUE(iv);
@@ -5582,6 +5772,328 @@
     CheckAesIncrementalEncryptOperation(BlockMode::GCM, 240);
 }
 
+/*
+ * EncryptionOperationsTest.Aes128CBCNoPaddingOneByteAtATime
+ * Verifies input and output sizes of AES/CBC/NoPadding Algorithm.
+ */
+TEST_P(EncryptionOperationsTest, Aes128CBCNoPaddingOneByteAtATime) {
+    string kat_key = hex2str("7E3D723C09A9852B24F584F9D916F6A8");
+    string kat_iv = hex2str("944AE274D983892EADE422274858A96A");
+    string kat_plaintext =
+            hex2str("044E15899A080AADEB6778F64323B64D2CBCBADB338DF93B9AC459D4F41029"
+                    "809FFF37081C22EF278F896AB213A2A631");
+    string kat_ciphertext =
+            hex2str("B419293FCBD686F2913D1CF947E510D42FAFEDE5593C98AFD6AEE272596A"
+                    "56FE42C22F2A5E3B6A02BA9D8D0DE1E9A810");
+    AesCheckEncryptOneByteAtATime(kat_key, BlockMode::CBC, PaddingMode::NONE, kat_iv, kat_plaintext,
+                                  kat_ciphertext);
+}
+
+/*
+ * EncryptionOperationsTest.Aes128CBCPKCS7PaddingOneByteAtATime
+ * Verifies input and output sizes of AES/CBC/PKCS7Padding Algorithm.
+ */
+TEST_P(EncryptionOperationsTest, Aes128CBCPKCS7PaddingOneByteAtATime) {
+    string kat_key = hex2str("F16E698472578E919D92806262C5169F");
+    string kat_iv = hex2str("EF743540F8421ACA128A3247521F3E7D");
+    string kat_plaintext =
+            hex2str("5BEBF33569D90BF5E853814E12E7C7AA5758013F755773E29F4A25EC26EEB7"
+                    "65F7F2DC251F7DC62AEFCA1E8A5A11A1DCD44F0BD8FB593A5AE3");
+    string kat_ciphertext =
+            hex2str("3197CF6DB9466188B5FED375329324EE7D6092A8C0E41DFAF49E3724271427"
+                    "896D56A6243C0D59D6639722AF93CD53449BDDABF9C5F153EBDBFED9ED98C8CC37");
+    AesCheckEncryptOneByteAtATime(kat_key, BlockMode::CBC, PaddingMode::PKCS7, kat_iv,
+                                  kat_plaintext, kat_ciphertext);
+}
+
+/*
+ * EncryptionOperationsTest.Aes128CTRNoPaddingOneByteAtATime
+ * Verifies input and output sizes of AES/CTR/NoPadding Algorithm.
+ */
+TEST_P(EncryptionOperationsTest, Aes128CTRNoPaddingOneByteAtATime) {
+    string kat_key = hex2str("4713a7b2f93efe809b42ecc45213ef9f");
+    string kat_iv = hex2str("ebfa19b0ebf3d57feabd4c4bd04bea01");
+    string kat_plaintext =
+            hex2str("6d2c07e1fc86f99c6e2a8f6567828b4262a9c23d0f3ed8ab32482283c79796"
+                    "f0adba1bcd3736084996452a917fae98005aebe61f9e91c3");
+    string kat_ciphertext =
+            hex2str("345deb1d67b95e600e05cad4c32ec381aadb3e2c1ec7e0fb956dc38e6860cf"
+                    "0553535566e1b12fa9f87d29266ca26df427233df035df28");
+    AesCheckEncryptOneByteAtATime(kat_key, BlockMode::CTR, PaddingMode::NONE, kat_iv, kat_plaintext,
+                                  kat_ciphertext);
+}
+
+/*
+ * EncryptionOperationsTest.Aes128ECBNoPaddingOneByteAtATime
+ * Verifies input and output sizes of AES/ECB/NoPadding Algorithm.
+ */
+TEST_P(EncryptionOperationsTest, Aes128ECBNoPaddingOneByteAtATime) {
+    string kat_key = hex2str("7DA2467F068854B3CB36E5C333A16619");
+    string kat_plaintext =
+            hex2str("9A07C9575AD9CE209DF9F3953965CEBE8208587C7AE575A1904BF25048946D"
+                    "7B6168A9A27BCE554BEA94EF26E6C742A0");
+    string kat_ciphertext =
+            hex2str("8C47E49420FC92AC4CA2C601BC3F8AC31D01B260B7B849F2B8EEDFFFED8F36"
+                    "C31CBDA0D22F95C9C2A48C347E8C77AC82");
+    AesCheckEncryptOneByteAtATime(kat_key, BlockMode::ECB, PaddingMode::NONE, "", kat_plaintext,
+                                  kat_ciphertext);
+}
+
+/*
+ * EncryptionOperationsTest.Aes128ECBPKCS7PaddingOneByteAtATime
+ * Verifies input and output sizes of AES/ECB/PKCS7Padding Algorithm.
+ */
+TEST_P(EncryptionOperationsTest, Aes128ECBPKCS7PaddingOneByteAtATime) {
+    string kat_key = hex2str("C3BE04BCCB3D99B85290F113FE7AF194");
+    string kat_plaintext =
+            hex2str("348C213FD8DF3F990C20C5ACBF07B34B6264AE245784A5A6176DBFB1C2E7DD"
+                    "27E52CC92B8EEE40614F05B507B355F6354A2705BD86");
+    string kat_ciphertext =
+            hex2str("07CD05C41FEDEDDC5DB4B3E35E676153184A119AA4DFDDC290616F1FA60093"
+                    "1DE6BEA9BDB90D1D733899946F8C8E5C0C4383F99F5D88E27F3EBC0C6E52759ED3");
+    AesCheckEncryptOneByteAtATime(kat_key, BlockMode::ECB, PaddingMode::PKCS7, "", kat_plaintext,
+                                  kat_ciphertext);
+}
+
+/*
+ * EncryptionOperationsTest.Aes128GCMNoPaddingOneByteAtATime
+ * Verifies input and output sizes of AES/GCM/NoPadding Algorithm.
+ */
+TEST_P(EncryptionOperationsTest, Aes128GCMNoPaddingOneByteAtATime) {
+    string kat_key = hex2str("ba76354f0aed6e8d91f45c4ff5a062db");
+    string kat_iv = hex2str("b79437ae08ff355d7d8a4d0f");
+    string kat_plaintext =
+            hex2str("6d7596a8fd56ceaec61de7940984b7736fec44f572afc3c8952e4dc6541e2b"
+                    "c6a702c440a37610989543f63fedb047ca2173bc18581944");
+    string kat_ciphertext =
+            hex2str("b3f6799e8f9326f2df1e80fcd2cb16d78c9dc7cc14bb677862dc6c639b3a63"
+                    "38d24b312d3989e5920b5dbfc976765efbfe57bb385940a7a43bdf05bddae3c9d6a2fb"
+                    "bdfcc0cba0");
+
+    AesCheckEncryptOneByteAtATime(kat_key, BlockMode::GCM, PaddingMode::NONE, kat_iv, kat_plaintext,
+                                  kat_ciphertext);
+}
+
+/*
+ * EncryptionOperationsTest.Aes192CBCNoPaddingOneByteAtATime
+ * Verifies input and output sizes of AES/CBC/NoPadding Algorithm.
+ */
+TEST_P(EncryptionOperationsTest, Aes192CBCNoPaddingOneByteAtATime) {
+    if (SecLevel() == SecurityLevel::STRONGBOX) {
+        GTEST_SKIP() << "Key size 192 is not supported by Strongbox.";
+    }
+    string kat_key = hex2str("be8cc4e25cce46e5d55725e2391f7d3cf59ed60062f5a43b");
+    string kat_iv = hex2str("80a199aab0eee77e7762ddf3b3a32f40");
+    string kat_plaintext =
+            hex2str("064f9200e0df37d4711af4a69d11addf9e1c345d9d8195f9f1f715019ce96a"
+                    "167f2497c994bd496eb80bfb2ba2c9d5af");
+    string kat_ciphertext =
+            hex2str("859b90becaa85e95a71e104efbd7a3b723bcbf4eb39865544a05d9e90b6fe5"
+                    "72c134552f3a138e726fbe493b3a839598");
+    AesCheckEncryptOneByteAtATime(kat_key, BlockMode::CBC, PaddingMode::NONE, kat_iv, kat_plaintext,
+                                  kat_ciphertext);
+}
+
+/*
+ * EncryptionOperationsTest.Aes192CBCPKCS7PaddingOneByteAtATime
+ * Verifies input and output sizes of AES/CBC/PKCS7Padding Algorithm.
+ */
+TEST_P(EncryptionOperationsTest, Aes192CBCPKCS7PaddingOneByteAtATime) {
+    if (SecLevel() == SecurityLevel::STRONGBOX) {
+        GTEST_SKIP() << "Key size 192 is not supported by Strongbox.";
+    }
+    string kat_key = hex2str("68969215ec41e4df7d23de0e806f458f52aff492bd7c5263");
+    string kat_iv = hex2str("e61d13dfbf0533289f0e7950209da418");
+    string kat_plaintext =
+            hex2str("8d4c1cac27511ee2d82409a7f378e7e402b0eb189c1eaa5c506eb72a9074"
+                    "b170");
+    string kat_ciphertext =
+            hex2str("e70bcd62c595dc1b2b8c197bb91a7447e1be2cbcf3fdc69e7e991faf0f57cf"
+                    "4e3884138ff403a41fd99818708ada301c");
+    AesCheckEncryptOneByteAtATime(kat_key, BlockMode::CBC, PaddingMode::PKCS7, kat_iv,
+                                  kat_plaintext, kat_ciphertext);
+}
+
+/*
+ * EncryptionOperationsTest.Aes192CTRNoPaddingOneByteAtATime
+ * Verifies input and output sizes of AES/CTR/NoPadding Algorithm.
+ */
+TEST_P(EncryptionOperationsTest, Aes192CTRNoPaddingOneByteAtATime) {
+    if (SecLevel() == SecurityLevel::STRONGBOX) {
+        GTEST_SKIP() << "Key size 192 is not supported by Strongbox.";
+    }
+    string kat_key = hex2str("5e2036e790d38815c90beb67a1c9e5aa0e167ef082927317");
+    string kat_iv = hex2str("df0694959b89054156962d68a226965c");
+    string kat_plaintext =
+            hex2str("6ed2781c99e03e45314d6019932220c2c98130c53f9f67ad10ac519adf50e9"
+                    "28091e09cdbbd3b42b");
+    string kat_ciphertext =
+            hex2str("e427b6666502e05b82d0b20ae50e862b1936d71266fc49178ac984e71571f2"
+                    "2ae0f90f0c19f42b4a");
+    AesCheckEncryptOneByteAtATime(kat_key, BlockMode::CTR, PaddingMode::NONE, kat_iv, kat_plaintext,
+                                  kat_ciphertext);
+}
+
+/*
+ * EncryptionOperationsTest.Aes192ECBNoPaddingOneByteAtATime
+ * Verifies input and output sizes of AES/ECB/NoPadding Algorithm.
+ */
+TEST_P(EncryptionOperationsTest, Aes192ECBNoPaddingOneByteAtATime) {
+    if (SecLevel() == SecurityLevel::STRONGBOX) {
+        GTEST_SKIP() << "Key size 192 is not supported by Strongbox.";
+    }
+    string kat_key = hex2str("3cab83fb338ba985fbfe74c5e9d2e900adb570b1d67faf92");
+    string kat_plaintext =
+            hex2str("2cc64c335a13fb838f3c6aad0a6b47297ca90bb886ddb059200f0b41740c"
+                    "44ab");
+    string kat_ciphertext =
+            hex2str("9c5c825328f5ee0aa24947e374d3f9165f484b39dd808c790d7a12964810"
+                    "2453");
+    AesCheckEncryptOneByteAtATime(kat_key, BlockMode::ECB, PaddingMode::NONE, "", kat_plaintext,
+                                  kat_ciphertext);
+}
+
+/*
+ * EncryptionOperationsTest.Aes192ECBPKCS7PaddingOneByteAtATime
+ * Verifies input and output sizes of AES/ECB/PKCS7Padding Algorithm.
+ */
+TEST_P(EncryptionOperationsTest, Aes192ECBPKCS7PaddingOneByteAtATime) {
+    if (SecLevel() == SecurityLevel::STRONGBOX) {
+        GTEST_SKIP() << "Key size 192 is not supported by Strongbox.";
+    }
+    string kat_key = hex2str("d57f4e5446f736c16476ec4db5decc7b1bf3936e4f7e4618");
+    string kat_plaintext =
+            hex2str("b115777f1ee7a43a07daa6401e59c46b7a98213a8747eabfbe3ca4ec93524d"
+                    "e2c7");
+    string kat_ciphertext =
+            hex2str("1e92cd20da08bb5fa174a7a69879d4fc25a155e6af06d75b26c5b450d273c8"
+                    "bb7e3a889dd4a9589098b44acf1056e7aa");
+    AesCheckEncryptOneByteAtATime(kat_key, BlockMode::ECB, PaddingMode::PKCS7, "", kat_plaintext,
+                                  kat_ciphertext);
+}
+
+/*
+ * EncryptionOperationsTest.Aes192GCMNoPaddingOneByteAtATime
+ * Verifies input and output sizes of AES/GCM/NoPadding Algorithm.
+ */
+TEST_P(EncryptionOperationsTest, Aes192GCMNoPaddingOneByteAtATime) {
+    if (SecLevel() == SecurityLevel::STRONGBOX) {
+        GTEST_SKIP() << "Key size 192 is not supported by Strongbox.";
+    }
+    string kat_key = hex2str("21339fc1d011abca65d50ce2365230603fd47d07e8830f6e");
+    string kat_iv = hex2str("d5fb1469a8d81dd75286a418");
+    string kat_plaintext =
+            hex2str("cf776dedf53a828d51a0073db3ef0dd1ee19e2e9e243ce97e95841bb9ad4e3"
+                    "ff52");
+    string kat_ciphertext =
+            hex2str("3a0d48278111d3296bc663df8a5dbeb2474ea47fd85b608f8d9375d9dcf7de"
+                    "1413ad70fb0e1970669095ad77ebb5974ae8");
+
+    AesCheckEncryptOneByteAtATime(kat_key, BlockMode::GCM, PaddingMode::NONE, kat_iv, kat_plaintext,
+                                  kat_ciphertext);
+}
+
+/*
+ * EncryptionOperationsTest.Aes256CBCNoPaddingOneByteAtATime
+ * Verifies input and output sizes of AES/CBC/NoPadding Algorithm.
+ */
+TEST_P(EncryptionOperationsTest, Aes256CBCNoPaddingOneByteAtATime) {
+    string kat_key = hex2str("dd2f20dc6b98c100bac919120ff95eb5d96003f8229987b283a1e777b0cd5c30");
+    string kat_iv = hex2str("23b4d85239fb90db93b07a981e90a170");
+    string kat_plaintext =
+            hex2str("2fbe5d46dca5cea433e550d8b291740ab9551c2a2d37680d7fb7b993225f58"
+                    "494cb53caca353e4b637ba05687be20f8d");
+    string kat_ciphertext =
+            hex2str("5aba24fc316936c8369061ee8fe463e4faed04288e204456626b988c0e376b"
+                    "6047da1e4fd7c4e1cf2656097f75ae8685");
+    AesCheckEncryptOneByteAtATime(kat_key, BlockMode::CBC, PaddingMode::NONE, kat_iv, kat_plaintext,
+                                  kat_ciphertext);
+}
+
+/*
+ * EncryptionOperationsTest.Aes256CBCPKCS7PaddingOneByteAtATime
+ * Verifies input and output sizes of AES/CBC/PKCS7Padding Algorithm.
+ */
+TEST_P(EncryptionOperationsTest, Aes256CBCPKCS7PaddingOneByteAtATime) {
+    string kat_key = hex2str("03ab2510520f5cfebfab0a17a7f8324c9634911f6fc59e586f85346bb38ac88a");
+    string kat_iv = hex2str("9af96967195bb0184f129beffa8241ae");
+    string kat_plaintext =
+            hex2str("2d6944653ac14988a772a2730b7c5bfa99a21732ae26f40cdc5b3a2874c794"
+                    "2545a82b73c48078b9dae62261c65909");
+    string kat_ciphertext =
+            hex2str("26b308f7e1668b55705a79c8b3ad10e244655f705f027f390a5c34e4536f51"
+                    "9403a71987b95124073d69f2a3cb95b0ab");
+    AesCheckEncryptOneByteAtATime(kat_key, BlockMode::CBC, PaddingMode::PKCS7, kat_iv,
+                                  kat_plaintext, kat_ciphertext);
+}
+
+/*
+ * EncryptionOperationsTest.Aes256CTRNoPaddingOneByteAtATime
+ * Verifies input and output sizes of AES/CTR/NoPadding Algorithm.
+ */
+TEST_P(EncryptionOperationsTest, Aes256CTRNoPaddingOneByteAtATime) {
+    string kat_key = hex2str("928b380a8fed4b4b4cfeb56e0c66a4cb0f9ff58d61ac68bcfd0e3fbd910a684f");
+    string kat_iv = hex2str("0b678a5249e6eeda461dfb4776b6c58e");
+    string kat_plaintext =
+            hex2str("f358de57543b297e997cba46fb9100553d6abd65377e55b9aac3006400ead1"
+                    "1f6db3c884");
+    string kat_ciphertext =
+            hex2str("a07a35fbd1776ad81462e1935f542337add60962bf289249476817b6ddd532"
+                    "a7be30d4c3");
+    AesCheckEncryptOneByteAtATime(kat_key, BlockMode::CTR, PaddingMode::NONE, kat_iv, kat_plaintext,
+                                  kat_ciphertext);
+}
+
+/*
+ * EncryptionOperationsTest.Aes256ECBNoPaddingOneByteAtATime
+ * Verifies input and output sizes of AES/ECB/NoPadding Algorithm.
+ */
+TEST_P(EncryptionOperationsTest, Aes256ECBNoPaddingOneByteAtATime) {
+    string kat_key = hex2str("fa4622d9cf6485075daedd33d2c4fffdf859e2edb7f7df4f04603f7e647fae90");
+    string kat_plaintext =
+            hex2str("96ccabbe0c68970d8cdee2b30ab43c2d61cc50ee68271e77571e72478d713a"
+                    "31a476d6806b8116089c6ec50bb543200f");
+    string kat_ciphertext =
+            hex2str("0e81839e9dfbfe3b503d619e676abe5ac80fac3f245d8f09b9134b1b32a67d"
+                    "c83e377faf246288931136bef2a07c0be4");
+    AesCheckEncryptOneByteAtATime(kat_key, BlockMode::ECB, PaddingMode::NONE, "", kat_plaintext,
+                                  kat_ciphertext);
+}
+
+/*
+ * EncryptionOperationsTest.Aes256ECBPKCS7PaddingOneByteAtATime
+ * Verifies input and output sizes of AES/ECB/PKCS7Padding Algorithm.
+ */
+TEST_P(EncryptionOperationsTest, Aes256ECBPKCS7PaddingOneByteAtATime) {
+    string kat_key = hex2str("bf3f07c68467fead0ca8e2754500ab514258abf02eb7e615a493bcaaa45d5ee1");
+    string kat_plaintext =
+            hex2str("af0757e49018dad628f16998628a407db5f28291bef3bc2e4d8a5a31fb238e"
+                    "6f");
+    string kat_ciphertext =
+            hex2str("21ec3011074bf1ef140643d47130326c5e183f61237c69bc77551ca207d71f"
+                    "c2b90cfac6c8d2d125e5cd9ff353dee0df");
+    AesCheckEncryptOneByteAtATime(kat_key, BlockMode::ECB, PaddingMode::PKCS7, "", kat_plaintext,
+                                  kat_ciphertext);
+}
+
+/*
+ * EncryptionOperationsTest.Aes256GCMNoPaddingOneByteAtATime
+ * Verifies input and output sizes of AES/GCM/NoPadding Algorithm.
+ */
+TEST_P(EncryptionOperationsTest, Aes256GCMNoPaddingOneByteAtATime) {
+    string kat_key = hex2str("7972140d831eedac75d5ea515c9a4c3bb124499a90b5f317ac1a685e88fae395");
+    string kat_iv = hex2str("a66c5252808d823dd4151fed");
+    string kat_plaintext =
+            hex2str("c2b9dabf3a55adaa94e8c0d1e77a84a3435aee23b2c3c4abb587b09a9c2afb"
+                    "f0");
+    string kat_ciphertext =
+            hex2str("a960619314657b2afb96b93bebb372bffd09e19d53e351f17d1ba2611f9dc3"
+                    "3c9c92d563e8fd381254ac262aa2a4ea0d");
+
+    AesCheckEncryptOneByteAtATime(kat_key, BlockMode::GCM, PaddingMode::NONE, kat_iv, kat_plaintext,
+                                  kat_ciphertext);
+}
+
 struct AesCtrSp80038aTestVector {
     const char* key;
     const char* nonce;
@@ -5722,6 +6234,49 @@
 }
 
 /*
+ * EncryptionOperationsTest.AesCbcZeroInputSuccessb
+ *
+ * Verifies that keymaster generates correct output on zero-input with
+ * NonePadding mode
+ */
+TEST_P(EncryptionOperationsTest, AesCbcZeroInputSuccess) {
+    ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
+                                                 .Authorization(TAG_NO_AUTH_REQUIRED)
+                                                 .AesEncryptionKey(128)
+                                                 .BlockMode(BlockMode::CBC)
+                                                 .Padding(PaddingMode::NONE, PaddingMode::PKCS7)));
+
+    // Zero input message
+    string message = "";
+    for (auto padding : {PaddingMode::NONE, PaddingMode::PKCS7}) {
+        auto params = AuthorizationSetBuilder().BlockMode(BlockMode::CBC).Padding(padding);
+        AuthorizationSet out_params;
+        string ciphertext1 = EncryptMessage(message, params, &out_params);
+        vector<uint8_t> iv1 = CopyIv(out_params);
+        if (padding == PaddingMode::NONE)
+            EXPECT_EQ(message.size(), ciphertext1.size()) << "PaddingMode: " << padding;
+        else
+            EXPECT_EQ(message.size(), ciphertext1.size() - 16) << "PaddingMode: " << padding;
+
+        out_params.Clear();
+
+        string ciphertext2 = EncryptMessage(message, params, &out_params);
+        vector<uint8_t> iv2 = CopyIv(out_params);
+        if (padding == PaddingMode::NONE)
+            EXPECT_EQ(message.size(), ciphertext2.size()) << "PaddingMode: " << padding;
+        else
+            EXPECT_EQ(message.size(), ciphertext2.size() - 16) << "PaddingMode: " << padding;
+
+        // IVs should be random
+        EXPECT_NE(iv1, iv2) << "PaddingMode: " << padding;
+
+        params.push_back(TAG_NONCE, iv1);
+        string plaintext = DecryptMessage(ciphertext1, params);
+        EXPECT_EQ(message, plaintext) << "PaddingMode: " << padding;
+    }
+}
+
+/*
  * EncryptionOperationsTest.AesCallerNonce
  *
  * Verifies that AES caller-provided nonces work correctly.
@@ -6088,7 +6643,7 @@
 
     // Encrypt
     AuthorizationSet begin_out_params;
-    EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params, &begin_out_params));
+    ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params, &begin_out_params));
     string ciphertext;
     AuthorizationSet finish_out_params;
     ASSERT_EQ(ErrorCode::OK, UpdateAad(aad));
@@ -6131,7 +6686,7 @@
                                 .Authorization(TAG_MAC_LENGTH, tag_bits);
     AuthorizationSet begin_out_params;
 
-    EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, begin_params, &begin_out_params));
+    ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, begin_params, &begin_out_params));
 
     // No data, AAD only.
     EXPECT_EQ(ErrorCode::OK, UpdateAad("foo"));
@@ -6147,7 +6702,7 @@
     begin_params.push_back(begin_out_params);
 
     // Decrypt
-    EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params));
+    ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params));
     EXPECT_EQ(ErrorCode::OK, UpdateAad("foofoo"));
     string plaintext;
     EXPECT_EQ(ErrorCode::OK, Finish(ciphertext, &plaintext));
@@ -6174,7 +6729,7 @@
                                 .Authorization(TAG_MAC_LENGTH, 128);
     AuthorizationSet begin_out_params;
 
-    EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, begin_params, &begin_out_params));
+    ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, begin_params, &begin_out_params));
 
     EXPECT_EQ(ErrorCode::OK, UpdateAad("foo"));
     string ciphertext;
@@ -6208,7 +6763,7 @@
 
     // Encrypt
     AuthorizationSet begin_out_params;
-    EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, begin_params, &begin_out_params));
+    ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, begin_params, &begin_out_params));
     EXPECT_EQ(ErrorCode::OK, UpdateAad("foobar"));
     string ciphertext;
     EXPECT_EQ(ErrorCode::OK, Finish(message, &ciphertext));
@@ -6217,7 +6772,7 @@
     begin_params.push_back(begin_out_params);
 
     // Decrypt.
-    EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params, &begin_out_params));
+    ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params, &begin_out_params));
     EXPECT_EQ(ErrorCode::OK, UpdateAad("barfoo"));
     string plaintext;
     EXPECT_EQ(ErrorCode::VERIFICATION_FAILED, Finish(ciphertext, &plaintext));
@@ -6244,7 +6799,7 @@
 
     // Encrypt
     AuthorizationSet begin_out_params;
-    EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, begin_params, &begin_out_params));
+    ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, begin_params, &begin_out_params));
     EXPECT_EQ(ErrorCode::OK, UpdateAad("foobar"));
     string ciphertext;
     AuthorizationSet finish_out_params;
@@ -6254,7 +6809,7 @@
     begin_params.push_back(TAG_NONCE, AidlBuf("123456789012"));
 
     // Decrypt.
-    EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params, &begin_out_params));
+    ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params, &begin_out_params));
     EXPECT_EQ(ErrorCode::OK, UpdateAad("foobar"));
     string plaintext;
     EXPECT_EQ(ErrorCode::VERIFICATION_FAILED, Finish(ciphertext, &plaintext));
@@ -6286,7 +6841,7 @@
 
     // Encrypt
     AuthorizationSet begin_out_params;
-    EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params, &begin_out_params));
+    ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params, &begin_out_params));
     EXPECT_EQ(ErrorCode::OK, UpdateAad(aad));
     string ciphertext;
     EXPECT_EQ(ErrorCode::OK, Finish(message, &ciphertext));
@@ -6298,7 +6853,7 @@
     params.push_back(begin_out_params);
 
     // Decrypt.
-    EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, params));
+    ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, params));
     EXPECT_EQ(ErrorCode::OK, UpdateAad(aad));
     string plaintext;
     EXPECT_EQ(ErrorCode::VERIFICATION_FAILED, Finish(ciphertext, &plaintext));
@@ -6411,7 +6966,7 @@
     for (size_t i = 0; i < kMaxPaddingCorruptionRetries; ++i) {
         ++ciphertext[ciphertext.size() / 2];
 
-        EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params));
+        ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params));
         string plaintext;
         EXPECT_EQ(ErrorCode::OK, Update(ciphertext, &plaintext));
         ErrorCode error = Finish(&plaintext);
@@ -6683,7 +7238,7 @@
         auto begin_params =
                 AuthorizationSetBuilder().BlockMode(blockMode).Padding(PaddingMode::NONE);
         AuthorizationSet output_params;
-        EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, begin_params, &output_params));
+        ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, begin_params, &output_params));
         string ciphertext;
         EXPECT_EQ(ErrorCode::INVALID_INPUT_LENGTH, Finish(message, "", &ciphertext));
 
@@ -6762,7 +7317,7 @@
     for (size_t i = 0; i < kMaxPaddingCorruptionRetries; ++i) {
         SCOPED_TRACE(testing::Message() << "i = " << i);
         ++ciphertext[ciphertext.size() / 2];
-        EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params));
+        ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params));
         string plaintext;
         EXPECT_EQ(ErrorCode::OK, Update(ciphertext, &plaintext));
         ErrorCode error = Finish(&plaintext);
@@ -6794,7 +7349,7 @@
     AuthorizationSet input_params =
             AuthorizationSetBuilder().BlockMode(BlockMode::CBC).Padding(PaddingMode::NONE);
     AuthorizationSet output_params;
-    EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, input_params, &output_params));
+    ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, input_params, &output_params));
 
     string ciphertext;
     for (size_t i = 0; i < message.size(); i += increment)
@@ -6808,7 +7363,7 @@
     input_params.push_back(TAG_PADDING, PaddingMode::NONE);
     output_params.Clear();
 
-    EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, input_params, &output_params));
+    ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, input_params, &output_params));
     string plaintext;
     for (size_t i = 0; i < ciphertext.size(); i += increment)
         EXPECT_EQ(ErrorCode::OK, Update(ciphertext.substr(i, increment), &plaintext));
@@ -6925,7 +7480,7 @@
     } else {
         // Usage count limit tag is enforced by keystore, keymint does nothing.
         EXPECT_TRUE(keystore_auths.Contains(TAG_USAGE_COUNT_LIMIT, 1U));
-        EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params));
+        ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params));
     }
 }
 
@@ -6972,7 +7527,7 @@
     } else {
         // Usage count limit tag is enforced by keystore, keymint does nothing.
         EXPECT_TRUE(keystore_auths.Contains(TAG_USAGE_COUNT_LIMIT, 3U));
-        EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params));
+        ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params));
     }
 }
 
@@ -7018,7 +7573,7 @@
     } else {
         // Usage count limit tag is enforced by keystore, keymint does nothing.
         EXPECT_TRUE(keystore_auths.Contains(TAG_USAGE_COUNT_LIMIT, 1U));
-        EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::SIGN, params));
+        ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::SIGN, params));
     }
 }
 
@@ -7065,7 +7620,7 @@
     } else {
         // Usage count limit tag is enforced by keystore, keymint does nothing.
         EXPECT_TRUE(keystore_auths.Contains(TAG_USAGE_COUNT_LIMIT, 3U));
-        EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::SIGN, params));
+        ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::SIGN, params));
     }
 }
 
@@ -7378,7 +7933,7 @@
         EXPECT_EQ(ErrorCode::OK, Abort(op_handles[j]))
                 << "Aboort failed for i = " << j << std::endl;
     }
-    EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, key_blob_, params, &out_params));
+    ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, key_blob_, params, &out_params));
     AbortIfNeeded();
 }
 
@@ -7403,7 +7958,7 @@
                 AuthorizationSetBuilder().BlockMode(BlockMode::ECB).Padding(PaddingMode::NONE);
 
         AuthorizationSet out_params;
-        EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, cipher_params, &out_params));
+        ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, cipher_params, &out_params));
 
         string plain_message = std::string(1 << msg_size, 'x');
         string encrypted_message;
@@ -7414,7 +7969,7 @@
                 << "Encrypt finish returned OK, but did not consume all of the given input";
         cipher_params.push_back(out_params);
 
-        EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, cipher_params));
+        ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, cipher_params));
 
         string decrypted_message;
         rc = Finish(encrypted_message, &decrypted_message);
@@ -7450,7 +8005,6 @@
             uint8_t privKeyData[32];
             uint8_t pubKeyData[32];
             X25519_keypair(pubKeyData, privKeyData);
-            *localPublicKey = vector<uint8_t>(pubKeyData, pubKeyData + 32);
             *localPrivKey = EVP_PKEY_Ptr(EVP_PKEY_new_raw_private_key(
                     EVP_PKEY_X25519, nullptr, privKeyData, sizeof(privKeyData)));
         } else {
@@ -7462,16 +8016,15 @@
             ASSERT_EQ(EC_KEY_generate_key(ecKey.get()), 1);
             *localPrivKey = EVP_PKEY_Ptr(EVP_PKEY_new());
             ASSERT_EQ(EVP_PKEY_set1_EC_KEY(localPrivKey->get(), ecKey.get()), 1);
-
-            // Get encoded form of the public part of the locally generated key...
-            unsigned char* p = nullptr;
-            int localPublicKeySize = i2d_PUBKEY(localPrivKey->get(), &p);
-            ASSERT_GT(localPublicKeySize, 0);
-            *localPublicKey =
-                    vector<uint8_t>(reinterpret_cast<const uint8_t*>(p),
-                                    reinterpret_cast<const uint8_t*>(p + localPublicKeySize));
-            OPENSSL_free(p);
         }
+
+        // Get encoded form of the public part of the locally generated key...
+        unsigned char* p = nullptr;
+        int localPublicKeySize = i2d_PUBKEY(localPrivKey->get(), &p);
+        ASSERT_GT(localPublicKeySize, 0);
+        *localPublicKey = vector<uint8_t>(reinterpret_cast<const uint8_t*>(p),
+                                          reinterpret_cast<const uint8_t*>(p + localPublicKeySize));
+        OPENSSL_free(p);
     }
 
     void GenerateKeyMintEcKey(EcCurve curve, EVP_PKEY_Ptr* kmPubKey) {
@@ -7566,6 +8119,9 @@
     //
     for (auto curve : ValidCurves()) {
         for (auto localCurve : ValidCurves()) {
+            SCOPED_TRACE(testing::Message()
+                         << "local-curve-" << localCurve << "-keymint-curve-" << curve);
+
             // Generate EC key locally (with access to private key material)
             EVP_PKEY_Ptr localPrivKey;
             vector<uint8_t> localPublicKey;
@@ -7579,7 +8135,7 @@
             if (curve != localCurve) {
                 // If the keys are using different curves KeyMint should fail with
                 // ErrorCode:INVALID_ARGUMENT. Check that.
-                EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::AGREE_KEY, AuthorizationSetBuilder()));
+                ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::AGREE_KEY, AuthorizationSetBuilder()));
                 string ZabFromKeyMintStr;
                 EXPECT_EQ(ErrorCode::INVALID_ARGUMENT,
                           Finish(string(localPublicKey.begin(), localPublicKey.end()),
@@ -7719,7 +8275,7 @@
         vector<uint8_t> encodedPublicKey;
         GenerateLocalEcKey(localCurve, &privKey, &encodedPublicKey);
 
-        EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::AGREE_KEY, AuthorizationSetBuilder()));
+        ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::AGREE_KEY, AuthorizationSetBuilder()));
         string ZabFromKeyMintStr;
         EXPECT_EQ(ErrorCode::INVALID_ARGUMENT,
                   Finish(string(encodedPublicKey.begin(), encodedPublicKey.end()),
@@ -7915,6 +8471,18 @@
 
 INSTANTIATE_KEYMINT_AIDL_TEST(UnlockedDeviceRequiredTest);
 
+using VsrRequirementTest = KeyMintAidlTestBase;
+
+TEST_P(VsrRequirementTest, Vsr13Test) {
+    int vsr_api_level = get_vsr_api_level();
+    if (vsr_api_level < 33) {
+        GTEST_SKIP() << "Applies only to VSR API level 33, this device is: " << vsr_api_level;
+    }
+    EXPECT_GE(AidlVersion(), 2) << "VSR 13+ requires KeyMint version 2";
+}
+
+INSTANTIATE_KEYMINT_AIDL_TEST(VsrRequirementTest);
+
 }  // namespace aidl::android::hardware::security::keymint::test
 
 int main(int argc, char** argv) {
diff --git a/security/keymint/aidl/vts/functional/SecureElementProvisioningTest.cpp b/security/keymint/aidl/vts/functional/SecureElementProvisioningTest.cpp
index 6f13867..c9a156d 100644
--- a/security/keymint/aidl/vts/functional/SecureElementProvisioningTest.cpp
+++ b/security/keymint/aidl/vts/functional/SecureElementProvisioningTest.cpp
@@ -36,6 +36,8 @@
 using std::shared_ptr;
 using std::vector;
 
+constexpr int kRoTVersion1 = 40001;
+
 class SecureElementProvisioningTest : public testing::Test {
   protected:
     static void SetUpTestSuite() {
@@ -57,6 +59,92 @@
         }
     }
 
+    void validateMacedRootOfTrust(const vector<uint8_t>& rootOfTrust) {
+        SCOPED_TRACE(testing::Message() << "RoT: " << bin2hex(rootOfTrust));
+
+        const auto [macItem, macEndPos, macErrMsg] = cppbor::parse(rootOfTrust);
+        ASSERT_TRUE(macItem) << "Root of trust parsing failed: " << macErrMsg;
+        ASSERT_EQ(macItem->semanticTagCount(), 1);
+        ASSERT_EQ(macItem->semanticTag(0), cppcose::kCoseMac0SemanticTag);
+        ASSERT_TRUE(macItem->asArray());
+        ASSERT_EQ(macItem->asArray()->size(), cppcose::kCoseMac0EntryCount);
+
+        const auto& protectedItem = macItem->asArray()->get(cppcose::kCoseMac0ProtectedParams);
+        ASSERT_TRUE(protectedItem);
+        ASSERT_TRUE(protectedItem->asBstr());
+        const auto [protMap, protEndPos, protErrMsg] = cppbor::parse(protectedItem->asBstr());
+        ASSERT_TRUE(protMap);
+        ASSERT_TRUE(protMap->asMap());
+        ASSERT_EQ(protMap->asMap()->size(), 1);
+
+        const auto& algorithm = protMap->asMap()->get(cppcose::ALGORITHM);
+        ASSERT_TRUE(algorithm);
+        ASSERT_TRUE(algorithm->asInt());
+        ASSERT_EQ(algorithm->asInt()->value(), cppcose::HMAC_256);
+
+        const auto& unprotItem = macItem->asArray()->get(cppcose::kCoseMac0UnprotectedParams);
+        ASSERT_TRUE(unprotItem);
+        ASSERT_TRUE(unprotItem->asMap());
+        ASSERT_EQ(unprotItem->asMap()->size(), 0);
+
+        const auto& payload = macItem->asArray()->get(cppcose::kCoseMac0Payload);
+        ASSERT_TRUE(payload);
+        ASSERT_TRUE(payload->asBstr());
+        validateRootOfTrust(payload->asBstr()->value());
+
+        const auto& tag = macItem->asArray()->get(cppcose::kCoseMac0Tag);
+        ASSERT_TRUE(tag);
+        ASSERT_TRUE(tag->asBstr());
+        ASSERT_EQ(tag->asBstr()->value().size(), 32);
+        // Cannot validate tag correctness.  Only the secure side has the necessary key.
+    }
+
+    void validateRootOfTrust(const vector<uint8_t>& payload) {
+        SCOPED_TRACE(testing::Message() << "RoT payload: " << bin2hex(payload));
+
+        const auto [rot, rotPos, rotErrMsg] = cppbor::parse(payload);
+        ASSERT_TRUE(rot);
+        ASSERT_EQ(rot->semanticTagCount(), 1);
+        ASSERT_EQ(rot->semanticTag(), kRoTVersion1);
+        ASSERT_TRUE(rot->asArray());
+        ASSERT_EQ(rot->asArray()->size(), 5);
+
+        size_t pos = 0;
+
+        const auto& vbKey = rot->asArray()->get(pos++);
+        ASSERT_TRUE(vbKey);
+        ASSERT_TRUE(vbKey->asBstr());
+
+        const auto& deviceLocked = rot->asArray()->get(pos++);
+        ASSERT_TRUE(deviceLocked);
+        ASSERT_TRUE(deviceLocked->asBool());
+
+        const auto& verifiedBootState = rot->asArray()->get(pos++);
+        ASSERT_TRUE(verifiedBootState);
+        ASSERT_TRUE(verifiedBootState->asInt());
+
+        const auto& verifiedBootHash = rot->asArray()->get(pos++);
+        ASSERT_TRUE(verifiedBootHash);
+        ASSERT_TRUE(verifiedBootHash->asBstr());
+
+        const auto& bootPatchLevel = rot->asArray()->get(pos++);
+        ASSERT_TRUE(bootPatchLevel);
+        ASSERT_TRUE(bootPatchLevel->asInt());
+
+        verify_root_of_trust(vbKey->asBstr()->value(), deviceLocked->asBool()->value(),
+                             static_cast<VerifiedBoot>(verifiedBootState->asInt()->value()),
+                             verifiedBootHash->asBstr()->value());
+    }
+
+    int32_t AidlVersion(shared_ptr<IKeyMintDevice> keymint) {
+        int32_t version = 0;
+        auto status = keymint->getInterfaceVersion(&version);
+        if (!status.isOk()) {
+            ADD_FAILURE() << "Failed to determine interface version";
+        }
+        return version;
+    }
+
     static map<SecurityLevel, shared_ptr<IKeyMintDevice>> keymints_;
 };
 
@@ -73,50 +161,44 @@
 }
 
 TEST_F(SecureElementProvisioningTest, TeeOnly) {
-    if (keymints_.empty()) {
-        GTEST_SKIP() << "Test not applicable to device with no KeyMint devices";
+    if (keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT) == 0) {
+        GTEST_SKIP() << "Test not applicable to device with no TEE KeyMint device";
     }
-    ASSERT_EQ(keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT), 1);
     auto tee = keymints_.find(SecurityLevel::TRUSTED_ENVIRONMENT)->second;
-    ASSERT_NE(tee, nullptr);
+    // Execute the test only for KeyMint version >= 2.
+    if (AidlVersion(tee) < 2) {
+        GTEST_SKIP() << "Test not applicable to TEE KeyMint device before v2";
+    }
 
     array<uint8_t, 16> challenge1 = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
     array<uint8_t, 16> challenge2 = {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
 
     vector<uint8_t> rootOfTrust1;
     Status result = tee->getRootOfTrust(challenge1, &rootOfTrust1);
-
-    // TODO: Remove the next line to require TEEs to succeed.
-    if (!result.isOk()) return;
-
-    ASSERT_TRUE(result.isOk());
-
-    // TODO:  Parse and validate rootOfTrust1 here
+    ASSERT_TRUE(result.isOk()) << "getRootOfTrust returned " << result.getServiceSpecificError();
+    validateMacedRootOfTrust(rootOfTrust1);
 
     vector<uint8_t> rootOfTrust2;
     result = tee->getRootOfTrust(challenge2, &rootOfTrust2);
     ASSERT_TRUE(result.isOk());
-
-    // TODO:  Parse and validate rootOfTrust2 here
-
+    validateMacedRootOfTrust(rootOfTrust2);
     ASSERT_NE(rootOfTrust1, rootOfTrust2);
 
     vector<uint8_t> rootOfTrust3;
     result = tee->getRootOfTrust(challenge1, &rootOfTrust3);
     ASSERT_TRUE(result.isOk());
-
     ASSERT_EQ(rootOfTrust1, rootOfTrust3);
-
-    // TODO:  Parse and validate rootOfTrust3 here
 }
 
 TEST_F(SecureElementProvisioningTest, TeeDoesNotImplementStrongBoxMethods) {
-    if (keymints_.empty()) {
-        GTEST_SKIP() << "Test not applicable to device with no KeyMint devices";
+    if (keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT) == 0) {
+        GTEST_SKIP() << "Test not applicable to device with no TEE KeyMint device";
     }
-    ASSERT_EQ(keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT), 1);
     auto tee = keymints_.find(SecurityLevel::TRUSTED_ENVIRONMENT)->second;
-    ASSERT_NE(tee, nullptr);
+    // Execute the test only for KeyMint version >= 2.
+    if (AidlVersion(tee) < 2) {
+        GTEST_SKIP() << "Test not applicable to TEE KeyMint device before v2";
+    }
 
     array<uint8_t, 16> challenge;
     Status result = tee->getRootOfTrustChallenge(&challenge);
@@ -135,9 +217,11 @@
         // Need a StrongBox to provision.
         GTEST_SKIP() << "Test not applicable to device with no StrongBox KeyMint device";
     }
-
+    // Execute the test only for KeyMint version >= 2.
     auto sb = keymints_.find(SecurityLevel::STRONGBOX)->second;
-    ASSERT_NE(sb, nullptr);
+    if (AidlVersion(sb) < 2) {
+        GTEST_SKIP() << "Test not applicable to StrongBox KeyMint device before v2";
+    }
 
     vector<uint8_t> rootOfTrust;
     Status result = sb->getRootOfTrust({}, &rootOfTrust);
@@ -151,14 +235,19 @@
         // Need a StrongBox to provision.
         GTEST_SKIP() << "Test not applicable to device with no StrongBox KeyMint device";
     }
-
-    ASSERT_EQ(keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT), 1);
-    auto tee = keymints_.find(SecurityLevel::TRUSTED_ENVIRONMENT)->second;
-    ASSERT_NE(tee, nullptr);
-
-    ASSERT_EQ(keymints_.count(SecurityLevel::STRONGBOX), 1);
+    // Execute the test only for KeyMint version >= 2.
     auto sb = keymints_.find(SecurityLevel::STRONGBOX)->second;
-    ASSERT_NE(sb, nullptr);
+    if (AidlVersion(sb) < 2) {
+        GTEST_SKIP() << "Test not applicable to StrongBox KeyMint device before v2";
+    }
+
+    if (keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT) == 0) {
+        GTEST_SKIP() << "Test not applicable to device with no TEE KeyMint device";
+    }
+    auto tee = keymints_.find(SecurityLevel::TRUSTED_ENVIRONMENT)->second;
+    if (AidlVersion(tee) < 2) {
+        GTEST_SKIP() << "Test not applicable to TEE KeyMint device before v2";
+    }
 
     array<uint8_t, 16> challenge;
     Status result = sb->getRootOfTrustChallenge(&challenge);
@@ -185,10 +274,11 @@
         // Need a StrongBox to provision.
         GTEST_SKIP() << "Test not applicable to device with no StrongBox KeyMint device";
     }
-
-    ASSERT_EQ(keymints_.count(SecurityLevel::STRONGBOX), 1);
+    // Execute the test only for KeyMint version >= 2.
     auto sb = keymints_.find(SecurityLevel::STRONGBOX)->second;
-    ASSERT_NE(sb, nullptr);
+    if (AidlVersion(sb) < 2) {
+        GTEST_SKIP() << "Test not applicable to StrongBox KeyMint device before v2";
+    }
 
     array<uint8_t, 16> challenge1;
     Status result = sb->getRootOfTrustChallenge(&challenge1);
@@ -208,14 +298,20 @@
         // Need a StrongBox to provision.
         GTEST_SKIP() << "Test not applicable to device with no StrongBox KeyMint device";
     }
-
-    ASSERT_EQ(keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT), 1);
-    auto tee = keymints_.find(SecurityLevel::TRUSTED_ENVIRONMENT)->second;
-    ASSERT_NE(tee, nullptr);
-
-    ASSERT_EQ(keymints_.count(SecurityLevel::STRONGBOX), 1);
+    // Execute the test only for KeyMint version >= 2.
     auto sb = keymints_.find(SecurityLevel::STRONGBOX)->second;
-    ASSERT_NE(sb, nullptr);
+    if (AidlVersion(sb) < 2) {
+        GTEST_SKIP() << "Test not applicable to StrongBox KeyMint device before v2";
+    }
+
+    if (keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT) == 0) {
+        GTEST_SKIP() << "Test not applicable to device with no TEE KeyMint device";
+    }
+    // Execute the test only for KeyMint version >= 2.
+    auto tee = keymints_.find(SecurityLevel::TRUSTED_ENVIRONMENT)->second;
+    if (AidlVersion(tee) < 2) {
+        GTEST_SKIP() << "Test not applicable to TEE KeyMint device before v2";
+    }
 
     array<uint8_t, 16> challenge;
     Status result = sb->getRootOfTrustChallenge(&challenge);
@@ -225,7 +321,7 @@
     result = tee->getRootOfTrust(challenge, &rootOfTrust);
     ASSERT_TRUE(result.isOk());
 
-    // TODO: Verify COSE_Mac0 structure and content here.
+    validateMacedRootOfTrust(rootOfTrust);
 
     result = sb->sendRootOfTrust(rootOfTrust);
     ASSERT_TRUE(result.isOk());
@@ -240,14 +336,20 @@
         // Need a StrongBox to provision.
         GTEST_SKIP() << "Test not applicable to device with no StrongBox KeyMint device";
     }
-
-    ASSERT_EQ(keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT), 1);
-    auto tee = keymints_.find(SecurityLevel::TRUSTED_ENVIRONMENT)->second;
-    ASSERT_NE(tee, nullptr);
-
-    ASSERT_EQ(keymints_.count(SecurityLevel::STRONGBOX), 1);
+    // Execute the test only for KeyMint version >= 2.
     auto sb = keymints_.find(SecurityLevel::STRONGBOX)->second;
-    ASSERT_NE(sb, nullptr);
+    if (AidlVersion(sb) < 2) {
+        GTEST_SKIP() << "Test not applicable to StrongBox KeyMint device before v2";
+    }
+
+    if (keymints_.count(SecurityLevel::TRUSTED_ENVIRONMENT) == 0) {
+        GTEST_SKIP() << "Test not applicable to device with no TEE KeyMint device";
+    }
+    // Execute the test only for KeyMint version >= 2.
+    auto tee = keymints_.find(SecurityLevel::TRUSTED_ENVIRONMENT)->second;
+    if (AidlVersion(tee) < 2) {
+        GTEST_SKIP() << "Test not applicable to TEE KeyMint device before v2";
+    }
 
     array<uint8_t, 16> challenge;
     Status result = sb->getRootOfTrustChallenge(&challenge);
@@ -263,6 +365,8 @@
     result = tee->getRootOfTrust(challenge, &rootOfTrust);
     ASSERT_TRUE(result.isOk());
 
+    validateMacedRootOfTrust(rootOfTrust);
+
     vector<uint8_t> corruptedRootOfTrust = rootOfTrust;
     corruptedRootOfTrust[corruptedRootOfTrust.size() / 2]++;
     result = sb->sendRootOfTrust(corruptedRootOfTrust);
diff --git a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp b/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
index 3cc11f6..7184613 100644
--- a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
+++ b/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
@@ -358,8 +358,7 @@
 
 class CertificateRequestTest : public VtsRemotelyProvisionedComponentTests {
   protected:
-    CertificateRequestTest() : eekId_(string_to_bytevec("eekid")), challenge_(randomBytes(32)) {
-    }
+    CertificateRequestTest() : eekId_(string_to_bytevec("eekid")), challenge_(randomBytes(64)) {}
 
     void generateTestEekChain(size_t eekLength) {
         auto chain = generateEekChain(rpcHardwareInfo.supportedEekCurve, eekLength, eekId_);
diff --git a/security/keymint/aidl/vts/performance/KeyMintBenchmark.cpp b/security/keymint/aidl/vts/performance/KeyMintBenchmark.cpp
index 54b6fdc..5bbae4c 100644
--- a/security/keymint/aidl/vts/performance/KeyMintBenchmark.cpp
+++ b/security/keymint/aidl/vts/performance/KeyMintBenchmark.cpp
@@ -142,6 +142,25 @@
         return Digest::NONE;
     }
 
+    optional<EcCurve> getCurveFromLength(int keySize) {
+        switch (keySize) {
+            case 224:
+                return EcCurve::P_224;
+                break;
+            case 256:
+                return EcCurve::P_256;
+                break;
+            case 384:
+                return EcCurve::P_384;
+                break;
+            case 521:
+                return EcCurve::P_521;
+                break;
+            default:
+                return {};
+        }
+    }
+
     bool GenerateKey(string transform, int keySize, bool sign = false) {
         if (transform == key_transform_) {
             return true;
@@ -184,6 +203,12 @@
         }
         if (algorithm == Algorithm::EC) {
             authSet.SetDefaultValidity();
+            std::optional<EcCurve> curve = getCurveFromLength(keySize);
+            if (!curve) {
+                std::cerr << "Error: invalid EC-Curve from size " << keySize << std::endl;
+                return false;
+            }
+            authSet.Authorization(TAG_EC_CURVE, curve.value());
         }
         error_ = GenerateKey(authSet);
         return error_ == ErrorCode::OK;
diff --git a/security/secureclock/aidl/Android.bp b/security/secureclock/aidl/Android.bp
index 00a6ba3..853ad89 100644
--- a/security/secureclock/aidl/Android.bp
+++ b/security/secureclock/aidl/Android.bp
@@ -18,11 +18,6 @@
         java: {
             platform_apis: true,
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
         rust: {
             enabled: true,
             apex_available: [
diff --git a/security/sharedsecret/aidl/Android.bp b/security/sharedsecret/aidl/Android.bp
index f1fce74..fe77c10 100644
--- a/security/sharedsecret/aidl/Android.bp
+++ b/security/sharedsecret/aidl/Android.bp
@@ -18,11 +18,6 @@
         java: {
             sdk_version: "module_current",
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
         rust: {
             enabled: true,
         },
diff --git a/security/sharedsecret/aidl/android/hardware/security/sharedsecret/SharedSecretParameters.aidl b/security/sharedsecret/aidl/android/hardware/security/sharedsecret/SharedSecretParameters.aidl
index 8144699..b72f0de 100644
--- a/security/sharedsecret/aidl/android/hardware/security/sharedsecret/SharedSecretParameters.aidl
+++ b/security/sharedsecret/aidl/android/hardware/security/sharedsecret/SharedSecretParameters.aidl
@@ -33,9 +33,9 @@
     byte[] seed;
 
     /**
-     * A 32-byte value which is guaranteed to be different each time
-     * getSharedSecretParameters() is called.  Probabilistic uniqueness (i.e. random) is acceptable,
-     * though a stronger uniqueness guarantee (e.g. counter) is recommended where possible.
+     * A 32-byte value which is guaranteed to be different each time getSharedSecretParameters() is
+     * called after a restart.  Probabilistic uniqueness (i.e. random) is acceptable, though a
+     * stronger uniqueness guarantee (e.g. counter) is recommended where possible.
      */
     byte[] nonce;
 }
diff --git a/sensors/2.0/multihal/android.hardware.sensors@2.0-service-multihal.rc b/sensors/2.0/multihal/android.hardware.sensors@2.0-service-multihal.rc
index 8867a1a..c874604 100644
--- a/sensors/2.0/multihal/android.hardware.sensors@2.0-service-multihal.rc
+++ b/sensors/2.0/multihal/android.hardware.sensors@2.0-service-multihal.rc
@@ -1,7 +1,7 @@
 service vendor.sensors-hal-2-0-multihal /vendor/bin/hw/android.hardware.sensors@2.0-service.multihal
     class hal
     user system
-    group system wakelock context_hub
+    group system wakelock context_hub input
     task_profiles ServiceCapacityLow
     capabilities BLOCK_SUSPEND
     rlimit rtprio 10 10
diff --git a/sensors/2.1/multihal/android.hardware.sensors@2.1-service-multihal.rc b/sensors/2.1/multihal/android.hardware.sensors@2.1-service-multihal.rc
index f47e060..deea16e 100644
--- a/sensors/2.1/multihal/android.hardware.sensors@2.1-service-multihal.rc
+++ b/sensors/2.1/multihal/android.hardware.sensors@2.1-service-multihal.rc
@@ -1,7 +1,7 @@
 service vendor.sensors-hal-2-1-multihal /vendor/bin/hw/android.hardware.sensors@2.1-service.multihal
     class hal
     user system
-    group system wakelock context_hub
+    group system wakelock context_hub input
     task_profiles ServiceCapacityLow
     capabilities BLOCK_SUSPEND
     rlimit rtprio 10 10
diff --git a/sensors/common/default/2.X/multihal/HalProxyCallback.cpp b/sensors/common/default/2.X/multihal/HalProxyCallback.cpp
index 3c1b17c..addefe8 100644
--- a/sensors/common/default/2.X/multihal/HalProxyCallback.cpp
+++ b/sensors/common/default/2.X/multihal/HalProxyCallback.cpp
@@ -68,6 +68,10 @@
     std::vector<V2_1::Event> eventsOut;
     for (V2_1::Event event : events) {
         event.sensorHandle = setSubHalIndex(event.sensorHandle, mSubHalIndex);
+        if (event.sensorType == V2_1::SensorType::DYNAMIC_SENSOR_META) {
+            event.u.dynamic.sensorHandle =
+                    setSubHalIndex(event.u.dynamic.sensorHandle, mSubHalIndex);
+        }
         eventsOut.push_back(event);
         const V2_1::SensorInfo& sensor = mCallback->getSensorInfo(event.sensorHandle);
         if ((sensor.flags & V1_0::SensorFlagBits::WAKE_UP) != 0) {
diff --git a/tests/extension/vibrator/aidl/default/CustomVibrator.cpp b/tests/extension/vibrator/aidl/default/CustomVibrator.cpp
index 2f3dfcb..7a7c58b 100644
--- a/tests/extension/vibrator/aidl/default/CustomVibrator.cpp
+++ b/tests/extension/vibrator/aidl/default/CustomVibrator.cpp
@@ -57,4 +57,12 @@
     return ndk::ScopedAStatus::ok();
 }
 
+ndk::SpAIBinder CustomVibrator::createBinder() {
+    auto binder = BnCustomVibrator::createBinder();
+    // e.g. AIBinder_setInheritRt(binder.get(), true);
+    // e.g. AIBinder_setMinSchedulerPolicy(binder.get(), SCHED_NORMAL, 20);
+    // e.g. AIBinder_setRequestingSid(binder.get(), true);
+    return binder;
+}
+
 }  // namespace aidl::android::hardware::tests::extension::vibrator
diff --git a/tests/extension/vibrator/aidl/default/CustomVibrator.h b/tests/extension/vibrator/aidl/default/CustomVibrator.h
index 6dc5743..084a557 100644
--- a/tests/extension/vibrator/aidl/default/CustomVibrator.h
+++ b/tests/extension/vibrator/aidl/default/CustomVibrator.h
@@ -29,6 +29,12 @@
     ndk::ScopedAStatus perform(VendorEffect effect,
                                const std::shared_ptr<IVibratorCallback>& callback,
                                int32_t* _aidl_return) override;
+
+  private:
+    // override for AIBinder_setInheritRt, AIBinder_setMinSchedulerPolicy, or
+    // AIBinder_setRequestingSid calling this in the constructor or elsewhere, the binder would
+    // immediately be destroyed.
+    ndk::SpAIBinder createBinder() override;
 };
 
 }  // namespace aidl::android::hardware::tests::extension::vibrator
diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
index b39abe3..53280d7 100644
--- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
+++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
@@ -144,9 +144,9 @@
     ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(filterId));
     ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId));
     ASSERT_TRUE(mFilterTests.getFilterMQDescriptor(filterId, filterConf.getMqDesc));
-    mDvrTests.startPlaybackInputThread(dvrConf.playbackInputFile, dvrConf.settings.playback());
     ASSERT_TRUE(mDvrTests.startDvrPlayback());
     ASSERT_TRUE(mFilterTests.startFilter(filterId));
+    mDvrTests.startPlaybackInputThread(dvrConf.playbackInputFile, dvrConf.settings.playback());
     ASSERT_TRUE(filterDataOutputTest());
     mDvrTests.stopPlaybackThread();
     ASSERT_TRUE(mFilterTests.stopFilter(filterId));
diff --git a/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service-lazy.rc b/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service-lazy.rc
index abff430..3fe6b52 100644
--- a/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service-lazy.rc
+++ b/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service-lazy.rc
@@ -7,4 +7,4 @@
     user media
     group mediadrm drmrpc
     ioprio rt 4
-    writepid /dev/cpuset/foreground/tasks
\ No newline at end of file
+    task_profiles ProcessCapacityHigh
diff --git a/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service.rc b/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service.rc
index 3718a93..bc62c7d 100644
--- a/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service.rc
+++ b/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service.rc
@@ -3,4 +3,4 @@
     user media
     group mediadrm drmrpc
     ioprio rt 4
-    writepid /dev/cpuset/foreground/tasks
\ No newline at end of file
+    task_profiles ProcessCapacityHigh
diff --git a/usb/1.0/default/Usb.cpp b/usb/1.0/default/Usb.cpp
index 6eb8842..573e0e3 100644
--- a/usb/1.0/default/Usb.cpp
+++ b/usb/1.0/default/Usb.cpp
@@ -234,7 +234,7 @@
     else
         return Status::UNRECOGNIZED_ROLE;
 
-        return Status::SUCCESS;
+    return Status::SUCCESS;
 }
 
 Status getPortStatusHelper (hidl_vec<PortStatus>& currentPortStatus) {
diff --git a/usb/aidl/Android.bp b/usb/aidl/Android.bp
new file mode 100644
index 0000000..f01b44e
--- /dev/null
+++ b/usb/aidl/Android.bp
@@ -0,0 +1,37 @@
+// 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 {
+    // 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"],
+}
+
+aidl_interface {
+    name: "android.hardware.usb",
+    vendor_available: true,
+    srcs: ["android/hardware/usb/*.aidl"],
+    stability: "vintf",
+    backend: {
+        cpp: {
+            enabled: false,
+        },
+        java: {
+            sdk_version: "module_current",
+        },
+    },
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/ContaminantDetectionStatus.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/ContaminantDetectionStatus.aidl
new file mode 100644
index 0000000..24c6966
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/ContaminantDetectionStatus.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.usb;
+@VintfStability
+enum ContaminantDetectionStatus {
+  NOT_SUPPORTED = 0,
+  DISABLED = 1,
+  NOT_DETECTED = 2,
+  DETECTED = 3,
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/ContaminantProtectionMode.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/ContaminantProtectionMode.aidl
new file mode 100644
index 0000000..9979869
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/ContaminantProtectionMode.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.usb;
+@VintfStability
+enum ContaminantProtectionMode {
+  NONE = 0,
+  FORCE_SINK = 1,
+  FORCE_SOURCE = 2,
+  FORCE_DISABLE = 3,
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/ContaminantProtectionStatus.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/ContaminantProtectionStatus.aidl
new file mode 100644
index 0000000..9642261
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/ContaminantProtectionStatus.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.usb;
+@VintfStability
+enum ContaminantProtectionStatus {
+  NONE = 0,
+  FORCE_SINK = 1,
+  FORCE_SOURCE = 2,
+  FORCE_DISABLE = 3,
+  DISABLED = 4,
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/IUsb.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/IUsb.aidl
new file mode 100644
index 0000000..7513461
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/IUsb.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.usb;
+@VintfStability
+interface IUsb {
+  oneway void enableContaminantPresenceDetection(in String portName, in boolean enable, long transactionId);
+  oneway void enableUsbData(in String portName, boolean enable, long transactionId);
+  oneway void queryPortStatus(long transactionId);
+  oneway void setCallback(in android.hardware.usb.IUsbCallback callback);
+  oneway void switchRole(in String portName, in android.hardware.usb.PortRole role, long transactionId);
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/IUsbCallback.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/IUsbCallback.aidl
new file mode 100644
index 0000000..57be590
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/IUsbCallback.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.usb;
+@VintfStability
+interface IUsbCallback {
+  oneway void notifyPortStatusChange(in android.hardware.usb.PortStatus[] currentPortStatus, in android.hardware.usb.Status retval);
+  oneway void notifyRoleSwitchStatus(in String portName, in android.hardware.usb.PortRole newRole, in android.hardware.usb.Status retval, long transactionId);
+  oneway void notifyEnableUsbDataStatus(in String portName, boolean enable, in android.hardware.usb.Status retval, long transactionId);
+  oneway void notifyContaminantEnabledStatus(in String portName, boolean enable, in android.hardware.usb.Status retval, long transactionId);
+  oneway void notifyQueryPortStatus(in String portName, in android.hardware.usb.Status retval, long transactionId);
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortDataRole.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortDataRole.aidl
new file mode 100644
index 0000000..105b316
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortDataRole.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.usb;
+@VintfStability
+enum PortDataRole {
+  NONE = 0,
+  HOST = 1,
+  DEVICE = 2,
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortMode.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortMode.aidl
new file mode 100644
index 0000000..34e4334
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortMode.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.usb;
+@VintfStability
+enum PortMode {
+  NONE = 0,
+  UFP = 1,
+  DFP = 2,
+  DRP = 3,
+  AUDIO_ACCESSORY = 4,
+  DEBUG_ACCESSORY = 5,
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortPowerRole.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortPowerRole.aidl
new file mode 100644
index 0000000..0e6f3fb
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortPowerRole.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.usb;
+@VintfStability
+enum PortPowerRole {
+  NONE = 0,
+  SOURCE = 1,
+  SINK = 2,
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortRole.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortRole.aidl
new file mode 100644
index 0000000..c66aecc
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortRole.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.usb;
+@VintfStability
+union PortRole {
+  android.hardware.usb.PortPowerRole powerRole = android.hardware.usb.PortPowerRole.NONE;
+  android.hardware.usb.PortDataRole dataRole;
+  android.hardware.usb.PortMode mode;
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortStatus.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortStatus.aidl
new file mode 100644
index 0000000..78dcfac
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/PortStatus.aidl
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.usb;
+@VintfStability
+parcelable PortStatus {
+  String portName;
+  android.hardware.usb.PortDataRole currentDataRole = android.hardware.usb.PortDataRole.NONE;
+  android.hardware.usb.PortPowerRole currentPowerRole = android.hardware.usb.PortPowerRole.NONE;
+  android.hardware.usb.PortMode currentMode = android.hardware.usb.PortMode.NONE;
+  boolean canChangeMode;
+  boolean canChangeDataRole;
+  boolean canChangePowerRole;
+  android.hardware.usb.PortMode[] supportedModes;
+  android.hardware.usb.ContaminantProtectionMode[] supportedContaminantProtectionModes;
+  boolean supportsEnableContaminantPresenceProtection;
+  android.hardware.usb.ContaminantProtectionStatus contaminantProtectionStatus = android.hardware.usb.ContaminantProtectionStatus.NONE;
+  boolean supportsEnableContaminantPresenceDetection;
+  android.hardware.usb.ContaminantDetectionStatus contaminantDetectionStatus = android.hardware.usb.ContaminantDetectionStatus.NOT_SUPPORTED;
+  boolean usbDataEnabled;
+}
diff --git a/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/Status.aidl b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/Status.aidl
new file mode 100644
index 0000000..f28fc2a
--- /dev/null
+++ b/usb/aidl/aidl_api/android.hardware.usb/current/android/hardware/usb/Status.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.usb;
+@Backing(type="int") @VintfStability
+enum Status {
+  SUCCESS = 0,
+  ERROR = 1,
+  INVALID_ARGUMENT = 2,
+  UNRECOGNIZED_ROLE = 3,
+  NOT_SUPPORTED = 4,
+}
diff --git a/usb/aidl/android/hardware/usb/ContaminantDetectionStatus.aidl b/usb/aidl/android/hardware/usb/ContaminantDetectionStatus.aidl
new file mode 100644
index 0000000..d9bc576
--- /dev/null
+++ b/usb/aidl/android/hardware/usb/ContaminantDetectionStatus.aidl
@@ -0,0 +1,37 @@
+/*
+ * 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.usb;
+
+@VintfStability
+enum ContaminantDetectionStatus {
+    /**
+     * Contaminant presence detection is not supported.
+     */
+    NOT_SUPPORTED = 0,
+    /**
+     * Contaminant presence detection is supported but disabled.
+     */
+    DISABLED = 1,
+    /**
+     * Contaminant presence detection is enabled and contaminant not detected.
+     */
+    NOT_DETECTED = 2,
+    /**
+     * Contaminant presence detection is enabled and contaminant detected.
+     */
+    DETECTED = 3,
+}
diff --git a/usb/aidl/android/hardware/usb/ContaminantProtectionMode.aidl b/usb/aidl/android/hardware/usb/ContaminantProtectionMode.aidl
new file mode 100644
index 0000000..47c073d
--- /dev/null
+++ b/usb/aidl/android/hardware/usb/ContaminantProtectionMode.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.usb;
+
+@VintfStability
+enum ContaminantProtectionMode {
+    /**
+     * No action performed upon detection of contaminant presence.
+     */
+    NONE = 0,
+    /**
+     * Upon detection of contaminant presence, Port is forced to sink only
+     * mode where a port shall only detect chargers until contaminant presence
+     * is no longer detected.
+     */
+    FORCE_SINK = 1,
+    /**
+     * Upon detection of contaminant presence, Port is forced to source only
+     * mode where a port shall only detect usb accessories such as headsets
+     * until contaminant presence is no longer detected.
+     */
+    FORCE_SOURCE = 2,
+    /**
+     * Upon detection of contaminant presence, port is disabled until contaminant
+     * presence is no longer detected. In the disabled state port will
+     * not respond to connection of chargers or usb accessories.
+     */
+    FORCE_DISABLE = 3,
+}
diff --git a/usb/aidl/android/hardware/usb/ContaminantProtectionStatus.aidl b/usb/aidl/android/hardware/usb/ContaminantProtectionStatus.aidl
new file mode 100644
index 0000000..c4fa979
--- /dev/null
+++ b/usb/aidl/android/hardware/usb/ContaminantProtectionStatus.aidl
@@ -0,0 +1,51 @@
+/*
+ * 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.usb;
+
+import android.hardware.usb.ContaminantProtectionMode;
+
+@VintfStability
+enum ContaminantProtectionStatus {
+    /**
+     * No action performed upon detection of contaminant presence.
+     */
+    NONE = 0,
+    /**
+     * Upon detection of contaminant presence, Port is forced to sink only
+     * mode where a port shall only detect chargers until contaminant presence
+     * is no longer detected.
+     */
+    FORCE_SINK = 1,
+    /**
+     * Upon detection of contaminant presence, Port is forced to source only
+     * mode where a port shall only detect usb accessories such as headsets
+     * until contaminant presence is no longer detected.
+     */
+    FORCE_SOURCE = 2,
+    /**
+     * Upon detection of contaminant presence, port is disabled until contaminant
+     * presence is no longer detected. In the disabled state port will
+     * not respond to connection of chargers or usb accessories.
+     */
+    FORCE_DISABLE = 3,
+    /**
+     * Client disabled cotaminant protection by calling
+     * enableContaminantPresencePortProtection set to false. Low level drivers should
+     * not autmomously take any corrective action when contaminant presence is detected.
+     */
+    DISABLED = 4,
+}
diff --git a/usb/aidl/android/hardware/usb/IUsb.aidl b/usb/aidl/android/hardware/usb/IUsb.aidl
new file mode 100644
index 0000000..9a8f000
--- /dev/null
+++ b/usb/aidl/android/hardware/usb/IUsb.aidl
@@ -0,0 +1,85 @@
+/*
+ * 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.usb;
+
+import android.hardware.usb.IUsbCallback;
+import android.hardware.usb.PortRole;
+
+@VintfStability
+oneway interface IUsb {
+    /**
+     * When supportsEnableContaminantPresenceDetection is true,
+     * enableContaminantPresenceDetection enables/disables contaminant
+     * presence detection algorithm. Calling enableContaminantPresenceDetection
+     * when supportsEnableContaminantPresenceDetection is false does
+     * not have any effect.
+     * Change in contantaminant presence status should be notified to the
+     * client via notifyPortStatusChange through PortStatus.
+     *
+     * @param portName name of the port.
+     * @param enable true Enable contaminant presence detection algorithm.
+     *               false Disable contaminant presence detection algorithm.
+     * @param transactionId ID to be used when invoking the callback.
+     */
+    void enableContaminantPresenceDetection(in String portName, in boolean enable, long transactionId);
+
+    /**
+     * This function is used to enable/disable USB data controller.
+     *
+     * @param portName Name of the port.
+     * @param enable   true Enable USB data signaling.
+     *                 false Disable USB data signaling.
+     * @param transactionId ID to be used when invoking the callback.
+     *
+     */
+    void enableUsbData(in String portName, boolean enable, long transactionId);
+
+    /**
+     * This functions is used to request the hal for the current status
+     * status of the Type-C ports. The result of the query would be sent
+     * through the IUsbCallback object's notifyRoleSwitchStatus
+     * to the caller. This api would would let the caller know of the number
+     * of type-c ports that are present and their connection status through the
+     * PortStatus type.
+     * @param transactionId ID to be used when invoking the callback.
+     */
+    void queryPortStatus(long transactionId);
+
+    /**
+     * This function is used to register a callback function which is
+     * called by the HAL to inform the client of port status updates and
+     * result of the requested operation. Please refer IUsbCallback for
+     * complete description of when each of the IUsbCallback's interface
+     * methods is expected to be called.
+     *
+     * @param callback IUsbCallback object used to convey status to the
+     * userspace.
+     */
+    void setCallback(in IUsbCallback callback);
+
+    /**
+     * This function is used to change the port role of a specific port.
+     * For example, when DR_SWAP or PR_SWAP is supported.
+     * The status of the role switch will be informed through IUsbCallback
+     * object's notifyPortStatusChange method.
+     *
+     * @param portName name of the port for which the role has to be changed
+     * @param role the new port role.
+     * @param transactionId ID to be used when invoking the callback.
+     */
+    void switchRole(in String portName, in PortRole role, long transactionId);
+}
diff --git a/usb/aidl/android/hardware/usb/IUsbCallback.aidl b/usb/aidl/android/hardware/usb/IUsbCallback.aidl
new file mode 100644
index 0000000..232a15b
--- /dev/null
+++ b/usb/aidl/android/hardware/usb/IUsbCallback.aidl
@@ -0,0 +1,86 @@
+/*
+ * 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.usb;
+
+import android.hardware.usb.PortRole;
+import android.hardware.usb.PortStatus;
+import android.hardware.usb.Status;
+
+/**
+ * Callback object used for all the IUsb async methods which expects a result.
+ * Caller is expected to register the callback object using setCallback method
+ * to receive updates on the PortStatus.
+ */
+@VintfStability
+oneway interface IUsbCallback {
+    /**
+     * Used to convey the current port status to the caller.
+     * Must be called either when PortState changes due to the port partner or
+     * when caller requested for the PortStatus update through queryPortStatus.
+     *
+     * @param currentPortStatus describes the status of all the USB ports in the
+     *                          device.
+     * @param retval SUCCESS when the required information was enquired form
+     *               kernel and the PortStatus object was built.
+     *               ERROR otherwise.
+     */
+    void notifyPortStatusChange(in PortStatus[] currentPortStatus, in Status retval);
+
+    /**
+     * Used to notify the result of the switchRole call to the caller.
+     *
+     * @param portName name of the port for which the roleswap is requested.
+     * @param newRole the new role requested by the caller.
+     * @param retval SUCCESS if the role switch succeeded. FAILURE otherwise.
+     * @param transactionId  transactionId sent during switchRole request.
+     */
+    void notifyRoleSwitchStatus(in String portName, in PortRole newRole, in Status retval,
+            long transactionId);
+
+    /**
+     * Used to notify the result of notifyEnableUsbDataStatus call to the caller.
+     *
+     * @param portName name of the port for which the enableUsbData is requested.
+     * @param enable true when usb data is enabled.
+     *               false when usb data is disabled.
+     * @param retval SUCCESS if current request succeeded. FAILURE otherwise.
+     * @param transactionId transactionId sent during enableUsbData request.
+     */
+    void notifyEnableUsbDataStatus(in String portName, boolean enable, in Status retval,
+            long transactionId);
+
+    /**
+     * Used to notify the result of enableContaminantPresenceDetection.
+     *
+     * @param portName name of the port for which contaminant detection is enabled/disabled.
+     * @param enable true when contaminant detection is enabled.
+     *               false when disabled.
+     * @param retval SUCCESS if the request for enabling/disabling contamiant detection succeeds.
+     *               FAILURE otherwise.
+     * @param transactionId transactionId sent during queryPortStatus request
+     */
+    void notifyContaminantEnabledStatus(in String portName, boolean enable, in Status retval,
+            long transactionId);
+
+    /**
+     * Used to notify the request to query port status.
+     *
+     * @param portName name of the port for which port status is queried.
+     * @param retval SUCCESS if the port query succeeded. FAILURE otherwise.
+     * @param transactionId transactionId sent during queryPortStatus request
+     */
+    void notifyQueryPortStatus(in String portName, in Status retval, long transactionId);
+}
diff --git a/usb/aidl/android/hardware/usb/PortDataRole.aidl b/usb/aidl/android/hardware/usb/PortDataRole.aidl
new file mode 100644
index 0000000..a69f977
--- /dev/null
+++ b/usb/aidl/android/hardware/usb/PortDataRole.aidl
@@ -0,0 +1,35 @@
+/*
+ * 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.usb;
+
+@VintfStability
+enum PortDataRole {
+    /**
+     * Indicates that the port does not have a data role.
+     * In case of DRP, the current data role of the port is only resolved
+     * when the type-c handshake happens.
+     */
+    NONE = 0,
+    /**
+     * Indicates that the port is acting as a host for data.
+     */
+    HOST = 1,
+    /**
+     * Indicated that the port is acting as a device for data.
+     */
+    DEVICE = 2,
+}
diff --git a/usb/aidl/android/hardware/usb/PortMode.aidl b/usb/aidl/android/hardware/usb/PortMode.aidl
new file mode 100644
index 0000000..399f0eb
--- /dev/null
+++ b/usb/aidl/android/hardware/usb/PortMode.aidl
@@ -0,0 +1,49 @@
+/*
+ * 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.usb;
+
+import android.hardware.usb.PortMode;
+
+@VintfStability
+enum PortMode {
+    /**
+     * Indicates that the port does not have a mode.
+     * In case of DRP, the current mode of the port is only resolved
+     * when the type-c handshake happens.
+     */
+    NONE = 0,
+    /**
+     * Indicates that port can only act as device for data and sink for power.
+     */
+    UFP = 1,
+    /**
+     * Indicates the port can only act as host for data and source for power.
+     */
+    DFP = 2,
+    /**
+     * Indicates can either act as UFP or DFP at a given point of time.
+     */
+    DRP = 3,
+    /*
+     * Indicates that the port supports Audio Accessory mode.
+     */
+    AUDIO_ACCESSORY = 4,
+    /*
+     * Indicates that the port supports Debug Accessory mode.
+     */
+    DEBUG_ACCESSORY = 5,
+}
diff --git a/usb/aidl/android/hardware/usb/PortPowerRole.aidl b/usb/aidl/android/hardware/usb/PortPowerRole.aidl
new file mode 100644
index 0000000..ae3dc47
--- /dev/null
+++ b/usb/aidl/android/hardware/usb/PortPowerRole.aidl
@@ -0,0 +1,35 @@
+/*
+ * 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.usb;
+
+@VintfStability
+enum PortPowerRole {
+    /**
+     * Indicates that the port does not have a power role.
+     * In case of DRP, the current power role of the port is only resolved
+     * when the type-c handshake happens.
+     */
+    NONE = 0,
+    /**
+     * Indicates that the port is supplying power to the other port.
+     */
+    SOURCE = 1,
+    /**
+     * Indicates that the port is sinking power from the other port.
+     */
+    SINK = 2,
+}
diff --git a/usb/aidl/android/hardware/usb/PortRole.aidl b/usb/aidl/android/hardware/usb/PortRole.aidl
new file mode 100644
index 0000000..e0429c8
--- /dev/null
+++ b/usb/aidl/android/hardware/usb/PortRole.aidl
@@ -0,0 +1,31 @@
+/*
+ * 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.usb;
+
+import android.hardware.usb.PortDataRole;
+import android.hardware.usb.PortMode;
+import android.hardware.usb.PortPowerRole;
+
+/**
+ * Used as a container to send port role information.
+ */
+@VintfStability
+union PortRole {
+    PortPowerRole powerRole = PortPowerRole.NONE;
+    PortDataRole dataRole;
+    PortMode mode;
+}
diff --git a/usb/aidl/android/hardware/usb/PortStatus.aidl b/usb/aidl/android/hardware/usb/PortStatus.aidl
new file mode 100644
index 0000000..8afe009
--- /dev/null
+++ b/usb/aidl/android/hardware/usb/PortStatus.aidl
@@ -0,0 +1,107 @@
+/*
+ * 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.usb;
+
+import android.hardware.usb.ContaminantDetectionStatus;
+import android.hardware.usb.ContaminantProtectionMode;
+import android.hardware.usb.ContaminantProtectionStatus;
+import android.hardware.usb.PortDataRole;
+import android.hardware.usb.PortMode;
+import android.hardware.usb.PortPowerRole;
+
+@VintfStability
+parcelable PortStatus {
+    /**
+     * Name of the port.
+     * Used as the port's id by the caller.
+     */
+    String portName;
+    /**
+     * Data role of the port.
+     */
+    PortDataRole currentDataRole = PortDataRole.NONE;
+    /**
+     * Power Role of thte port.
+     */
+    PortPowerRole currentPowerRole = PortPowerRole.NONE;
+    /**
+     * Mode in which the port is connected.
+     * Can be UFP or DFP or AUDIO_ACCESSORY or
+     * DEBUG_ACCESSORY.
+     */
+    PortMode currentMode = PortMode.NONE;
+    /**
+     * True indicates that the port's mode can
+     * be changed. False otherwise.
+     */
+    boolean canChangeMode;
+    /**
+     * True indicates that the port's data role
+     * can be changed. False otherwise.
+     * For example, true if Type-C PD PD_SWAP
+     * is supported.
+     */
+    boolean canChangeDataRole;
+    /**
+     * True indicates that the port's power role
+     * can be changed. False otherwise.
+     * For example, true if Type-C PD PR_SWAP
+     * is supported.
+     */
+    boolean canChangePowerRole;
+    /**
+     * Identifies the type of the local port.
+     *
+     * UFP - Indicates that port can only act as device for
+     *       data and sink for power.
+     * DFP - Indicates the port can only act as host for data
+     *       and source for power.
+     * DRP - Indicates can either act as UFP or DFP at a
+     *       given point of time.
+     * AUDIO_ACCESSORY -  Indicates that the port supports
+     *                    Audio Accessory mode.
+     * DEBUG_ACCESSORY - Indicates that the port supports
+     *                   Debug Accessory mode.
+     */
+    PortMode[] supportedModes;
+    /**
+     * Contaminant presence protection modes supported by the port.
+     */
+    ContaminantProtectionMode[] supportedContaminantProtectionModes;
+    /**
+     * Client can enable/disable contaminant presence protection through
+     * enableContaminantPresenceProtection when true.
+     */
+    boolean supportsEnableContaminantPresenceProtection;
+    /**
+     * Contaminant presence protection modes currently active for the port.
+     */
+    ContaminantProtectionStatus contaminantProtectionStatus = ContaminantProtectionStatus.NONE;
+    /**
+     * Client can enable/disable contaminant presence detection through
+     * enableContaminantPresenceDetection when true.
+     */
+    boolean supportsEnableContaminantPresenceDetection;
+    /**
+     * Current status of contaminant detection algorithm.
+     */
+    ContaminantDetectionStatus contaminantDetectionStatus = ContaminantDetectionStatus.NOT_SUPPORTED;
+    /**
+     * UsbData status of the port.
+     */
+    boolean usbDataEnabled;
+}
diff --git a/usb/aidl/android/hardware/usb/Status.aidl b/usb/aidl/android/hardware/usb/Status.aidl
new file mode 100644
index 0000000..468ba4a
--- /dev/null
+++ b/usb/aidl/android/hardware/usb/Status.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.usb;
+
+@VintfStability
+@Backing(type="int")
+enum Status {
+    SUCCESS = 0,
+    /**
+     * error value when the HAL operation fails for reasons not listed here.
+     */
+    ERROR = 1,
+    /**
+     * error value returned when input argument is invalid.
+     */
+    INVALID_ARGUMENT = 2,
+    /**
+     * error value returned when role string is unrecognized.
+     */
+    UNRECOGNIZED_ROLE = 3,
+    /**
+     * Error value returned when the operation is not supported.
+     */
+    NOT_SUPPORTED = 4,
+}
diff --git a/usb/aidl/conversion.log b/usb/aidl/conversion.log
new file mode 100644
index 0000000..c090446
--- /dev/null
+++ b/usb/aidl/conversion.log
@@ -0,0 +1,11 @@
+Notes relating to hidl2aidl conversion of android.hardware.usb@1.3 to android.hardware.usb (if any) follow:
+Unhandled comments from android.hardware.usb@1.1::types follow. Consider using hidl-lint to locate these and fixup as many as possible.
+ // NOTE: suffix '_1_1' is for legacy ABI compatibility. It cannot be
+ // changed to 'PortMode' which the convention dictates.
+ // NOTE: suffix '_1_1' is for legacy ABI compatibility. It cannot be
+ // changed to 'PortStatus' which the convention dictates.
+
+An unknown named type was found in translation: android.hardware.usb@1.0::PortStatus
+An unknown named type was found in translation: android.hardware.usb@1.0::PortStatus
+An unknown named type was found in translation: android.hardware.usb@1.0::PortStatus
+END OF LOG
diff --git a/usb/aidl/default/Android.bp b/usb/aidl/default/Android.bp
new file mode 100644
index 0000000..7cb2822
--- /dev/null
+++ b/usb/aidl/default/Android.bp
@@ -0,0 +1,44 @@
+//
+// 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 {
+    // 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"],
+}
+
+cc_binary {
+    name: "android.hardware.usb-service.example",
+    relative_install_path: "hw",
+    init_rc: ["android.hardware.usb-service.example.rc"],
+    vintf_fragments: ["android.hardware.usb-service.example.xml"],
+    vendor: true,
+    srcs: [
+        "service.cpp",
+        "Usb.cpp",
+    ],
+    shared_libs: [
+        "android.hardware.usb-V1-ndk",
+        "libbase",
+        "libbinder_ndk",
+	"libcutils",
+        "liblog",
+        "libutils",
+    ],
+}
diff --git a/usb/aidl/default/Usb.cpp b/usb/aidl/default/Usb.cpp
new file mode 100644
index 0000000..1105376
--- /dev/null
+++ b/usb/aidl/default/Usb.cpp
@@ -0,0 +1,693 @@
+/*
+ * 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.usb.aidl-service"
+
+#include <aidl/android/hardware/usb/PortRole.h>
+#include <android-base/logging.h>
+#include <android-base/properties.h>
+#include <android-base/strings.h>
+#include <assert.h>
+#include <dirent.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <chrono>
+#include <regex>
+#include <thread>
+#include <unordered_map>
+
+#include <cutils/uevent.h>
+#include <sys/epoll.h>
+#include <utils/Errors.h>
+#include <utils/StrongPointer.h>
+
+#include "Usb.h"
+
+using android::base::GetProperty;
+using android::base::Trim;
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace usb {
+
+constexpr char kTypecPath[] = "/sys/class/typec/";
+constexpr char kDataRoleNode[] = "/data_role";
+constexpr char kPowerRoleNode[] = "/power_role";
+
+// Set by the signal handler to destroy the thread
+volatile bool destroyThread;
+
+void queryVersionHelper(android::hardware::usb::Usb *usb,
+                        std::vector<PortStatus> *currentPortStatus);
+
+ScopedAStatus Usb::enableUsbData(const string& in_portName, bool in_enable, int64_t in_transactionId) {
+    std::vector<PortStatus> currentPortStatus;
+
+    pthread_mutex_lock(&mLock);
+    if (mCallback != NULL) {
+        ScopedAStatus ret = mCallback->notifyEnableUsbDataStatus(
+            in_portName, true, in_enable ? Status::SUCCESS : Status::ERROR, in_transactionId);
+        if (!ret.isOk())
+            ALOGE("notifyEnableUsbDataStatus error %s", ret.getDescription().c_str());
+    } else {
+        ALOGE("Not notifying the userspace. Callback is not set");
+    }
+    pthread_mutex_unlock(&mLock);
+    queryVersionHelper(this, &currentPortStatus);
+
+    return ScopedAStatus::ok();
+}
+
+Status queryMoistureDetectionStatus(std::vector<PortStatus> *currentPortStatus) {
+    string enabled, status, path, DetectedPath;
+
+    for (int i = 0; i < currentPortStatus->size(); i++) {
+        (*currentPortStatus)[i].supportedContaminantProtectionModes
+                .push_back(ContaminantProtectionMode::NONE);
+        (*currentPortStatus)[i].contaminantProtectionStatus
+                = ContaminantProtectionStatus::NONE;
+        (*currentPortStatus)[i].contaminantDetectionStatus
+                = ContaminantDetectionStatus::NOT_SUPPORTED;
+        (*currentPortStatus)[i].supportsEnableContaminantPresenceDetection = false;
+        (*currentPortStatus)[i].supportsEnableContaminantPresenceProtection = false;
+    }
+
+    return Status::SUCCESS;
+}
+
+string appendRoleNodeHelper(const string &portName, PortRole::Tag tag) {
+    string node(kTypecPath + portName);
+
+    switch (tag) {
+        case PortRole::dataRole:
+            return node + kDataRoleNode;
+        case PortRole::powerRole:
+            return node + kPowerRoleNode;
+        case PortRole::mode:
+            return node + "/port_type";
+        default:
+            return "";
+    }
+}
+
+string convertRoletoString(PortRole role) {
+    if (role.getTag() == PortRole::powerRole) {
+        if (role.get<PortRole::powerRole>() == PortPowerRole::SOURCE)
+            return "source";
+        else if (role.get<PortRole::powerRole>() == PortPowerRole::SINK)
+            return "sink";
+    } else if (role.getTag() == PortRole::dataRole) {
+        if (role.get<PortRole::dataRole>() == PortDataRole::HOST)
+            return "host";
+        if (role.get<PortRole::dataRole>() == PortDataRole::DEVICE)
+            return "device";
+    } else if (role.getTag() == PortRole::mode) {
+        if (role.get<PortRole::mode>() == PortMode::UFP)
+            return "sink";
+        if (role.get<PortRole::mode>() == PortMode::DFP)
+            return "source";
+    }
+    return "none";
+}
+
+void extractRole(string *roleName) {
+    std::size_t first, last;
+
+    first = roleName->find("[");
+    last = roleName->find("]");
+
+    if (first != string::npos && last != string::npos) {
+        *roleName = roleName->substr(first + 1, last - first - 1);
+    }
+}
+
+void switchToDrp(const string &portName) {
+    string filename = appendRoleNodeHelper(string(portName.c_str()), PortRole::mode);
+    FILE *fp;
+
+    if (filename != "") {
+        fp = fopen(filename.c_str(), "w");
+        if (fp != NULL) {
+            int ret = fputs("dual", fp);
+            fclose(fp);
+            if (ret == EOF)
+                ALOGE("Fatal: Error while switching back to drp");
+        } else {
+            ALOGE("Fatal: Cannot open file to switch back to drp");
+        }
+    } else {
+        ALOGE("Fatal: invalid node type");
+    }
+}
+
+bool switchMode(const string &portName, const PortRole &in_role, struct Usb *usb) {
+    string filename = appendRoleNodeHelper(string(portName.c_str()), in_role.getTag());
+    string written;
+    FILE *fp;
+    bool roleSwitch = false;
+
+    if (filename == "") {
+        ALOGE("Fatal: invalid node type");
+        return false;
+    }
+
+    fp = fopen(filename.c_str(), "w");
+    if (fp != NULL) {
+        // Hold the lock here to prevent loosing connected signals
+        // as once the file is written the partner added signal
+        // can arrive anytime.
+        pthread_mutex_lock(&usb->mPartnerLock);
+        usb->mPartnerUp = false;
+        int ret = fputs(convertRoletoString(in_role).c_str(), fp);
+        fclose(fp);
+
+        if (ret != EOF) {
+            struct timespec to;
+            struct timespec now;
+
+        wait_again:
+            clock_gettime(CLOCK_MONOTONIC, &now);
+            to.tv_sec = now.tv_sec + PORT_TYPE_TIMEOUT;
+            to.tv_nsec = now.tv_nsec;
+
+            int err = pthread_cond_timedwait(&usb->mPartnerCV, &usb->mPartnerLock, &to);
+            // There are no uevent signals which implies role swap timed out.
+            if (err == ETIMEDOUT) {
+                ALOGI("uevents wait timedout");
+                // Validity check.
+            } else if (!usb->mPartnerUp) {
+                goto wait_again;
+                // Role switch succeeded since usb->mPartnerUp is true.
+            } else {
+                roleSwitch = true;
+            }
+        } else {
+            ALOGI("Role switch failed while wrting to file");
+        }
+        pthread_mutex_unlock(&usb->mPartnerLock);
+    }
+
+    if (!roleSwitch)
+        switchToDrp(string(portName.c_str()));
+
+    return roleSwitch;
+}
+
+Usb::Usb()
+    : mLock(PTHREAD_MUTEX_INITIALIZER),
+      mRoleSwitchLock(PTHREAD_MUTEX_INITIALIZER),
+      mPartnerLock(PTHREAD_MUTEX_INITIALIZER),
+      mPartnerUp(false)
+{
+    pthread_condattr_t attr;
+    if (pthread_condattr_init(&attr)) {
+        ALOGE("pthread_condattr_init failed: %s", strerror(errno));
+        abort();
+    }
+    if (pthread_condattr_setclock(&attr, CLOCK_MONOTONIC)) {
+        ALOGE("pthread_condattr_setclock failed: %s", strerror(errno));
+        abort();
+    }
+    if (pthread_cond_init(&mPartnerCV, &attr)) {
+        ALOGE("pthread_cond_init failed: %s", strerror(errno));
+        abort();
+    }
+    if (pthread_condattr_destroy(&attr)) {
+        ALOGE("pthread_condattr_destroy failed: %s", strerror(errno));
+        abort();
+    }
+}
+
+ScopedAStatus Usb::switchRole(const string& in_portName,
+        const PortRole& in_role, int64_t in_transactionId) {
+    string filename = appendRoleNodeHelper(string(in_portName.c_str()), in_role.getTag());
+    string written;
+    FILE *fp;
+    bool roleSwitch = false;
+
+    if (filename == "") {
+        ALOGE("Fatal: invalid node type");
+        return ScopedAStatus::ok();
+    }
+
+    pthread_mutex_lock(&mRoleSwitchLock);
+
+    ALOGI("filename write: %s role:%s", filename.c_str(), convertRoletoString(in_role).c_str());
+
+    if (in_role.getTag() == PortRole::mode) {
+        roleSwitch = switchMode(in_portName, in_role, this);
+    } else {
+        fp = fopen(filename.c_str(), "w");
+        if (fp != NULL) {
+            int ret = fputs(convertRoletoString(in_role).c_str(), fp);
+            fclose(fp);
+            if ((ret != EOF) && ReadFileToString(filename, &written)) {
+                written = Trim(written);
+                extractRole(&written);
+                ALOGI("written: %s", written.c_str());
+                if (written == convertRoletoString(in_role)) {
+                    roleSwitch = true;
+                } else {
+                    ALOGE("Role switch failed");
+                }
+            } else {
+                ALOGE("failed to update the new role");
+            }
+        } else {
+            ALOGE("fopen failed");
+        }
+    }
+
+    pthread_mutex_lock(&mLock);
+    if (mCallback != NULL) {
+         ScopedAStatus ret = mCallback->notifyRoleSwitchStatus(
+            in_portName, in_role, roleSwitch ? Status::SUCCESS : Status::ERROR, in_transactionId);
+        if (!ret.isOk())
+            ALOGE("RoleSwitchStatus error %s", ret.getDescription().c_str());
+    } else {
+        ALOGE("Not notifying the userspace. Callback is not set");
+    }
+    pthread_mutex_unlock(&mLock);
+    pthread_mutex_unlock(&mRoleSwitchLock);
+
+    return ScopedAStatus::ok();
+}
+
+Status getAccessoryConnected(const string &portName, string *accessory) {
+    string filename = kTypecPath + portName + "-partner/accessory_mode";
+
+    if (!ReadFileToString(filename, accessory)) {
+        ALOGE("getAccessoryConnected: Failed to open filesystem node: %s", filename.c_str());
+        return Status::ERROR;
+    }
+    *accessory = Trim(*accessory);
+
+    return Status::SUCCESS;
+}
+
+Status getCurrentRoleHelper(const string &portName, bool connected, PortRole *currentRole) {
+    string filename;
+    string roleName;
+    string accessory;
+
+    // Mode
+
+    if (currentRole->getTag() == PortRole::powerRole) {
+        filename = kTypecPath + portName + kPowerRoleNode;
+        currentRole->set<PortRole::powerRole>(PortPowerRole::NONE);
+    } else if (currentRole->getTag() == PortRole::dataRole) {
+        filename = kTypecPath + portName + kDataRoleNode;
+        currentRole->set<PortRole::dataRole>(PortDataRole::NONE);
+    } else if (currentRole->getTag() == PortRole::mode) {
+        filename = kTypecPath + portName + kDataRoleNode;
+        currentRole->set<PortRole::mode>(PortMode::NONE);
+    } else {
+        return Status::ERROR;
+    }
+
+    if (!connected)
+        return Status::SUCCESS;
+
+    if (currentRole->getTag() == PortRole::mode) {
+        if (getAccessoryConnected(portName, &accessory) != Status::SUCCESS) {
+            return Status::ERROR;
+        }
+        if (accessory == "analog_audio") {
+            currentRole->set<PortRole::mode>(PortMode::AUDIO_ACCESSORY);
+            return Status::SUCCESS;
+        } else if (accessory == "debug") {
+            currentRole->set<PortRole::mode>(PortMode::DEBUG_ACCESSORY);
+            return Status::SUCCESS;
+        }
+    }
+
+    if (!ReadFileToString(filename, &roleName)) {
+        ALOGE("getCurrentRole: Failed to open filesystem node: %s", filename.c_str());
+        return Status::ERROR;
+    }
+
+    roleName = Trim(roleName);
+    extractRole(&roleName);
+
+    if (roleName == "source") {
+        currentRole->set<PortRole::powerRole>(PortPowerRole::SOURCE);
+    } else if (roleName == "sink") {
+        currentRole->set<PortRole::powerRole>(PortPowerRole::SINK);
+    } else if (roleName == "host") {
+        if (currentRole->getTag() == PortRole::dataRole)
+            currentRole->set<PortRole::dataRole>(PortDataRole::HOST);
+        else
+            currentRole->set<PortRole::mode>(PortMode::DFP);
+    } else if (roleName == "device") {
+        if (currentRole->getTag() == PortRole::dataRole)
+            currentRole->set<PortRole::dataRole>(PortDataRole::DEVICE);
+        else
+            currentRole->set<PortRole::mode>(PortMode::UFP);
+    } else if (roleName != "none") {
+        /* case for none has already been addressed.
+         * so we check if the role isn't none.
+         */
+        return Status::UNRECOGNIZED_ROLE;
+    }
+
+    return Status::SUCCESS;
+}
+
+Status getTypeCPortNamesHelper(std::unordered_map<string, bool> *names) {
+    DIR *dp;
+
+    dp = opendir(kTypecPath);
+    if (dp != NULL) {
+        struct dirent *ep;
+
+        while ((ep = readdir(dp))) {
+            if (ep->d_type == DT_LNK) {
+                if (string::npos == string(ep->d_name).find("-partner")) {
+                    std::unordered_map<string, bool>::const_iterator portName =
+                        names->find(ep->d_name);
+                    if (portName == names->end()) {
+                        names->insert({ep->d_name, false});
+                    }
+                } else {
+                    (*names)[std::strtok(ep->d_name, "-")] = true;
+                }
+            }
+        }
+        closedir(dp);
+        return Status::SUCCESS;
+    }
+
+    ALOGE("Failed to open /sys/class/typec");
+    return Status::ERROR;
+}
+
+bool canSwitchRoleHelper(const string &portName) {
+    string filename = kTypecPath + portName + "-partner/supports_usb_power_delivery";
+    string supportsPD;
+
+    if (ReadFileToString(filename, &supportsPD)) {
+        supportsPD = Trim(supportsPD);
+        if (supportsPD == "yes") {
+            return true;
+        }
+    }
+
+    return false;
+}
+
+Status getPortStatusHelper(std::vector<PortStatus> *currentPortStatus) {
+    std::unordered_map<string, bool> names;
+    Status result = getTypeCPortNamesHelper(&names);
+    int i = -1;
+
+    if (result == Status::SUCCESS) {
+        currentPortStatus->resize(names.size());
+        for (std::pair<string, bool> port : names) {
+            i++;
+            ALOGI("%s", port.first.c_str());
+            (*currentPortStatus)[i].portName = port.first;
+
+            PortRole currentRole;
+            currentRole.set<PortRole::powerRole>(PortPowerRole::NONE);
+            if (getCurrentRoleHelper(port.first, port.second, &currentRole) == Status::SUCCESS){
+                (*currentPortStatus)[i].currentPowerRole = currentRole.get<PortRole::powerRole>();
+            } else {
+                ALOGE("Error while retrieving portNames");
+                goto done;
+            }
+
+            currentRole.set<PortRole::dataRole>(PortDataRole::NONE);
+            if (getCurrentRoleHelper(port.first, port.second, &currentRole) == Status::SUCCESS) {
+                (*currentPortStatus)[i].currentDataRole = currentRole.get<PortRole::dataRole>();
+            } else {
+                ALOGE("Error while retrieving current port role");
+                goto done;
+            }
+
+            currentRole.set<PortRole::mode>(PortMode::NONE);
+            if (getCurrentRoleHelper(port.first, port.second, &currentRole) == Status::SUCCESS) {
+                (*currentPortStatus)[i].currentMode = currentRole.get<PortRole::mode>();
+            } else {
+                ALOGE("Error while retrieving current data role");
+                goto done;
+            }
+
+            (*currentPortStatus)[i].canChangeMode = true;
+            (*currentPortStatus)[i].canChangeDataRole =
+                port.second ? canSwitchRoleHelper(port.first) : false;
+            (*currentPortStatus)[i].canChangePowerRole =
+                port.second ? canSwitchRoleHelper(port.first) : false;
+
+            (*currentPortStatus)[i].supportedModes.push_back(PortMode::DRP);
+            (*currentPortStatus)[i].usbDataEnabled = true;
+
+            ALOGI("%d:%s connected:%d canChangeMode:%d canChagedata:%d canChangePower:%d "
+                "usbDataEnabled:%d",
+                i, port.first.c_str(), port.second,
+                (*currentPortStatus)[i].canChangeMode,
+                (*currentPortStatus)[i].canChangeDataRole,
+                (*currentPortStatus)[i].canChangePowerRole, 0);
+        }
+
+        return Status::SUCCESS;
+    }
+done:
+    return Status::ERROR;
+}
+
+void queryVersionHelper(android::hardware::usb::Usb *usb,
+                        std::vector<PortStatus> *currentPortStatus) {
+    Status status;
+    pthread_mutex_lock(&usb->mLock);
+    status = getPortStatusHelper(currentPortStatus);
+    queryMoistureDetectionStatus(currentPortStatus);
+    if (usb->mCallback != NULL) {
+        ScopedAStatus ret = usb->mCallback->notifyPortStatusChange(*currentPortStatus,
+            status);
+        if (!ret.isOk())
+            ALOGE("queryPortStatus error %s", ret.getDescription().c_str());
+    } else {
+        ALOGI("Notifying userspace skipped. Callback is NULL");
+    }
+    pthread_mutex_unlock(&usb->mLock);
+}
+
+ScopedAStatus Usb::queryPortStatus(int64_t in_transactionId) {
+    std::vector<PortStatus> currentPortStatus;
+
+    queryVersionHelper(this, &currentPortStatus);
+    pthread_mutex_lock(&mLock);
+    if (mCallback != NULL) {
+        ScopedAStatus ret = mCallback->notifyQueryPortStatus(
+            "all", Status::SUCCESS, in_transactionId);
+        if (!ret.isOk())
+            ALOGE("notifyQueryPortStatus error %s", ret.getDescription().c_str());
+    } else {
+        ALOGE("Not notifying the userspace. Callback is not set");
+    }
+    pthread_mutex_unlock(&mLock);
+
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus Usb::enableContaminantPresenceDetection(const string& in_portName,
+        bool /*in_enable*/, int64_t in_transactionId) {
+    std::vector<PortStatus> currentPortStatus;
+
+    pthread_mutex_lock(&mLock);
+    if (mCallback != NULL) {
+        ScopedAStatus ret = mCallback->notifyContaminantEnabledStatus(
+            in_portName, false, Status::ERROR, in_transactionId);
+        if (!ret.isOk())
+            ALOGE("enableContaminantPresenceDetection  error %s", ret.getDescription().c_str());
+    } else {
+        ALOGE("Not notifying the userspace. Callback is not set");
+    }
+    pthread_mutex_unlock(&mLock);
+
+    queryVersionHelper(this, &currentPortStatus);
+    return ScopedAStatus::ok();
+}
+
+
+struct data {
+    int uevent_fd;
+    ::aidl::android::hardware::usb::Usb *usb;
+};
+
+static void uevent_event(uint32_t /*epevents*/, struct data *payload) {
+    char msg[UEVENT_MSG_LEN + 2];
+    char *cp;
+    int n;
+
+    n = uevent_kernel_multicast_recv(payload->uevent_fd, msg, UEVENT_MSG_LEN);
+    if (n <= 0)
+        return;
+    if (n >= UEVENT_MSG_LEN) /* overflow -- discard */
+        return;
+
+    msg[n] = '\0';
+    msg[n + 1] = '\0';
+    cp = msg;
+
+    while (*cp) {
+        if (std::regex_match(cp, std::regex("(add)(.*)(-partner)"))) {
+            ALOGI("partner added");
+            pthread_mutex_lock(&payload->usb->mPartnerLock);
+            payload->usb->mPartnerUp = true;
+            pthread_cond_signal(&payload->usb->mPartnerCV);
+            pthread_mutex_unlock(&payload->usb->mPartnerLock);
+        } else if (!strncmp(cp, "DEVTYPE=typec_", strlen("DEVTYPE=typec_"))) {
+            std::vector<PortStatus> currentPortStatus;
+            queryVersionHelper(payload->usb, &currentPortStatus);
+
+            // Role switch is not in progress and port is in disconnected state
+            if (!pthread_mutex_trylock(&payload->usb->mRoleSwitchLock)) {
+                for (unsigned long i = 0; i < currentPortStatus.size(); i++) {
+                    DIR *dp =
+                        opendir(string(kTypecPath +
+                                       string(currentPortStatus[i].portName.c_str()) +
+                                       "-partner").c_str());
+                    if (dp == NULL) {
+                        switchToDrp(currentPortStatus[i].portName);
+                    } else {
+                        closedir(dp);
+                    }
+                }
+                pthread_mutex_unlock(&payload->usb->mRoleSwitchLock);
+            }
+            break;
+        } /* advance to after the next \0 */
+        while (*cp++) {
+        }
+    }
+}
+
+void *work(void *param) {
+    int epoll_fd, uevent_fd;
+    struct epoll_event ev;
+    int nevents = 0;
+    struct data payload;
+
+    uevent_fd = uevent_open_socket(UEVENT_MAX_EVENTS * UEVENT_MSG_LEN, true);
+
+    if (uevent_fd < 0) {
+        ALOGE("uevent_init: uevent_open_socket failed\n");
+        return NULL;
+    }
+
+    payload.uevent_fd = uevent_fd;
+    payload.usb = (::aidl::android::hardware::usb::Usb *)param;
+
+    fcntl(uevent_fd, F_SETFL, O_NONBLOCK);
+
+    ev.events = EPOLLIN;
+    ev.data.ptr = (void *)uevent_event;
+
+    epoll_fd = epoll_create(UEVENT_MAX_EVENTS);
+    if (epoll_fd == -1) {
+        ALOGE("epoll_create failed; errno=%d", errno);
+        goto error;
+    }
+
+    if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, uevent_fd, &ev) == -1) {
+        ALOGE("epoll_ctl failed; errno=%d", errno);
+        goto error;
+    }
+
+    while (!destroyThread) {
+        struct epoll_event events[UEVENT_MAX_EVENTS];
+
+        nevents = epoll_wait(epoll_fd, events, UEVENT_MAX_EVENTS, -1);
+        if (nevents == -1) {
+            if (errno == EINTR)
+                continue;
+            ALOGE("usb epoll_wait failed; errno=%d", errno);
+            break;
+        }
+
+        for (int n = 0; n < nevents; ++n) {
+            if (events[n].data.ptr)
+                (*(void (*)(int, struct data *payload))events[n].data.ptr)(events[n].events,
+                                                                           &payload);
+        }
+    }
+
+    ALOGI("exiting worker thread");
+error:
+    close(uevent_fd);
+
+    if (epoll_fd >= 0)
+        close(epoll_fd);
+
+    return NULL;
+}
+
+void sighandler(int sig) {
+    if (sig == SIGUSR1) {
+        destroyThread = true;
+        ALOGI("destroy set");
+        return;
+    }
+    signal(SIGUSR1, sighandler);
+}
+
+ScopedAStatus Usb::setCallback(
+        const shared_ptr<IUsbCallback>& in_callback) {
+
+    pthread_mutex_lock(&mLock);
+    if ((mCallback == NULL && in_callback == NULL) ||
+            (mCallback != NULL && in_callback != NULL)) {
+        mCallback = in_callback;
+        pthread_mutex_unlock(&mLock);
+        return ScopedAStatus::ok();
+    }
+
+    mCallback = in_callback;
+    ALOGI("registering callback");
+
+    if (mCallback == NULL) {
+        if  (!pthread_kill(mPoll, SIGUSR1)) {
+            pthread_join(mPoll, NULL);
+            ALOGI("pthread destroyed");
+        }
+        pthread_mutex_unlock(&mLock);
+        return ScopedAStatus::ok();
+    }
+
+    destroyThread = false;
+    signal(SIGUSR1, sighandler);
+
+    /*
+     * Create a background thread if the old callback value is NULL
+     * and being updated with a new value.
+     */
+    if (pthread_create(&mPoll, NULL, work, this)) {
+        ALOGE("pthread creation failed %d", errno);
+        mCallback = NULL;
+    }
+
+    pthread_mutex_unlock(&mLock);
+    return ScopedAStatus::ok();
+}
+
+} // namespace usb
+} // namespace hardware
+} // namespace android
+} // aidl
diff --git a/usb/aidl/default/Usb.h b/usb/aidl/default/Usb.h
new file mode 100644
index 0000000..bca86ae
--- /dev/null
+++ b/usb/aidl/default/Usb.h
@@ -0,0 +1,76 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <android-base/file.h>
+#include <aidl/android/hardware/usb/BnUsb.h>
+#include <aidl/android/hardware/usb/BnUsbCallback.h>
+#include <utils/Log.h>
+
+#define UEVENT_MSG_LEN     2048
+#define UEVENT_MAX_EVENTS  64
+// The type-c stack waits for 4.5 - 5.5 secs before declaring a port non-pd.
+// The -partner directory would not be created until this is done.
+// Having a margin of ~3 secs for the directory and other related bookeeping
+// structures created and uvent fired.
+#define PORT_TYPE_TIMEOUT 8
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace usb {
+
+using ::aidl::android::hardware::usb::IUsbCallback;
+using ::aidl::android::hardware::usb::PortRole;
+using ::android::base::ReadFileToString;
+using ::android::base::WriteStringToFile;
+using ::android::sp;
+using ::ndk::ScopedAStatus;
+using ::std::shared_ptr;
+using ::std::string;
+
+struct Usb : public BnUsb {
+    Usb();
+
+    ScopedAStatus enableContaminantPresenceDetection(const std::string& in_portName,
+            bool in_enable, int64_t in_transactionId) override;
+    ScopedAStatus queryPortStatus(int64_t in_transactionId) override;
+    ScopedAStatus setCallback(const shared_ptr<IUsbCallback>& in_callback) override;
+    ScopedAStatus switchRole(const string& in_portName, const PortRole& in_role,
+            int64_t in_transactionId) override;
+    ScopedAStatus enableUsbData(const string& in_portName, bool in_enable,
+            int64_t in_transactionId) override;
+
+    shared_ptr<IUsbCallback> mCallback;
+    // Protects mCallback variable
+    pthread_mutex_t mLock;
+    // Protects roleSwitch operation
+    pthread_mutex_t mRoleSwitchLock;
+    // Threads waiting for the partner to come back wait here
+    pthread_cond_t mPartnerCV;
+    // lock protecting mPartnerCV
+    pthread_mutex_t mPartnerLock;
+    // Variable to signal partner coming back online after type switch
+    bool mPartnerUp;
+  private:
+    pthread_t mPoll;
+};
+
+} // namespace usb
+} // namespace hardware
+} // namespace android
+} // aidl
diff --git a/usb/aidl/default/android.hardware.usb-service.example.rc b/usb/aidl/default/android.hardware.usb-service.example.rc
new file mode 100644
index 0000000..335bca7
--- /dev/null
+++ b/usb/aidl/default/android.hardware.usb-service.example.rc
@@ -0,0 +1,4 @@
+service vendor.usb_default /vendor/bin/hw/android.hardware.usb-service.example
+    class hal
+    user system
+    group system
diff --git a/usb/aidl/default/android.hardware.usb-service.example.xml b/usb/aidl/default/android.hardware.usb-service.example.xml
new file mode 100644
index 0000000..6088194
--- /dev/null
+++ b/usb/aidl/default/android.hardware.usb-service.example.xml
@@ -0,0 +1,10 @@
+<manifest version="1.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.usb</name>
+        <version>1</version>
+        <interface>
+            <name>IUsb</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+</manifest>
diff --git a/usb/aidl/default/service.cpp b/usb/aidl/default/service.cpp
new file mode 100644
index 0000000..398458a
--- /dev/null
+++ b/usb/aidl/default/service.cpp
@@ -0,0 +1,35 @@
+/*
+ * 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/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+#include "Usb.h"
+
+using ::aidl::android::hardware::usb::Usb;
+
+int main() {
+    ABinderProcess_setThreadPoolMaxThreadCount(0);
+    std::shared_ptr<Usb> usb = ndk::SharedRefBase::make<Usb>();
+
+    const std::string instance = std::string() + Usb::descriptor + "/default";
+    binder_status_t status = AServiceManager_addService(usb->asBinder().get(), instance.c_str());
+    CHECK(status == STATUS_OK);
+
+    ABinderProcess_joinThreadPool();
+    return -1; // Should never be reached
+}
diff --git a/usb/aidl/vts/Android.bp b/usb/aidl/vts/Android.bp
new file mode 100644
index 0000000..00a7c93
--- /dev/null
+++ b/usb/aidl/vts/Android.bp
@@ -0,0 +1,43 @@
+//
+// 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 {
+    // 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"],
+}
+
+cc_test {
+    name: "VtsAidlUsbTargetTest",
+    defaults: [
+        "VtsHalTargetTestDefaults",
+        "use_libaidlvintf_gtest_helper_static",
+    ],
+    srcs: ["VtsAidlUsbTargetTest.cpp"],
+    shared_libs: [
+        "libbinder_ndk",
+    ],
+    static_libs: [
+        "android.hardware.usb-V1-ndk",
+    ],
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
+}
diff --git a/usb/aidl/vts/VtsAidlUsbTargetTest.cpp b/usb/aidl/vts/VtsAidlUsbTargetTest.cpp
new file mode 100644
index 0000000..09cb096
--- /dev/null
+++ b/usb/aidl/vts/VtsAidlUsbTargetTest.cpp
@@ -0,0 +1,424 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Probject
+ *
+ * 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 "UsbAidlTest"
+#include <android-base/logging.h>
+
+#include <aidl/android/hardware/usb/IUsb.h>
+#include <aidl/android/hardware/usb/IUsbCallback.h>
+#include <aidl/android/hardware/usb/BnUsbCallback.h>
+#include <aidl/android/hardware/usb/PortDataRole.h>
+#include <aidl/android/hardware/usb/PortMode.h>
+#include <aidl/android/hardware/usb/PortPowerRole.h>
+#include <aidl/android/hardware/usb/PortRole.h>
+#include <aidl/android/hardware/usb/PortStatus.h>
+#include <aidl/android/hardware/usb/Status.h>
+#include <aidl/Vintf.h>
+#include <aidl/Gtest.h>
+
+#include <android/binder_auto_utils.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <gtest/gtest.h>
+
+#include <log/log.h>
+#include <stdlib.h>
+#include <chrono>
+#include <condition_variable>
+#include <mutex>
+
+#define TIMEOUT_PERIOD 10
+
+using ::aidl::android::hardware::usb::BnUsbCallback;
+using ::aidl::android::hardware::usb::IUsb;
+using ::aidl::android::hardware::usb::IUsbCallback;
+using ::aidl::android::hardware::usb::PortDataRole;
+using ::aidl::android::hardware::usb::PortMode;
+using ::aidl::android::hardware::usb::PortPowerRole;
+using ::aidl::android::hardware::usb::PortRole;
+using ::aidl::android::hardware::usb::PortStatus;
+using ::aidl::android::hardware::usb::Status;
+
+using ::ndk::ScopedAStatus;
+using ::ndk::SpAIBinder;
+using std::vector;
+using std::shared_ptr;
+using std::string;
+
+// The main test class for the USB aidl hal
+class UsbAidlTest : public testing::TestWithParam<std::string> {
+ public:
+  // Callback class for the USB aidl hal.
+  // Usb Hal will call this object upon role switch or port query.
+  class UsbCallback : public BnUsbCallback {
+    UsbAidlTest& parent_;
+    int cookie;
+
+   public:
+    UsbCallback(UsbAidlTest& parent, int cookie)
+        : parent_(parent), cookie(cookie){};
+
+    virtual ~UsbCallback() = default;
+
+    // Callback method for the port status.
+    ScopedAStatus notifyPortStatusChange(const vector<PortStatus>& currentPortStatus,
+                                         Status retval) override {
+      if (retval == Status::SUCCESS && currentPortStatus.size() > 0) {
+        parent_.usb_last_port_status.portName =
+            currentPortStatus[0].portName.c_str();
+        parent_.usb_last_port_status.currentDataRole =
+            currentPortStatus[0].currentDataRole;
+        parent_.usb_last_port_status.currentPowerRole =
+            currentPortStatus[0].currentPowerRole;
+        parent_.usb_last_port_status.currentMode =
+            currentPortStatus[0].currentMode;
+      }
+      parent_.usb_last_cookie = cookie;
+      return ScopedAStatus::ok();
+    }
+
+    // Callback method for the status of role switch operation.
+    ScopedAStatus notifyRoleSwitchStatus(const string& /*portName*/, const PortRole& newRole,
+                                         Status retval, int64_t transactionId) override {
+      parent_.usb_last_status = retval;
+      parent_.usb_last_cookie = cookie;
+      parent_.usb_last_port_role = newRole;
+      parent_.usb_role_switch_done = true;
+      parent_.last_transactionId = transactionId;
+      parent_.notify();
+      return ScopedAStatus::ok();
+    }
+
+    // Callback method for the status of enableUsbData operation
+    ScopedAStatus notifyEnableUsbDataStatus(const string& /*portName*/, bool /*enable*/,
+                                            Status /*retval*/, int64_t transactionId) override {
+      parent_.last_transactionId = transactionId;
+      parent_.usb_last_cookie = cookie;
+      parent_.enable_usb_data_done = true;
+      parent_.notify();
+      return ScopedAStatus::ok();
+    }
+
+    // Callback method for the status of enableContaminantPresenceDetection
+    ScopedAStatus notifyContaminantEnabledStatus(const string& /*portName*/, bool /*enable*/,
+                                                 Status /*retval*/, int64_t transactionId) override {
+      parent_.last_transactionId = transactionId;
+      parent_.usb_last_cookie = cookie;
+      parent_.enable_contaminant_done = true;
+      parent_.notify();
+      return ScopedAStatus::ok();
+    }
+
+    // Callback method for the status of queryPortStatus operation
+    ScopedAStatus notifyQueryPortStatus(const string& /*portName*/, Status /*retval*/,
+                                        int64_t transactionId) override {
+      parent_.last_transactionId = transactionId;
+      parent_.notify();
+      return ScopedAStatus::ok();
+    }
+  };
+
+  virtual void SetUp() override {
+    ALOGI("Setup");
+    usb = IUsb::fromBinder(
+                SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
+    ASSERT_NE(usb, nullptr);
+
+    usb_cb_2 = ::ndk::SharedRefBase::make<UsbCallback>(*this, 2);
+    ASSERT_NE(usb_cb_2, nullptr);
+    const auto& ret = usb->setCallback(usb_cb_2);
+    ASSERT_TRUE(ret.isOk());
+  }
+
+  virtual void TearDown() override { ALOGI("Teardown"); }
+
+  // Used as a mechanism to inform the test about data/event callback.
+  inline void notify() {
+    std::unique_lock<std::mutex> lock(usb_mtx);
+    usb_count++;
+    usb_cv.notify_one();
+  }
+
+  // Test code calls this function to wait for data/event callback.
+  inline std::cv_status wait() {
+    std::unique_lock<std::mutex> lock(usb_mtx);
+
+    std::cv_status status = std::cv_status::no_timeout;
+    auto now = std::chrono::system_clock::now();
+    while (usb_count == 0) {
+      status =
+          usb_cv.wait_until(lock, now + std::chrono::seconds(TIMEOUT_PERIOD));
+      if (status == std::cv_status::timeout) {
+        ALOGI("timeout");
+        return status;
+      }
+    }
+    usb_count--;
+    return status;
+  }
+
+  // USB aidl hal Proxy
+  shared_ptr<IUsb> usb;
+
+  // Callback objects for usb aidl
+  // Methods of these objects are called to notify port status updates.
+  shared_ptr<IUsbCallback> usb_cb_1, usb_cb_2;
+
+  // The last conveyed status of the USB ports.
+  // Stores information of currentt_data_role, power_role for all the USB ports
+  PortStatus usb_last_port_status;
+
+  // Status of the last role switch operation.
+  Status usb_last_status;
+
+  // Port role information of the last role switch operation.
+  PortRole usb_last_port_role;
+
+  // Flag to indicate the invocation of role switch callback.
+  bool usb_role_switch_done;
+
+  // Flag to indicate the invocation of notifyContaminantEnabledStatus callback.
+  bool enable_contaminant_done;
+
+  // Flag to indicate the invocation of notifyEnableUsbDataStatus callback.
+  bool enable_usb_data_done;
+
+  // Stores the cookie of the last invoked usb callback object.
+  int usb_last_cookie;
+
+  // Last transaction ID that was recorded.
+  int64_t last_transactionId;
+  // synchronization primitives to coordinate between main test thread
+  // and the callback thread.
+  std::mutex usb_mtx;
+  std::condition_variable usb_cv;
+  int usb_count = 0;
+};
+
+/*
+ * Test to see if setCallback succeeds.
+ * Callback object is created and registered.
+ */
+TEST_P(UsbAidlTest, setCallback) {
+  ALOGI("UsbAidlTest setCallback start");
+  usb_cb_1 = ::ndk::SharedRefBase::make<UsbCallback>(*this, 1);
+  ASSERT_NE(usb_cb_1, nullptr);
+  const auto& ret = usb->setCallback(usb_cb_1);
+  ASSERT_TRUE(ret.isOk());
+  ALOGI("UsbAidlTest setCallback end");
+}
+
+/*
+ * Check to see if querying type-c
+ * port status succeeds.
+ * The callback parameters are checked to see if the transaction id
+ * matches.
+ */
+TEST_P(UsbAidlTest, queryPortStatus) {
+  ALOGI("UsbAidlTest queryPortStatus start");
+  int64_t transactionId = rand() % 10000;
+  const auto& ret = usb->queryPortStatus(transactionId);
+  ASSERT_TRUE(ret.isOk());
+  EXPECT_EQ(std::cv_status::no_timeout, wait());
+  EXPECT_EQ(2, usb_last_cookie);
+  EXPECT_EQ(transactionId, last_transactionId);
+  ALOGI("UsbAidlTest queryPortStatus end: %s", usb_last_port_status.portName.c_str());
+}
+
+/*
+ * Trying to switch a non-existent port should fail.
+ * This test case tried to switch the port with empty
+ * name which is expected to fail.
+ * The callback parameters are checked to see if the transaction id
+ * matches.
+ */
+TEST_P(UsbAidlTest, switchEmptyPort) {
+  ALOGI("UsbAidlTest switchEmptyPort start");
+  PortRole role;
+  role.set<PortRole::powerRole>(PortPowerRole::SOURCE);
+  int64_t transactionId = rand() % 10000;
+  const auto& ret = usb->switchRole("", role, transactionId);
+  ASSERT_TRUE(ret.isOk());
+  EXPECT_EQ(std::cv_status::no_timeout, wait());
+  EXPECT_EQ(Status::ERROR, usb_last_status);
+  EXPECT_EQ(transactionId, last_transactionId);
+  EXPECT_EQ(2, usb_last_cookie);
+  ALOGI("UsbAidlTest switchEmptyPort end");
+}
+
+/*
+ * Test switching the power role of usb port.
+ * Test case queries the usb ports present in device.
+ * If there is at least one usb port, a power role switch
+ * to SOURCE is attempted for the port.
+ * The callback parameters are checked to see if the transaction id
+ * matches.
+ */
+TEST_P(UsbAidlTest, switchPowerRole) {
+  ALOGI("UsbAidlTest switchPowerRole start");
+  PortRole role;
+  role.set<PortRole::powerRole>(PortPowerRole::SOURCE);
+  int64_t transactionId = rand() % 10000;
+  const auto& ret = usb->queryPortStatus(transactionId);
+  ASSERT_TRUE(ret.isOk());
+  EXPECT_EQ(std::cv_status::no_timeout, wait());
+  EXPECT_EQ(2, usb_last_cookie);
+  EXPECT_EQ(transactionId, last_transactionId);
+
+  if (!usb_last_port_status.portName.empty()) {
+    string portBeingSwitched = usb_last_port_status.portName;
+    ALOGI("switchPower role portname:%s", portBeingSwitched.c_str());
+    usb_role_switch_done = false;
+    transactionId = rand() % 10000;
+    const auto& ret = usb->switchRole(portBeingSwitched, role, transactionId);
+    ASSERT_TRUE(ret.isOk());
+
+    std::cv_status waitStatus = wait();
+    while (waitStatus == std::cv_status::no_timeout &&
+           usb_role_switch_done == false)
+      waitStatus = wait();
+
+    EXPECT_EQ(std::cv_status::no_timeout, waitStatus);
+    EXPECT_EQ(2, usb_last_cookie);
+    EXPECT_EQ(transactionId, last_transactionId);
+  }
+  ALOGI("UsbAidlTest switchPowerRole end");
+}
+
+/*
+ * Test switching the data role of usb port.
+ * Test case queries the usb ports present in device.
+ * If there is at least one usb port, a data role switch
+ * to device is attempted for the port.
+ * The callback parameters are checked to see if transaction id
+ * matches.
+ */
+TEST_P(UsbAidlTest, switchDataRole) {
+  ALOGI("UsbAidlTest switchDataRole start");
+  PortRole role;
+  role.set<PortRole::dataRole>(PortDataRole::DEVICE);
+  int64_t transactionId = rand() % 10000;
+  const auto& ret = usb->queryPortStatus(transactionId);
+  ASSERT_TRUE(ret.isOk());
+  EXPECT_EQ(std::cv_status::no_timeout, wait());
+  EXPECT_EQ(2, usb_last_cookie);
+  EXPECT_EQ(transactionId, last_transactionId);
+
+  if (!usb_last_port_status.portName.empty()) {
+    string portBeingSwitched = usb_last_port_status.portName;
+    ALOGI("portname:%s", portBeingSwitched.c_str());
+    usb_role_switch_done = false;
+    transactionId = rand() % 10000;
+    const auto& ret = usb->switchRole(portBeingSwitched, role, transactionId);
+    ASSERT_TRUE(ret.isOk());
+
+    std::cv_status waitStatus = wait();
+    while (waitStatus == std::cv_status::no_timeout &&
+           usb_role_switch_done == false)
+      waitStatus = wait();
+
+    EXPECT_EQ(std::cv_status::no_timeout, waitStatus);
+    EXPECT_EQ(2, usb_last_cookie);
+    EXPECT_EQ(transactionId, last_transactionId);
+  }
+  ALOGI("UsbAidlTest switchDataRole end");
+}
+
+/*
+ * Test enabling contaminant presence detection of the port.
+ * Test case queries the usb ports present in device.
+ * If there is at least one usb port, enabling contaminant detection
+ * is attempted for the port.
+ * The callback parameters are checked to see if transaction id
+ * matches.
+ */
+TEST_P(UsbAidlTest, enableContaminantPresenceDetection) {
+  ALOGI("UsbAidlTest enableContaminantPresenceDetection start");
+  int64_t transactionId = rand() % 10000;
+  const auto& ret = usb->queryPortStatus(transactionId);
+  ASSERT_TRUE(ret.isOk());
+  EXPECT_EQ(std::cv_status::no_timeout, wait());
+  EXPECT_EQ(2, usb_last_cookie);
+  EXPECT_EQ(transactionId, last_transactionId);
+
+  if (!usb_last_port_status.portName.empty()) {
+    ALOGI("portname:%s", usb_last_port_status.portName.c_str());
+    enable_contaminant_done = false;
+    transactionId = rand() % 10000;
+    const auto& ret = usb->enableContaminantPresenceDetection(usb_last_port_status.portName,
+                                                              true, transactionId);
+    ASSERT_TRUE(ret.isOk());
+
+    std::cv_status waitStatus = wait();
+    while (waitStatus == std::cv_status::no_timeout &&
+           enable_contaminant_done == false)
+      waitStatus = wait();
+
+    EXPECT_EQ(std::cv_status::no_timeout, waitStatus);
+    EXPECT_EQ(2, usb_last_cookie);
+    EXPECT_EQ(transactionId, last_transactionId);
+  }
+  ALOGI("UsbAidlTest enableContaminantPresenceDetection end");
+}
+
+/*
+ * Test enabling Usb data of the port.
+ * Test case queries the usb ports present in device.
+ * If there is at least one usb port, enabling Usb data is attempted
+ * for the port.
+ * The callback parameters are checked to see if transaction id
+ * matches.
+ */
+TEST_P(UsbAidlTest, enableUsbData) {
+  ALOGI("UsbAidlTest enableUsbData start");
+  int64_t transactionId = rand() % 10000;
+  const auto& ret = usb->queryPortStatus(transactionId);
+  ASSERT_TRUE(ret.isOk());
+  EXPECT_EQ(std::cv_status::no_timeout, wait());
+  EXPECT_EQ(2, usb_last_cookie);
+  EXPECT_EQ(transactionId, last_transactionId);
+
+  if (!usb_last_port_status.portName.empty()) {
+    ALOGI("portname:%s", usb_last_port_status.portName.c_str());
+    enable_usb_data_done = false;
+    transactionId = rand() % 10000;
+    const auto& ret = usb->enableUsbData(usb_last_port_status.portName, true, transactionId);
+    ASSERT_TRUE(ret.isOk());
+
+    std::cv_status waitStatus = wait();
+    while (waitStatus == std::cv_status::no_timeout &&
+           enable_usb_data_done == false)
+      waitStatus = wait();
+
+    EXPECT_EQ(std::cv_status::no_timeout, waitStatus);
+    EXPECT_EQ(2, usb_last_cookie);
+    EXPECT_EQ(transactionId, last_transactionId);
+  }
+  ALOGI("UsbAidlTest enableUsbData end");
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(UsbAidlTest);
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, UsbAidlTest,
+        testing::ValuesIn(::android::getAidlHalInstanceNames(IUsb::descriptor)),
+        ::android::PrintInstanceNameToString);
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    ABinderProcess_setThreadPoolMaxThreadCount(1);
+    ABinderProcess_startThreadPool();
+    return RUN_ALL_TESTS();
+}
diff --git a/vibrator/aidl/Android.bp b/vibrator/aidl/Android.bp
index d4d5857..86ef027 100644
--- a/vibrator/aidl/Android.bp
+++ b/vibrator/aidl/Android.bp
@@ -19,11 +19,6 @@
         java: {
             sdk_version: "module_current",
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
     },
     versions: [
         "1",
diff --git a/vibrator/aidl/default/Android.bp b/vibrator/aidl/default/Android.bp
index acdbdcd..c4140be 100644
--- a/vibrator/aidl/default/Android.bp
+++ b/vibrator/aidl/default/Android.bp
@@ -63,7 +63,6 @@
         "libbinder_random_parcel",
         "libcutils",
         "liblog",
-        "libutils",
         "libvibratorexampleimpl",
     ],
     target: {
@@ -71,12 +70,14 @@
             shared_libs: [
                 "libbinder_ndk",
                 "libbinder",
+                "libutils",
             ],
         },
         host: {
             static_libs: [
                 "libbinder_ndk",
                 "libbinder",
+                "libutils",
             ],
         },
         darwin: {
diff --git a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
index a8ae777..791d7e8 100644
--- a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
+++ b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
@@ -196,7 +196,7 @@
     active.startFrequency = frequencyHz;
     active.endAmplitude = (getAmplitudeMin() + getAmplitudeMax()) / 2;
     active.endFrequency = frequencyHz;
-    active.duration = 1000;
+    vibrator->getPwlePrimitiveDurationMax(&(active.duration));
 
     return active;
 }
@@ -332,6 +332,7 @@
         sleep(1);
         EXPECT_EQ(Status::EX_NONE, vibrator->setAmplitude(1.0f).exceptionCode());
         sleep(1);
+        EXPECT_TRUE(vibrator->off().isOk());
     }
 }
 
@@ -417,6 +418,9 @@
 
             if (isPrimitiveSupported) {
                 EXPECT_EQ(Status::EX_NONE, status.exceptionCode());
+                if (primitive != CompositePrimitive::NOOP) {
+                    ASSERT_GT(duration, 0) << toString(primitive) << " " << duration;
+                }
             } else {
                 EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
             }
@@ -756,7 +760,9 @@
     std::future<void> completionFuture{completionPromise.get_future()};
     sp<CompletionCallback> callback =
         new CompletionCallback([&completionPromise] { completionPromise.set_value(); });
-    uint32_t durationMs = 2100;  // Sum of 2 active and 1 braking below
+    int32_t segmentDurationMaxMs;
+    vibrator->getPwlePrimitiveDurationMax(&segmentDurationMaxMs);
+    uint32_t durationMs = segmentDurationMaxMs * 2 + 100;  // Sum of 2 active and 1 braking below
     //TODO(b/187207798): revert back to conservative timeout values once
     //latencies have been fixed
     std::chrono::milliseconds timeout{durationMs * 4};
@@ -860,7 +866,7 @@
     if (capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS) {
         ActivePwle active = composeValidActivePwle(vibrator, capabilities);
 
-        int segmentDurationMaxMs;
+        int32_t segmentDurationMaxMs;
         vibrator->getPwlePrimitiveDurationMax(&segmentDurationMaxMs);
         active.duration = segmentDurationMaxMs + 10;  // Segment duration greater than allowed
 
diff --git a/weaver/aidl/Android.bp b/weaver/aidl/Android.bp
index 8b4306f..caa92aa 100644
--- a/weaver/aidl/Android.bp
+++ b/weaver/aidl/Android.bp
@@ -16,11 +16,6 @@
         java: {
             platform_apis: true,
         },
-        ndk: {
-            vndk: {
-                enabled: true,
-            },
-        },
     },
     versions: ["1"],
 }
diff --git a/wifi/1.4/vts/functional/Android.bp b/wifi/1.4/vts/functional/Android.bp
index f86869b..cac8c0b 100644
--- a/wifi/1.4/vts/functional/Android.bp
+++ b/wifi/1.4/vts/functional/Android.bp
@@ -44,6 +44,27 @@
     ],
 }
 
+cc_library_static {
+    name: "VtsHalWifiV1_4TargetTestUtil",
+    defaults: ["VtsHalTargetTestDefaults"],
+    srcs: [
+        "wifi_hidl_test_utils_1_4.cpp",
+    ],
+    export_include_dirs: [
+        ".",
+    ],
+    shared_libs: [
+        "libnativehelper",
+    ],
+    static_libs: [
+        "VtsHalWifiV1_0TargetTestUtil",
+        "android.hardware.wifi@1.0",
+        "android.hardware.wifi@1.3",
+        "android.hardware.wifi@1.4",
+        "libwifi-system-iface",
+    ],
+}
+
 // SoftAP-specific tests, similar to VtsHalWifiApV1_0TargetTest.
 cc_test {
     name: "VtsHalWifiApV1_4TargetTest",
diff --git a/wifi/1.4/vts/functional/wifi_hidl_test_utils_1_4.cpp b/wifi/1.4/vts/functional/wifi_hidl_test_utils_1_4.cpp
new file mode 100644
index 0000000..02e8320
--- /dev/null
+++ b/wifi/1.4/vts/functional/wifi_hidl_test_utils_1_4.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 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 <VtsHalHidlTargetCallbackBase.h>
+#include <android-base/logging.h>
+
+#undef NAN  // NAN is defined in bionic/libc/include/math.h:38
+
+#include <android/hardware/wifi/1.4/IWifi.h>
+#include <android/hardware/wifi/1.4/IWifiApIface.h>
+#include <android/hardware/wifi/1.4/IWifiChip.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
+
+#include "wifi_hidl_call_util.h"
+#include "wifi_hidl_test_utils.h"
+
+using ::android::sp;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::wifi::V1_0::ChipModeId;
+using ::android::hardware::wifi::V1_0::IfaceType;
+using ::android::hardware::wifi::V1_4::IWifiApIface;
+using ::android::hardware::wifi::V1_4::IWifiChip;
+
+sp<IWifiChip> getWifiChip_1_4(const std::string& instance_name) {
+    return IWifiChip::castFrom(getWifiChip(instance_name));
+}
+
+sp<IWifiApIface> getWifiApIface_1_4(const std::string& instance_name) {
+    LOG(INFO) << "getWifiApIface_1_4";
+    ChipModeId mode_id;
+    sp<IWifiChip> wifi_chip_ = getWifiChip_1_4(instance_name);
+    configureChipToSupportIfaceType(wifi_chip_, IfaceType::AP, &mode_id);
+    const auto& status_and_iface = HIDL_INVOKE(wifi_chip_, createApIface);
+    LOG(INFO) << "getWifiApIface_1_4 done to status_and_iface";
+    return IWifiApIface::castFrom(status_and_iface.second);
+}
diff --git a/wifi/1.4/vts/functional/wifi_hidl_test_utils_1_4.h b/wifi/1.4/vts/functional/wifi_hidl_test_utils_1_4.h
new file mode 100644
index 0000000..ca7b57a
--- /dev/null
+++ b/wifi/1.4/vts/functional/wifi_hidl_test_utils_1_4.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/hardware/wifi/1.4/IWifi.h>
+#include <android/hardware/wifi/1.4/IWifiApIface.h>
+#include <android/hardware/wifi/1.4/IWifiChip.h>
+
+#include <getopt.h>
+
+#include <VtsHalHidlTargetTestEnvBase.h>
+// Helper functions to obtain references to the various HIDL interface objects.
+// Note: We only have a single instance of each of these objects currently.
+// These helper functions should be modified to return vectors if we support
+// multiple instances.
+android::sp<android::hardware::wifi::V1_4::IWifiChip> getWifiChip_1_4(
+    const std::string& instance_name);
+android::sp<android::hardware::wifi::V1_4::IWifiApIface> getWifiApIface_1_4(
+    const std::string& instance_name);
diff --git a/wifi/aidl/Android.bp b/wifi/aidl/Android.bp
new file mode 100644
index 0000000..c0ca667
--- /dev/null
+++ b/wifi/aidl/Android.bp
@@ -0,0 +1,44 @@
+// Copyright (C) 2022 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 {
+    // 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"],
+}
+
+aidl_interface {
+    name: "android.hardware.wifi",
+    vendor_available: true,
+    srcs: [
+        "android/hardware/wifi/*.aidl",
+    ],
+    stability: "vintf",
+    backend: {
+        java: {
+            sdk_version: "module_current",
+            apex_available: [
+                "//apex_available:platform",
+                "com.android.wifi",
+            ],
+            min_sdk_version: "30",
+            lint: {
+                enabled: false,
+            },
+        },
+    },
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifi.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifi.aidl
new file mode 100644
index 0000000..cc995fc
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifi.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+interface IWifi {
+  @PropagateAllowBlocking android.hardware.wifi.IWifiChip getChip(int chipId);
+  int[] getChipIds();
+  boolean isStarted();
+  void registerEventCallback(in android.hardware.wifi.IWifiEventCallback callback);
+  void start();
+  void stop();
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiApIface.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiApIface.aidl
new file mode 100644
index 0000000..a102b97
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiApIface.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+interface IWifiApIface {
+  String getName();
+  String[] getBridgedInstances();
+  byte[6] getFactoryMacAddress();
+  void setCountryCode(in byte[2] code);
+  int[] getValidFrequenciesForBand(in android.hardware.wifi.WifiBand band);
+  void resetToFactoryMacAddress();
+  void setMacAddress(in byte[6] mac);
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiChip.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiChip.aidl
new file mode 100644
index 0000000..647891f
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiChip.aidl
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+interface IWifiChip {
+  void configureChip(in int modeId);
+  @PropagateAllowBlocking android.hardware.wifi.IWifiApIface createApIface();
+  @PropagateAllowBlocking android.hardware.wifi.IWifiApIface createBridgedApIface();
+  @PropagateAllowBlocking android.hardware.wifi.IWifiNanIface createNanIface();
+  @PropagateAllowBlocking android.hardware.wifi.IWifiP2pIface createP2pIface();
+  @PropagateAllowBlocking android.hardware.wifi.IWifiRttController createRttController(in android.hardware.wifi.IWifiStaIface boundIface);
+  @PropagateAllowBlocking android.hardware.wifi.IWifiStaIface createStaIface();
+  void enableDebugErrorAlerts(in boolean enable);
+  void flushRingBufferToFile();
+  void forceDumpToDebugRingBuffer(in String ringName);
+  @PropagateAllowBlocking android.hardware.wifi.IWifiApIface getApIface(in String ifname);
+  String[] getApIfaceNames();
+  android.hardware.wifi.IWifiChip.ChipMode[] getAvailableModes();
+  android.hardware.wifi.IWifiChip.ChipCapabilityMask getCapabilities();
+  android.hardware.wifi.WifiDebugHostWakeReasonStats getDebugHostWakeReasonStats();
+  android.hardware.wifi.WifiDebugRingBufferStatus[] getDebugRingBuffersStatus();
+  int getId();
+  int getMode();
+  @PropagateAllowBlocking android.hardware.wifi.IWifiNanIface getNanIface(in String ifname);
+  String[] getNanIfaceNames();
+  @PropagateAllowBlocking android.hardware.wifi.IWifiP2pIface getP2pIface(in String ifname);
+  String[] getP2pIfaceNames();
+  @PropagateAllowBlocking android.hardware.wifi.IWifiStaIface getStaIface(in String ifname);
+  String[] getStaIfaceNames();
+  android.hardware.wifi.WifiRadioCombinationMatrix getSupportedRadioCombinationsMatrix();
+  android.hardware.wifi.WifiUsableChannel[] getUsableChannels(in android.hardware.wifi.WifiBand band, in android.hardware.wifi.WifiIfaceMode ifaceModeMask, in android.hardware.wifi.IWifiChip.UsableChannelFilter filterMask);
+  void registerEventCallback(in android.hardware.wifi.IWifiChipEventCallback callback);
+  void removeApIface(in String ifname);
+  void removeIfaceInstanceFromBridgedApIface(in String brIfaceName, in String ifaceInstanceName);
+  void removeNanIface(in String ifname);
+  void removeP2pIface(in String ifname);
+  void removeStaIface(in String ifname);
+  android.hardware.wifi.IWifiChip.ChipDebugInfo requestChipDebugInfo();
+  byte[] requestDriverDebugDump();
+  byte[] requestFirmwareDebugDump();
+  void resetTxPowerScenario();
+  void selectTxPowerScenario(in android.hardware.wifi.IWifiChip.TxPowerScenario scenario);
+  void setCoexUnsafeChannels(in android.hardware.wifi.IWifiChip.CoexUnsafeChannel[] unsafeChannels, in android.hardware.wifi.IWifiChip.CoexRestriction restrictions);
+  void setCountryCode(in byte[2] code);
+  void setLatencyMode(in android.hardware.wifi.IWifiChip.LatencyMode mode);
+  void setMultiStaPrimaryConnection(in String ifName);
+  void setMultiStaUseCase(in android.hardware.wifi.IWifiChip.MultiStaUseCase useCase);
+  void startLoggingToDebugRingBuffer(in String ringName, in android.hardware.wifi.WifiDebugRingBufferVerboseLevel verboseLevel, in int maxIntervalInSec, in int minDataSizeInBytes);
+  void stopLoggingToDebugRingBuffer();
+  void triggerSubsystemRestart();
+  const int NO_POWER_CAP_CONSTANT = 2147483647;
+  @Backing(type="int") @VintfStability
+  enum ChipCapabilityMask {
+    DEBUG_MEMORY_FIRMWARE_DUMP = 1,
+    DEBUG_MEMORY_DRIVER_DUMP = 2,
+    DEBUG_RING_BUFFER_CONNECT_EVENT = 4,
+    DEBUG_RING_BUFFER_POWER_EVENT = 8,
+    DEBUG_RING_BUFFER_WAKELOCK_EVENT = 16,
+    DEBUG_RING_BUFFER_VENDOR_DATA = 32,
+    DEBUG_HOST_WAKE_REASON_STATS = 64,
+    DEBUG_ERROR_ALERTS = 128,
+    SET_TX_POWER_LIMIT = 256,
+    D2D_RTT = 512,
+    D2AP_RTT = 1024,
+    USE_BODY_HEAD_SAR = 2048,
+    SET_LATENCY_MODE = 4096,
+    P2P_RAND_MAC = 8192,
+    WIGIG = 16384,
+  }
+  @VintfStability
+  parcelable ChipConcurrencyCombinationLimit {
+    android.hardware.wifi.IfaceConcurrencyType[] types;
+    int maxIfaces;
+  }
+  @VintfStability
+  parcelable ChipConcurrencyCombination {
+    android.hardware.wifi.IWifiChip.ChipConcurrencyCombinationLimit[] limits;
+  }
+  @VintfStability
+  parcelable ChipDebugInfo {
+    String driverDescription;
+    String firmwareDescription;
+  }
+  @VintfStability
+  parcelable ChipIfaceCombinationLimit {
+    android.hardware.wifi.IfaceType[] types;
+    int maxIfaces;
+  }
+  @VintfStability
+  parcelable ChipIfaceCombination {
+    android.hardware.wifi.IWifiChip.ChipIfaceCombinationLimit[] limits;
+  }
+  @VintfStability
+  parcelable ChipMode {
+    int id;
+    android.hardware.wifi.IWifiChip.ChipConcurrencyCombination[] availableCombinations;
+  }
+  @Backing(type="int") @VintfStability
+  enum CoexRestriction {
+    WIFI_DIRECT = 1,
+    SOFTAP = 2,
+    WIFI_AWARE = 4,
+  }
+  @VintfStability
+  parcelable CoexUnsafeChannel {
+    android.hardware.wifi.WifiBand band;
+    int channel;
+    int powerCapDbm;
+  }
+  @Backing(type="int") @VintfStability
+  enum LatencyMode {
+    NORMAL = 0,
+    LOW = 1,
+  }
+  @Backing(type="byte") @VintfStability
+  enum MultiStaUseCase {
+    DUAL_STA_TRANSIENT_PREFER_PRIMARY = 0,
+    DUAL_STA_NON_TRANSIENT_UNBIASED = 1,
+  }
+  @Backing(type="int") @VintfStability
+  enum TxPowerScenario {
+    VOICE_CALL = 0,
+    ON_HEAD_CELL_OFF = 1,
+    ON_HEAD_CELL_ON = 2,
+    ON_BODY_CELL_OFF = 3,
+    ON_BODY_CELL_ON = 4,
+  }
+  @Backing(type="int") @VintfStability
+  enum UsableChannelFilter {
+    CELLULAR_COEXISTENCE = 1,
+    CONCURRENCY = 2,
+    NAN_INSTANT_MODE = 4,
+  }
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiChipEventCallback.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiChipEventCallback.aidl
new file mode 100644
index 0000000..3fd8533
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiChipEventCallback.aidl
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+interface IWifiChipEventCallback {
+  oneway void onChipReconfigureFailure(in android.hardware.wifi.WifiStatusCode status);
+  oneway void onChipReconfigured(in int modeId);
+  oneway void onDebugErrorAlert(in int errorCode, in byte[] debugData);
+  oneway void onDebugRingBufferDataAvailable(in android.hardware.wifi.WifiDebugRingBufferStatus status, in byte[] data);
+  oneway void onIfaceAdded(in android.hardware.wifi.IfaceType type, in String name);
+  oneway void onIfaceRemoved(in android.hardware.wifi.IfaceType type, in String name);
+  oneway void onRadioModeChange(in android.hardware.wifi.IWifiChipEventCallback.RadioModeInfo[] radioModeInfos);
+  @VintfStability
+  parcelable IfaceInfo {
+    String name;
+    int channel;
+  }
+  @VintfStability
+  parcelable RadioModeInfo {
+    int radioId;
+    android.hardware.wifi.WifiBand bandInfo;
+    android.hardware.wifi.IWifiChipEventCallback.IfaceInfo[] ifaceInfos;
+  }
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiEventCallback.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiEventCallback.aidl
new file mode 100644
index 0000000..00e5cb6
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiEventCallback.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+interface IWifiEventCallback {
+  oneway void onFailure(in android.hardware.wifi.WifiStatusCode status);
+  oneway void onStart();
+  oneway void onStop();
+  oneway void onSubsystemRestart(in android.hardware.wifi.WifiStatusCode status);
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiNanIface.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiNanIface.aidl
new file mode 100644
index 0000000..070ca24
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiNanIface.aidl
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+interface IWifiNanIface {
+  String getName();
+  void configRequest(in char cmdId, in android.hardware.wifi.NanConfigRequest msg1, in android.hardware.wifi.NanConfigRequestSupplemental msg2);
+  void createDataInterfaceRequest(in char cmdId, in String ifaceName);
+  void deleteDataInterfaceRequest(in char cmdId, in String ifaceName);
+  void disableRequest(in char cmdId);
+  void enableRequest(in char cmdId, in android.hardware.wifi.NanEnableRequest msg1, in android.hardware.wifi.NanConfigRequestSupplemental msg2);
+  void getCapabilitiesRequest(in char cmdId);
+  void initiateDataPathRequest(in char cmdId, in android.hardware.wifi.NanInitiateDataPathRequest msg);
+  void registerEventCallback(in android.hardware.wifi.IWifiNanIfaceEventCallback callback);
+  void respondToDataPathIndicationRequest(in char cmdId, in android.hardware.wifi.NanRespondToDataPathIndicationRequest msg);
+  void startPublishRequest(in char cmdId, in android.hardware.wifi.NanPublishRequest msg);
+  void startSubscribeRequest(in char cmdId, in android.hardware.wifi.NanSubscribeRequest msg);
+  void stopPublishRequest(in char cmdId, in byte sessionId);
+  void stopSubscribeRequest(in char cmdId, in byte sessionId);
+  void terminateDataPathRequest(in char cmdId, in int ndpInstanceId);
+  void transmitFollowupRequest(in char cmdId, in android.hardware.wifi.NanTransmitFollowupRequest msg);
+  const int MIN_DATA_PATH_CONFIG_PASSPHRASE_LENGTH = 8;
+  const int MAX_DATA_PATH_CONFIG_PASSPHRASE_LENGTH = 63;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiNanIfaceEventCallback.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiNanIfaceEventCallback.aidl
new file mode 100644
index 0000000..591cd8c
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiNanIfaceEventCallback.aidl
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+interface IWifiNanIfaceEventCallback {
+  oneway void eventClusterEvent(in android.hardware.wifi.NanClusterEventInd event);
+  oneway void eventDataPathConfirm(in android.hardware.wifi.NanDataPathConfirmInd event);
+  oneway void eventDataPathRequest(in android.hardware.wifi.NanDataPathRequestInd event);
+  oneway void eventDataPathScheduleUpdate(in android.hardware.wifi.NanDataPathScheduleUpdateInd event);
+  oneway void eventDataPathTerminated(in int ndpInstanceId);
+  oneway void eventDisabled(in android.hardware.wifi.NanStatus status);
+  oneway void eventFollowupReceived(in android.hardware.wifi.NanFollowupReceivedInd event);
+  oneway void eventMatch(in android.hardware.wifi.NanMatchInd event);
+  oneway void eventMatchExpired(in byte discoverySessionId, in int peerId);
+  oneway void eventPublishTerminated(in byte sessionId, in android.hardware.wifi.NanStatus status);
+  oneway void eventSubscribeTerminated(in byte sessionId, in android.hardware.wifi.NanStatus status);
+  oneway void eventTransmitFollowup(in char id, in android.hardware.wifi.NanStatus status);
+  oneway void notifyCapabilitiesResponse(in char id, in android.hardware.wifi.NanStatus status, in android.hardware.wifi.NanCapabilities capabilities);
+  oneway void notifyConfigResponse(in char id, in android.hardware.wifi.NanStatus status);
+  oneway void notifyCreateDataInterfaceResponse(in char id, in android.hardware.wifi.NanStatus status);
+  oneway void notifyDeleteDataInterfaceResponse(in char id, in android.hardware.wifi.NanStatus status);
+  oneway void notifyDisableResponse(in char id, in android.hardware.wifi.NanStatus status);
+  oneway void notifyEnableResponse(in char id, in android.hardware.wifi.NanStatus status);
+  oneway void notifyInitiateDataPathResponse(in char id, in android.hardware.wifi.NanStatus status, in int ndpInstanceId);
+  oneway void notifyRespondToDataPathIndicationResponse(in char id, in android.hardware.wifi.NanStatus status);
+  oneway void notifyStartPublishResponse(in char id, in android.hardware.wifi.NanStatus status, in byte sessionId);
+  oneway void notifyStartSubscribeResponse(in char id, in android.hardware.wifi.NanStatus status, in byte sessionId);
+  oneway void notifyStopPublishResponse(in char id, in android.hardware.wifi.NanStatus status);
+  oneway void notifyStopSubscribeResponse(in char id, in android.hardware.wifi.NanStatus status);
+  oneway void notifyTerminateDataPathResponse(in char id, in android.hardware.wifi.NanStatus status);
+  oneway void notifyTransmitFollowupResponse(in char id, in android.hardware.wifi.NanStatus status);
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiP2pIface.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiP2pIface.aidl
new file mode 100644
index 0000000..5e9948e
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiP2pIface.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+interface IWifiP2pIface {
+  String getName();
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiRttController.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiRttController.aidl
new file mode 100644
index 0000000..730a055
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiRttController.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+interface IWifiRttController {
+  void disableResponder(in int cmdId);
+  void enableResponder(in int cmdId, in android.hardware.wifi.WifiChannelInfo channelHint, in int maxDurationInSeconds, in android.hardware.wifi.RttResponder info);
+  android.hardware.wifi.IWifiStaIface getBoundIface();
+  android.hardware.wifi.RttCapabilities getCapabilities();
+  android.hardware.wifi.RttResponder getResponderInfo();
+  void rangeCancel(in int cmdId, in android.hardware.wifi.MacAddress[] addrs);
+  void rangeRequest(in int cmdId, in android.hardware.wifi.RttConfig[] rttConfigs);
+  void registerEventCallback(in android.hardware.wifi.IWifiRttControllerEventCallback callback);
+  void setLci(in int cmdId, in android.hardware.wifi.RttLciInformation lci);
+  void setLcr(in int cmdId, in android.hardware.wifi.RttLcrInformation lcr);
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiRttControllerEventCallback.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiRttControllerEventCallback.aidl
new file mode 100644
index 0000000..a6a33fc
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiRttControllerEventCallback.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+interface IWifiRttControllerEventCallback {
+  oneway void onResults(in int cmdId, in android.hardware.wifi.RttResult[] results);
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiStaIface.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiStaIface.aidl
new file mode 100644
index 0000000..2f0dfa1
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiStaIface.aidl
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+interface IWifiStaIface {
+  String getName();
+  void configureRoaming(in android.hardware.wifi.StaRoamingConfig config);
+  void disableLinkLayerStatsCollection();
+  void enableLinkLayerStatsCollection(in boolean debug);
+  void enableNdOffload(in boolean enable);
+  android.hardware.wifi.StaApfPacketFilterCapabilities getApfPacketFilterCapabilities();
+  android.hardware.wifi.StaBackgroundScanCapabilities getBackgroundScanCapabilities();
+  android.hardware.wifi.IWifiStaIface.StaIfaceCapabilityMask getCapabilities();
+  android.hardware.wifi.WifiDebugRxPacketFateReport[] getDebugRxPacketFates();
+  android.hardware.wifi.WifiDebugTxPacketFateReport[] getDebugTxPacketFates();
+  byte[6] getFactoryMacAddress();
+  android.hardware.wifi.StaLinkLayerStats getLinkLayerStats();
+  android.hardware.wifi.StaRoamingCapabilities getRoamingCapabilities();
+  int[] getValidFrequenciesForBand(in android.hardware.wifi.WifiBand band);
+  void installApfPacketFilter(in byte[] program);
+  byte[] readApfPacketFilterData();
+  void registerEventCallback(in android.hardware.wifi.IWifiStaIfaceEventCallback callback);
+  void setMacAddress(in byte[6] mac);
+  void setRoamingState(in android.hardware.wifi.StaRoamingState state);
+  void setScanMode(in boolean enable);
+  void startBackgroundScan(in int cmdId, in android.hardware.wifi.StaBackgroundScanParameters params);
+  void startDebugPacketFateMonitoring();
+  void startRssiMonitoring(in int cmdId, in int maxRssi, in int minRssi);
+  void startSendingKeepAlivePackets(in int cmdId, in byte[] ipPacketData, in char etherType, in byte[6] srcAddress, in byte[6] dstAddress, in int periodInMs);
+  void stopBackgroundScan(in int cmdId);
+  void stopRssiMonitoring(in int cmdId);
+  void stopSendingKeepAlivePackets(in int cmdId);
+  @Backing(type="int") @VintfStability
+  enum StaIfaceCapabilityMask {
+    APF = 1,
+    BACKGROUND_SCAN = 2,
+    LINK_LAYER_STATS = 4,
+    RSSI_MONITOR = 8,
+    CONTROL_ROAMING = 16,
+    PROBE_IE_ALLOWLIST = 32,
+    SCAN_RAND = 64,
+    STA_5G = 128,
+    HOTSPOT = 256,
+    PNO = 512,
+    TDLS = 1024,
+    TDLS_OFFCHANNEL = 2048,
+    ND_OFFLOAD = 4096,
+    KEEP_ALIVE = 8192,
+    DEBUG_PACKET_FATE = 16384,
+  }
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiStaIfaceEventCallback.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiStaIfaceEventCallback.aidl
new file mode 100644
index 0000000..48b85b0
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiStaIfaceEventCallback.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+interface IWifiStaIfaceEventCallback {
+  oneway void onBackgroundFullScanResult(in int cmdId, in int bucketsScanned, in android.hardware.wifi.StaScanResult result);
+  oneway void onBackgroundScanFailure(in int cmdId);
+  oneway void onBackgroundScanResults(in int cmdId, in android.hardware.wifi.StaScanData[] scanDatas);
+  oneway void onRssiThresholdBreached(in int cmdId, in byte[6] currBssid, in int currRssi);
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IfaceConcurrencyType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IfaceConcurrencyType.aidl
new file mode 100644
index 0000000..0a3ad1a
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IfaceConcurrencyType.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum IfaceConcurrencyType {
+  STA = 0,
+  AP = 1,
+  AP_BRIDGED = 2,
+  P2P = 3,
+  NAN_IFACE = 4,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IfaceType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IfaceType.aidl
new file mode 100644
index 0000000..dbdc439
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IfaceType.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum IfaceType {
+  STA = 0,
+  AP = 1,
+  P2P = 2,
+  NAN_IFACE = 3,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/MacAddress.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/MacAddress.aidl
new file mode 100644
index 0000000..c4a0613
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/MacAddress.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable MacAddress {
+  byte[6] data;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBandIndex.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBandIndex.aidl
new file mode 100644
index 0000000..ca6c910
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBandIndex.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum NanBandIndex {
+  NAN_BAND_24GHZ = 0,
+  NAN_BAND_5GHZ = 1,
+  NAN_BAND_6GHZ = 2,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBandSpecificConfig.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBandSpecificConfig.aidl
new file mode 100644
index 0000000..57540b3
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBandSpecificConfig.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanBandSpecificConfig {
+  byte rssiClose;
+  byte rssiMiddle;
+  byte rssiCloseProximity;
+  char dwellTimeMs;
+  char scanPeriodSec;
+  boolean validDiscoveryWindowIntervalVal;
+  byte discoveryWindowIntervalVal;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanCapabilities.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanCapabilities.aidl
new file mode 100644
index 0000000..c44654e
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanCapabilities.aidl
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanCapabilities {
+  int maxConcurrentClusters;
+  int maxPublishes;
+  int maxSubscribes;
+  int maxServiceNameLen;
+  int maxMatchFilterLen;
+  int maxTotalMatchFilterLen;
+  int maxServiceSpecificInfoLen;
+  int maxExtendedServiceSpecificInfoLen;
+  int maxNdiInterfaces;
+  int maxNdpSessions;
+  int maxAppInfoLen;
+  int maxQueuedTransmitFollowupMsgs;
+  int maxSubscribeInterfaceAddresses;
+  android.hardware.wifi.NanCipherSuiteType supportedCipherSuites;
+  boolean instantCommunicationModeSupportFlag;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanCipherSuiteType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanCipherSuiteType.aidl
new file mode 100644
index 0000000..4450956
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanCipherSuiteType.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum NanCipherSuiteType {
+  NONE = 0,
+  SHARED_KEY_128_MASK = 1,
+  SHARED_KEY_256_MASK = 2,
+  PUBLIC_KEY_128_MASK = 4,
+  PUBLIC_KEY_256_MASK = 8,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanClusterEventInd.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanClusterEventInd.aidl
new file mode 100644
index 0000000..7a3ff81
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanClusterEventInd.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanClusterEventInd {
+  android.hardware.wifi.NanClusterEventType eventType;
+  byte[6] addr;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanClusterEventType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanClusterEventType.aidl
new file mode 100644
index 0000000..1dfa45f
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanClusterEventType.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum NanClusterEventType {
+  DISCOVERY_MAC_ADDRESS_CHANGED = 0,
+  STARTED_CLUSTER = 1,
+  JOINED_CLUSTER = 2,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanConfigRequest.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanConfigRequest.aidl
new file mode 100644
index 0000000..5ead651
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanConfigRequest.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanConfigRequest {
+  byte masterPref;
+  boolean disableDiscoveryAddressChangeIndication;
+  boolean disableStartedClusterIndication;
+  boolean disableJoinedClusterIndication;
+  boolean includePublishServiceIdsInBeacon;
+  byte numberOfPublishServiceIdsInBeacon;
+  boolean includeSubscribeServiceIdsInBeacon;
+  byte numberOfSubscribeServiceIdsInBeacon;
+  char rssiWindowSize;
+  int macAddressRandomizationIntervalSec;
+  android.hardware.wifi.NanBandSpecificConfig[3] bandSpecificConfig;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanConfigRequestSupplemental.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanConfigRequestSupplemental.aidl
new file mode 100644
index 0000000..682699e
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanConfigRequestSupplemental.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanConfigRequestSupplemental {
+  int discoveryBeaconIntervalMs;
+  int numberOfSpatialStreamsInDiscovery;
+  boolean enableDiscoveryWindowEarlyTermination;
+  boolean enableRanging;
+  boolean enableInstantCommunicationMode;
+  int instantModeChannel;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathChannelCfg.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathChannelCfg.aidl
new file mode 100644
index 0000000..ce75288
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathChannelCfg.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum NanDataPathChannelCfg {
+  CHANNEL_NOT_REQUESTED = 0,
+  REQUEST_CHANNEL_SETUP = 1,
+  FORCE_CHANNEL_SETUP = 2,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathChannelInfo.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathChannelInfo.aidl
new file mode 100644
index 0000000..d111db7
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathChannelInfo.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanDataPathChannelInfo {
+  int channelFreq;
+  android.hardware.wifi.WifiChannelWidthInMhz channelBandwidth;
+  int numSpatialStreams;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathConfirmInd.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathConfirmInd.aidl
new file mode 100644
index 0000000..2e1e2ca
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathConfirmInd.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanDataPathConfirmInd {
+  int ndpInstanceId;
+  boolean dataPathSetupSuccess;
+  byte[6] peerNdiMacAddr;
+  byte[] appInfo;
+  android.hardware.wifi.NanStatus status;
+  android.hardware.wifi.NanDataPathChannelInfo[] channelInfo;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathRequestInd.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathRequestInd.aidl
new file mode 100644
index 0000000..74d5b73
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathRequestInd.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanDataPathRequestInd {
+  byte discoverySessionId;
+  byte[6] peerDiscMacAddr;
+  int ndpInstanceId;
+  boolean securityRequired;
+  byte[] appInfo;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathScheduleUpdateInd.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathScheduleUpdateInd.aidl
new file mode 100644
index 0000000..5fabf55
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathScheduleUpdateInd.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanDataPathScheduleUpdateInd {
+  byte[6] peerDiscoveryAddress;
+  android.hardware.wifi.NanDataPathChannelInfo[] channelInfo;
+  int[] ndpInstanceIds;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathSecurityConfig.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathSecurityConfig.aidl
new file mode 100644
index 0000000..635dbce
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathSecurityConfig.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanDataPathSecurityConfig {
+  android.hardware.wifi.NanDataPathSecurityType securityType;
+  android.hardware.wifi.NanCipherSuiteType cipherType;
+  byte[32] pmk;
+  byte[] passphrase;
+  byte[16] scid;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathSecurityType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathSecurityType.aidl
new file mode 100644
index 0000000..64288ca
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathSecurityType.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum NanDataPathSecurityType {
+  OPEN = 0,
+  PMK = 1,
+  PASSPHRASE = 2,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDebugConfig.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDebugConfig.aidl
new file mode 100644
index 0000000..b84d891
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDebugConfig.aidl
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanDebugConfig {
+  boolean validClusterIdVals;
+  char clusterIdBottomRangeVal;
+  char clusterIdTopRangeVal;
+  boolean validIntfAddrVal;
+  byte[6] intfAddrVal;
+  boolean validOuiVal;
+  int ouiVal;
+  boolean validRandomFactorForceVal;
+  byte randomFactorForceVal;
+  boolean validHopCountForceVal;
+  byte hopCountForceVal;
+  boolean validDiscoveryChannelVal;
+  int[3] discoveryChannelMhzVal;
+  boolean validUseBeaconsInBandVal;
+  boolean[3] useBeaconsInBandVal;
+  boolean validUseSdfInBandVal;
+  boolean[3] useSdfInBandVal;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDiscoveryCommonConfig.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDiscoveryCommonConfig.aidl
new file mode 100644
index 0000000..761cdbb
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDiscoveryCommonConfig.aidl
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanDiscoveryCommonConfig {
+  byte sessionId;
+  char ttlSec;
+  char discoveryWindowPeriod;
+  byte discoveryCount;
+  byte[] serviceName;
+  android.hardware.wifi.NanMatchAlg discoveryMatchIndicator;
+  byte[] serviceSpecificInfo;
+  byte[] extendedServiceSpecificInfo;
+  byte[] rxMatchFilter;
+  byte[] txMatchFilter;
+  boolean useRssiThreshold;
+  boolean disableDiscoveryTerminationIndication;
+  boolean disableMatchExpirationIndication;
+  boolean disableFollowupReceivedIndication;
+  android.hardware.wifi.NanDataPathSecurityConfig securityConfig;
+  boolean rangingRequired;
+  int rangingIntervalMs;
+  android.hardware.wifi.NanRangingIndication configRangingIndications;
+  char distanceIngressCm;
+  char distanceEgressCm;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanEnableRequest.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanEnableRequest.aidl
new file mode 100644
index 0000000..eaa009c
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanEnableRequest.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanEnableRequest {
+  boolean[3] operateInBand;
+  byte hopCountMax;
+  android.hardware.wifi.NanConfigRequest configParams;
+  android.hardware.wifi.NanDebugConfig debugConfigs;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanFollowupReceivedInd.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanFollowupReceivedInd.aidl
new file mode 100644
index 0000000..743ad9d
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanFollowupReceivedInd.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanFollowupReceivedInd {
+  byte discoverySessionId;
+  int peerId;
+  byte[6] addr;
+  boolean receivedInFaw;
+  byte[] serviceSpecificInfo;
+  byte[] extendedServiceSpecificInfo;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanInitiateDataPathRequest.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanInitiateDataPathRequest.aidl
new file mode 100644
index 0000000..697e29a
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanInitiateDataPathRequest.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanInitiateDataPathRequest {
+  int peerId;
+  byte[6] peerDiscMacAddr;
+  android.hardware.wifi.NanDataPathChannelCfg channelRequestType;
+  int channel;
+  String ifaceName;
+  android.hardware.wifi.NanDataPathSecurityConfig securityConfig;
+  byte[] appInfo;
+  byte[] serviceNameOutOfBand;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanMatchAlg.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanMatchAlg.aidl
new file mode 100644
index 0000000..dab33ad
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanMatchAlg.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum NanMatchAlg {
+  MATCH_ONCE = 0,
+  MATCH_CONTINUOUS = 1,
+  MATCH_NEVER = 2,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanMatchInd.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanMatchInd.aidl
new file mode 100644
index 0000000..ae430c4
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanMatchInd.aidl
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanMatchInd {
+  byte discoverySessionId;
+  int peerId;
+  byte[6] addr;
+  byte[] serviceSpecificInfo;
+  byte[] extendedServiceSpecificInfo;
+  byte[] matchFilter;
+  boolean matchOccurredInBeaconFlag;
+  boolean outOfResourceFlag;
+  byte rssiValue;
+  android.hardware.wifi.NanCipherSuiteType peerCipherType;
+  boolean peerRequiresSecurityEnabledInNdp;
+  boolean peerRequiresRanging;
+  int rangingMeasurementInMm;
+  android.hardware.wifi.NanRangingIndication rangingIndicationType;
+  byte[] scid;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPublishRequest.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPublishRequest.aidl
new file mode 100644
index 0000000..d8d6b1b
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPublishRequest.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanPublishRequest {
+  android.hardware.wifi.NanDiscoveryCommonConfig baseConfigs;
+  android.hardware.wifi.NanPublishType publishType;
+  android.hardware.wifi.NanTxType txType;
+  boolean autoAcceptDataPathRequests;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPublishType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPublishType.aidl
new file mode 100644
index 0000000..fc9b7a0
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPublishType.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum NanPublishType {
+  UNSOLICITED = 0,
+  SOLICITED = 1,
+  UNSOLICITED_SOLICITED = 2,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanRangingIndication.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanRangingIndication.aidl
new file mode 100644
index 0000000..d03dffc
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanRangingIndication.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum NanRangingIndication {
+  CONTINUOUS_INDICATION_MASK = 1,
+  INGRESS_MET_MASK = 2,
+  EGRESS_MET_MASK = 4,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanRespondToDataPathIndicationRequest.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanRespondToDataPathIndicationRequest.aidl
new file mode 100644
index 0000000..5542ff6
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanRespondToDataPathIndicationRequest.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanRespondToDataPathIndicationRequest {
+  boolean acceptRequest;
+  int ndpInstanceId;
+  String ifaceName;
+  android.hardware.wifi.NanDataPathSecurityConfig securityConfig;
+  byte[] appInfo;
+  byte[] serviceNameOutOfBand;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanSrfType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanSrfType.aidl
new file mode 100644
index 0000000..3c0583c
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanSrfType.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum NanSrfType {
+  BLOOM_FILTER = 0,
+  PARTIAL_MAC_ADDR = 1,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanStatus.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanStatus.aidl
new file mode 100644
index 0000000..834558a
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanStatus.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanStatus {
+  android.hardware.wifi.NanStatusCode status;
+  String description;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanStatusCode.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanStatusCode.aidl
new file mode 100644
index 0000000..9eaf518
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanStatusCode.aidl
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum NanStatusCode {
+  SUCCESS = 0,
+  INTERNAL_FAILURE = 1,
+  PROTOCOL_FAILURE = 2,
+  INVALID_SESSION_ID = 3,
+  NO_RESOURCES_AVAILABLE = 4,
+  INVALID_ARGS = 5,
+  INVALID_PEER_ID = 6,
+  INVALID_NDP_ID = 7,
+  NAN_NOT_ALLOWED = 8,
+  NO_OTA_ACK = 9,
+  ALREADY_ENABLED = 10,
+  FOLLOWUP_TX_QUEUE_FULL = 11,
+  UNSUPPORTED_CONCURRENCY_NAN_DISABLED = 12,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanSubscribeRequest.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanSubscribeRequest.aidl
new file mode 100644
index 0000000..bf176a5
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanSubscribeRequest.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanSubscribeRequest {
+  android.hardware.wifi.NanDiscoveryCommonConfig baseConfigs;
+  android.hardware.wifi.NanSubscribeType subscribeType;
+  android.hardware.wifi.NanSrfType srfType;
+  boolean srfRespondIfInAddressSet;
+  boolean shouldUseSrf;
+  boolean isSsiRequiredForMatch;
+  android.hardware.wifi.MacAddress[] intfAddr;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanSubscribeType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanSubscribeType.aidl
new file mode 100644
index 0000000..325e40b
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanSubscribeType.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum NanSubscribeType {
+  PASSIVE = 0,
+  ACTIVE = 1,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanTransmitFollowupRequest.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanTransmitFollowupRequest.aidl
new file mode 100644
index 0000000..20c94d9
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanTransmitFollowupRequest.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable NanTransmitFollowupRequest {
+  byte discoverySessionId;
+  int peerId;
+  byte[6] addr;
+  boolean isHighPriority;
+  boolean shouldUseDiscoveryWindow;
+  byte[] serviceSpecificInfo;
+  byte[] extendedServiceSpecificInfo;
+  boolean disableFollowupResultIndication;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanTxType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanTxType.aidl
new file mode 100644
index 0000000..6f7696f
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanTxType.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum NanTxType {
+  BROADCAST = 0,
+  UNICAST = 1,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttBw.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttBw.aidl
new file mode 100644
index 0000000..bd7efff
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttBw.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum RttBw {
+  BW_5MHZ = 1,
+  BW_10MHZ = 2,
+  BW_20MHZ = 4,
+  BW_40MHZ = 8,
+  BW_80MHZ = 16,
+  BW_160MHZ = 32,
+  BW_320MHZ = 64,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttCapabilities.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttCapabilities.aidl
new file mode 100644
index 0000000..cf64687
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttCapabilities.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable RttCapabilities {
+  boolean rttOneSidedSupported;
+  boolean rttFtmSupported;
+  boolean lciSupported;
+  boolean lcrSupported;
+  boolean responderSupported;
+  android.hardware.wifi.RttPreamble preambleSupport;
+  android.hardware.wifi.RttBw bwSupport;
+  byte mcVersion;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttConfig.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttConfig.aidl
new file mode 100644
index 0000000..ccdf2ce
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttConfig.aidl
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable RttConfig {
+  byte[6] addr;
+  android.hardware.wifi.RttType type;
+  android.hardware.wifi.RttPeerType peer;
+  android.hardware.wifi.WifiChannelInfo channel;
+  int burstPeriod;
+  int numBurst;
+  int numFramesPerBurst;
+  int numRetriesPerRttFrame;
+  int numRetriesPerFtmr;
+  boolean mustRequestLci;
+  boolean mustRequestLcr;
+  int burstDuration;
+  android.hardware.wifi.RttPreamble preamble;
+  android.hardware.wifi.RttBw bw;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttLciInformation.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttLciInformation.aidl
new file mode 100644
index 0000000..0fcf151
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttLciInformation.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable RttLciInformation {
+  long latitude;
+  long longitude;
+  int altitude;
+  byte latitudeUnc;
+  byte longitudeUnc;
+  byte altitudeUnc;
+  android.hardware.wifi.RttMotionPattern motionPattern;
+  int floor;
+  int heightAboveFloor;
+  int heightUnc;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttLcrInformation.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttLcrInformation.aidl
new file mode 100644
index 0000000..c756dda
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttLcrInformation.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable RttLcrInformation {
+  byte[2] countryCode;
+  String civicInfo;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttMotionPattern.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttMotionPattern.aidl
new file mode 100644
index 0000000..7c8e369
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttMotionPattern.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum RttMotionPattern {
+  NOT_EXPECTED = 0,
+  EXPECTED = 1,
+  UNKNOWN = 2,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttPeerType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttPeerType.aidl
new file mode 100644
index 0000000..23fa7f6
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttPeerType.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum RttPeerType {
+  AP = 1,
+  STA = 2,
+  P2P_GO = 3,
+  P2P_CLIENT = 4,
+  NAN_TYPE = 5,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttPreamble.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttPreamble.aidl
new file mode 100644
index 0000000..02e6479
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttPreamble.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum RttPreamble {
+  LEGACY = 1,
+  HT = 2,
+  VHT = 4,
+  HE = 8,
+  EHT = 16,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttResponder.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttResponder.aidl
new file mode 100644
index 0000000..41463b5
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttResponder.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable RttResponder {
+  android.hardware.wifi.WifiChannelInfo channel;
+  android.hardware.wifi.RttPreamble preamble;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttResult.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttResult.aidl
new file mode 100644
index 0000000..743e0bd
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttResult.aidl
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable RttResult {
+  byte[6] addr;
+  int burstNum;
+  int measurementNumber;
+  int successNumber;
+  byte numberPerBurstPeer;
+  android.hardware.wifi.RttStatus status;
+  byte retryAfterDuration;
+  android.hardware.wifi.RttType type;
+  int rssi;
+  int rssiSpread;
+  android.hardware.wifi.WifiRateInfo txRate;
+  android.hardware.wifi.WifiRateInfo rxRate;
+  long rtt;
+  long rttSd;
+  long rttSpread;
+  int distanceInMm;
+  int distanceSdInMm;
+  int distanceSpreadInMm;
+  long timeStampInUs;
+  int burstDurationInMs;
+  int negotiatedBurstNum;
+  android.hardware.wifi.WifiInformationElement lci;
+  android.hardware.wifi.WifiInformationElement lcr;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttStatus.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttStatus.aidl
new file mode 100644
index 0000000..2817497
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttStatus.aidl
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum RttStatus {
+  SUCCESS = 0,
+  FAILURE = 1,
+  FAIL_NO_RSP = 2,
+  FAIL_REJECTED = 3,
+  FAIL_NOT_SCHEDULED_YET = 4,
+  FAIL_TM_TIMEOUT = 5,
+  FAIL_AP_ON_DIFF_CHANNEL = 6,
+  FAIL_NO_CAPABILITY = 7,
+  ABORTED = 8,
+  FAIL_INVALID_TS = 9,
+  FAIL_PROTOCOL = 10,
+  FAIL_SCHEDULE = 11,
+  FAIL_BUSY_TRY_LATER = 12,
+  INVALID_REQ = 13,
+  NO_WIFI = 14,
+  FAIL_FTM_PARAM_OVERRIDE = 15,
+  NAN_RANGING_PROTOCOL_FAILURE = 16,
+  NAN_RANGING_CONCURRENCY_NOT_SUPPORTED = 17,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttType.aidl
new file mode 100644
index 0000000..2b6087a
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttType.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum RttType {
+  ONE_SIDED = 1,
+  TWO_SIDED = 2,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/Ssid.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/Ssid.aidl
new file mode 100644
index 0000000..98b523f
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/Ssid.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable Ssid {
+  byte[32] data;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaApfPacketFilterCapabilities.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaApfPacketFilterCapabilities.aidl
new file mode 100644
index 0000000..3b4d785
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaApfPacketFilterCapabilities.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable StaApfPacketFilterCapabilities {
+  int version;
+  int maxLength;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaBackgroundScanBucketEventReportSchemeMask.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaBackgroundScanBucketEventReportSchemeMask.aidl
new file mode 100644
index 0000000..1041dd7
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaBackgroundScanBucketEventReportSchemeMask.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum StaBackgroundScanBucketEventReportSchemeMask {
+  EACH_SCAN = 1,
+  FULL_RESULTS = 2,
+  NO_BATCH = 4,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaBackgroundScanBucketParameters.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaBackgroundScanBucketParameters.aidl
new file mode 100644
index 0000000..b49d406
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaBackgroundScanBucketParameters.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable StaBackgroundScanBucketParameters {
+  int bucketIdx;
+  android.hardware.wifi.WifiBand band;
+  int[] frequencies;
+  int periodInMs;
+  android.hardware.wifi.StaBackgroundScanBucketEventReportSchemeMask eventReportScheme;
+  int exponentialMaxPeriodInMs;
+  int exponentialBase;
+  int exponentialStepCount;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaBackgroundScanCapabilities.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaBackgroundScanCapabilities.aidl
new file mode 100644
index 0000000..758dd97
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaBackgroundScanCapabilities.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable StaBackgroundScanCapabilities {
+  int maxCacheSize;
+  int maxBuckets;
+  int maxApCachePerScan;
+  int maxReportingThreshold;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaBackgroundScanLimits.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaBackgroundScanLimits.aidl
new file mode 100644
index 0000000..05d0277
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaBackgroundScanLimits.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum StaBackgroundScanLimits {
+  MAX_CHANNELS = 16,
+  MAX_BUCKETS = 16,
+  MAX_AP_CACHE_PER_SCAN = 32,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaBackgroundScanParameters.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaBackgroundScanParameters.aidl
new file mode 100644
index 0000000..0773566
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaBackgroundScanParameters.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable StaBackgroundScanParameters {
+  int basePeriodInMs;
+  int maxApPerScan;
+  int reportThresholdPercent;
+  int reportThresholdNumScans;
+  android.hardware.wifi.StaBackgroundScanBucketParameters[] buckets;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaLinkLayerIfaceContentionTimeStats.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaLinkLayerIfaceContentionTimeStats.aidl
new file mode 100644
index 0000000..4dee6de
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaLinkLayerIfaceContentionTimeStats.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable StaLinkLayerIfaceContentionTimeStats {
+  int contentionTimeMinInUsec;
+  int contentionTimeMaxInUsec;
+  int contentionTimeAvgInUsec;
+  int contentionNumSamples;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaLinkLayerIfacePacketStats.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaLinkLayerIfacePacketStats.aidl
new file mode 100644
index 0000000..eddf52e
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaLinkLayerIfacePacketStats.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable StaLinkLayerIfacePacketStats {
+  long rxMpdu;
+  long txMpdu;
+  long lostMpdu;
+  long retries;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaLinkLayerIfaceStats.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaLinkLayerIfaceStats.aidl
new file mode 100644
index 0000000..cf68fc6
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaLinkLayerIfaceStats.aidl
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable StaLinkLayerIfaceStats {
+  int beaconRx;
+  int avgRssiMgmt;
+  android.hardware.wifi.StaLinkLayerIfacePacketStats wmeBePktStats;
+  android.hardware.wifi.StaLinkLayerIfacePacketStats wmeBkPktStats;
+  android.hardware.wifi.StaLinkLayerIfacePacketStats wmeViPktStats;
+  android.hardware.wifi.StaLinkLayerIfacePacketStats wmeVoPktStats;
+  byte timeSliceDutyCycleInPercent;
+  android.hardware.wifi.StaLinkLayerIfaceContentionTimeStats wmeBeContentionTimeStats;
+  android.hardware.wifi.StaLinkLayerIfaceContentionTimeStats wmeBkContentionTimeStats;
+  android.hardware.wifi.StaLinkLayerIfaceContentionTimeStats wmeViContentionTimeStats;
+  android.hardware.wifi.StaLinkLayerIfaceContentionTimeStats wmeVoContentionTimeStats;
+  android.hardware.wifi.StaPeerInfo[] peers;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaLinkLayerRadioStats.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaLinkLayerRadioStats.aidl
new file mode 100644
index 0000000..84d24c9
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaLinkLayerRadioStats.aidl
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable StaLinkLayerRadioStats {
+  int onTimeInMs;
+  int txTimeInMs;
+  int[] txTimeInMsPerLevel;
+  int rxTimeInMs;
+  int onTimeInMsForScan;
+  int onTimeInMsForNanScan;
+  int onTimeInMsForBgScan;
+  int onTimeInMsForRoamScan;
+  int onTimeInMsForPnoScan;
+  int onTimeInMsForHs20Scan;
+  android.hardware.wifi.WifiChannelStats[] channelStats;
+  int radioId;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaLinkLayerStats.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaLinkLayerStats.aidl
new file mode 100644
index 0000000..9c05346
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaLinkLayerStats.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable StaLinkLayerStats {
+  android.hardware.wifi.StaLinkLayerIfaceStats iface;
+  android.hardware.wifi.StaLinkLayerRadioStats[] radios;
+  long timeStampInMs;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaPeerInfo.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaPeerInfo.aidl
new file mode 100644
index 0000000..93a901f
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaPeerInfo.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable StaPeerInfo {
+  char staCount;
+  char chanUtil;
+  android.hardware.wifi.StaRateStat[] rateStats;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaRateStat.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaRateStat.aidl
new file mode 100644
index 0000000..43b69fc
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaRateStat.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable StaRateStat {
+  android.hardware.wifi.WifiRateInfo rateInfo;
+  int txMpdu;
+  int rxMpdu;
+  int mpduLost;
+  int retries;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaRoamingCapabilities.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaRoamingCapabilities.aidl
new file mode 100644
index 0000000..9eed877
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaRoamingCapabilities.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable StaRoamingCapabilities {
+  int maxBlocklistSize;
+  int maxAllowlistSize;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaRoamingConfig.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaRoamingConfig.aidl
new file mode 100644
index 0000000..2b37cee
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaRoamingConfig.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable StaRoamingConfig {
+  android.hardware.wifi.MacAddress[] bssidBlocklist;
+  android.hardware.wifi.Ssid[] ssidAllowlist;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaRoamingState.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaRoamingState.aidl
new file mode 100644
index 0000000..1f3d91f
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaRoamingState.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="byte") @VintfStability
+enum StaRoamingState {
+  DISABLED = 0,
+  ENABLED = 1,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaScanData.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaScanData.aidl
new file mode 100644
index 0000000..5903760
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaScanData.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable StaScanData {
+  android.hardware.wifi.StaScanDataFlagMask flags;
+  int bucketsScanned;
+  android.hardware.wifi.StaScanResult[] results;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaScanDataFlagMask.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaScanDataFlagMask.aidl
new file mode 100644
index 0000000..dc8f2f1
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaScanDataFlagMask.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum StaScanDataFlagMask {
+  INTERRUPTED = 1,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaScanResult.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaScanResult.aidl
new file mode 100644
index 0000000..9a8d297
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaScanResult.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable StaScanResult {
+  long timeStampInUs;
+  byte[] ssid;
+  byte[6] bssid;
+  int rssi;
+  int frequency;
+  char beaconPeriodInMs;
+  char capability;
+  android.hardware.wifi.WifiInformationElement[] informationElements;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiAntennaMode.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiAntennaMode.aidl
new file mode 100644
index 0000000..b47b7f5
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiAntennaMode.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum WifiAntennaMode {
+  WIFI_ANTENNA_MODE_UNSPECIFIED = 0,
+  WIFI_ANTENNA_MODE_1X1 = 1,
+  WIFI_ANTENNA_MODE_2X2 = 2,
+  WIFI_ANTENNA_MODE_3X3 = 3,
+  WIFI_ANTENNA_MODE_4X4 = 4,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiBand.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiBand.aidl
new file mode 100644
index 0000000..e9a87ee
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiBand.aidl
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum WifiBand {
+  BAND_UNSPECIFIED = 0,
+  BAND_24GHZ = 1,
+  BAND_5GHZ = 2,
+  BAND_5GHZ_DFS = 4,
+  BAND_5GHZ_WITH_DFS = 6,
+  BAND_24GHZ_5GHZ = 3,
+  BAND_24GHZ_5GHZ_WITH_DFS = 7,
+  BAND_6GHZ = 8,
+  BAND_5GHZ_6GHZ = 10,
+  BAND_24GHZ_5GHZ_6GHZ = 11,
+  BAND_24GHZ_5GHZ_WITH_DFS_6GHZ = 15,
+  BAND_60GHZ = 16,
+  BAND_24GHZ_5GHZ_6GHZ_60GHZ = 27,
+  BAND_24GHZ_5GHZ_WITH_DFS_6GHZ_60GHZ = 31,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiChannelInfo.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiChannelInfo.aidl
new file mode 100644
index 0000000..297c923
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiChannelInfo.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable WifiChannelInfo {
+  android.hardware.wifi.WifiChannelWidthInMhz width;
+  int centerFreq;
+  int centerFreq0;
+  int centerFreq1;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiChannelStats.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiChannelStats.aidl
new file mode 100644
index 0000000..c6e7acc
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiChannelStats.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable WifiChannelStats {
+  android.hardware.wifi.WifiChannelInfo channel;
+  int onTimeInMs;
+  int ccaBusyTimeInMs;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiChannelWidthInMhz.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiChannelWidthInMhz.aidl
new file mode 100644
index 0000000..8c45044
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiChannelWidthInMhz.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum WifiChannelWidthInMhz {
+  WIDTH_INVALID = -1,
+  WIDTH_20 = 0,
+  WIDTH_40 = 1,
+  WIDTH_80 = 2,
+  WIDTH_160 = 3,
+  WIDTH_80P80 = 4,
+  WIDTH_5 = 5,
+  WIDTH_10 = 6,
+  WIDTH_320 = 7,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugHostWakeReasonRxIcmpPacketDetails.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugHostWakeReasonRxIcmpPacketDetails.aidl
new file mode 100644
index 0000000..8415e09
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugHostWakeReasonRxIcmpPacketDetails.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable WifiDebugHostWakeReasonRxIcmpPacketDetails {
+  int icmpPkt;
+  int icmp6Pkt;
+  int icmp6Ra;
+  int icmp6Na;
+  int icmp6Ns;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugHostWakeReasonRxMulticastPacketDetails.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugHostWakeReasonRxMulticastPacketDetails.aidl
new file mode 100644
index 0000000..30301d3
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugHostWakeReasonRxMulticastPacketDetails.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable WifiDebugHostWakeReasonRxMulticastPacketDetails {
+  int ipv4RxMulticastAddrCnt;
+  int ipv6RxMulticastAddrCnt;
+  int otherRxMulticastAddrCnt;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugHostWakeReasonRxPacketDetails.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugHostWakeReasonRxPacketDetails.aidl
new file mode 100644
index 0000000..8118322
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugHostWakeReasonRxPacketDetails.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable WifiDebugHostWakeReasonRxPacketDetails {
+  int rxUnicastCnt;
+  int rxMulticastCnt;
+  int rxBroadcastCnt;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugHostWakeReasonStats.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugHostWakeReasonStats.aidl
new file mode 100644
index 0000000..1766476
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugHostWakeReasonStats.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable WifiDebugHostWakeReasonStats {
+  int totalCmdEventWakeCnt;
+  int[] cmdEventWakeCntPerType;
+  int totalDriverFwLocalWakeCnt;
+  int[] driverFwLocalWakeCntPerType;
+  int totalRxPacketWakeCnt;
+  android.hardware.wifi.WifiDebugHostWakeReasonRxPacketDetails rxPktWakeDetails;
+  android.hardware.wifi.WifiDebugHostWakeReasonRxMulticastPacketDetails rxMulticastPkWakeDetails;
+  android.hardware.wifi.WifiDebugHostWakeReasonRxIcmpPacketDetails rxIcmpPkWakeDetails;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugPacketFateFrameInfo.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugPacketFateFrameInfo.aidl
new file mode 100644
index 0000000..2ff6cfc
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugPacketFateFrameInfo.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable WifiDebugPacketFateFrameInfo {
+  android.hardware.wifi.WifiDebugPacketFateFrameType frameType;
+  long frameLen;
+  long driverTimestampUsec;
+  long firmwareTimestampUsec;
+  byte[] frameContent;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugPacketFateFrameType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugPacketFateFrameType.aidl
new file mode 100644
index 0000000..ee26f2e
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugPacketFateFrameType.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum WifiDebugPacketFateFrameType {
+  UNKNOWN = 0,
+  ETHERNET_II = 1,
+  MGMT_80211 = 2,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugRingBufferFlags.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugRingBufferFlags.aidl
new file mode 100644
index 0000000..f210e82
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugRingBufferFlags.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum WifiDebugRingBufferFlags {
+  HAS_BINARY_ENTRIES = 1,
+  HAS_ASCII_ENTRIES = 2,
+  HAS_PER_PACKET_ENTRIES = 4,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugRingBufferStatus.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugRingBufferStatus.aidl
new file mode 100644
index 0000000..e4249d9
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugRingBufferStatus.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable WifiDebugRingBufferStatus {
+  String ringName;
+  int flags;
+  int ringId;
+  int sizeInBytes;
+  int freeSizeInBytes;
+  int verboseLevel;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugRingBufferVerboseLevel.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugRingBufferVerboseLevel.aidl
new file mode 100644
index 0000000..e614f3f
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugRingBufferVerboseLevel.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum WifiDebugRingBufferVerboseLevel {
+  NONE = 0,
+  DEFAULT = 1,
+  VERBOSE = 2,
+  EXCESSIVE = 3,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugRxPacketFate.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugRxPacketFate.aidl
new file mode 100644
index 0000000..75abb4e
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugRxPacketFate.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum WifiDebugRxPacketFate {
+  SUCCESS = 0,
+  FW_QUEUED = 1,
+  FW_DROP_FILTER = 2,
+  FW_DROP_INVALID = 3,
+  FW_DROP_NOBUFS = 4,
+  FW_DROP_OTHER = 5,
+  DRV_QUEUED = 6,
+  DRV_DROP_FILTER = 7,
+  DRV_DROP_INVALID = 8,
+  DRV_DROP_NOBUFS = 9,
+  DRV_DROP_OTHER = 10,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugRxPacketFateReport.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugRxPacketFateReport.aidl
new file mode 100644
index 0000000..bfe0c0a
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugRxPacketFateReport.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable WifiDebugRxPacketFateReport {
+  android.hardware.wifi.WifiDebugRxPacketFate fate;
+  android.hardware.wifi.WifiDebugPacketFateFrameInfo frameInfo;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugTxPacketFate.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugTxPacketFate.aidl
new file mode 100644
index 0000000..e360c2c
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugTxPacketFate.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum WifiDebugTxPacketFate {
+  ACKED = 0,
+  SENT = 1,
+  FW_QUEUED = 2,
+  FW_DROP_INVALID = 3,
+  FW_DROP_NOBUFS = 4,
+  FW_DROP_OTHER = 5,
+  DRV_QUEUED = 6,
+  DRV_DROP_INVALID = 7,
+  DRV_DROP_NOBUFS = 8,
+  DRV_DROP_OTHER = 9,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugTxPacketFateReport.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugTxPacketFateReport.aidl
new file mode 100644
index 0000000..aee5c31
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiDebugTxPacketFateReport.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable WifiDebugTxPacketFateReport {
+  android.hardware.wifi.WifiDebugTxPacketFate fate;
+  android.hardware.wifi.WifiDebugPacketFateFrameInfo frameInfo;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiIfaceMode.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiIfaceMode.aidl
new file mode 100644
index 0000000..e2fe57a
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiIfaceMode.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum WifiIfaceMode {
+  IFACE_MODE_STA = 1,
+  IFACE_MODE_SOFTAP = 2,
+  IFACE_MODE_IBSS = 4,
+  IFACE_MODE_P2P_CLIENT = 8,
+  IFACE_MODE_P2P_GO = 16,
+  IFACE_MODE_NAN = 32,
+  IFACE_MODE_MESH = 64,
+  IFACE_MODE_TDLS = 128,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiInformationElement.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiInformationElement.aidl
new file mode 100644
index 0000000..27ba0db
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiInformationElement.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable WifiInformationElement {
+  byte id;
+  byte[] data;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiRadioCombination.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiRadioCombination.aidl
new file mode 100644
index 0000000..f060db8
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiRadioCombination.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable WifiRadioCombination {
+  android.hardware.wifi.WifiRadioConfiguration[] radioConfigurations;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiRadioCombinationMatrix.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiRadioCombinationMatrix.aidl
new file mode 100644
index 0000000..ea86c4f
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiRadioCombinationMatrix.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable WifiRadioCombinationMatrix {
+  android.hardware.wifi.WifiRadioCombination[] radioCombinations;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiRadioConfiguration.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiRadioConfiguration.aidl
new file mode 100644
index 0000000..5169351
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiRadioConfiguration.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable WifiRadioConfiguration {
+  android.hardware.wifi.WifiBand bandInfo;
+  android.hardware.wifi.WifiAntennaMode antennaMode;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiRateInfo.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiRateInfo.aidl
new file mode 100644
index 0000000..c4aca63
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiRateInfo.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable WifiRateInfo {
+  android.hardware.wifi.WifiRatePreamble preamble;
+  android.hardware.wifi.WifiRateNss nss;
+  android.hardware.wifi.WifiChannelWidthInMhz bw;
+  byte rateMcsIdx;
+  int bitRateInKbps;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiRateNss.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiRateNss.aidl
new file mode 100644
index 0000000..0ad6f04
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiRateNss.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum WifiRateNss {
+  NSS_1x1 = 0,
+  NSS_2x2 = 1,
+  NSS_3x3 = 2,
+  NSS_4x4 = 3,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiRatePreamble.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiRatePreamble.aidl
new file mode 100644
index 0000000..04b6358
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiRatePreamble.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum WifiRatePreamble {
+  OFDM = 0,
+  CCK = 1,
+  HT = 2,
+  VHT = 3,
+  RESERVED = 4,
+  HE = 5,
+  EHT = 6,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiStatusCode.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiStatusCode.aidl
new file mode 100644
index 0000000..f27661c
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiStatusCode.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@Backing(type="int") @VintfStability
+enum WifiStatusCode {
+  SUCCESS = 0,
+  ERROR_WIFI_CHIP_INVALID = 1,
+  ERROR_WIFI_IFACE_INVALID = 2,
+  ERROR_WIFI_RTT_CONTROLLER_INVALID = 3,
+  ERROR_NOT_SUPPORTED = 4,
+  ERROR_NOT_AVAILABLE = 5,
+  ERROR_NOT_STARTED = 6,
+  ERROR_INVALID_ARGS = 7,
+  ERROR_BUSY = 8,
+  ERROR_UNKNOWN = 9,
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiUsableChannel.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiUsableChannel.aidl
new file mode 100644
index 0000000..94e3a8a
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/WifiUsableChannel.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable WifiUsableChannel {
+  int channel;
+  android.hardware.wifi.WifiChannelWidthInMhz channelBandwidth;
+  android.hardware.wifi.WifiIfaceMode ifaceModeMask;
+}
diff --git a/wifi/aidl/android/hardware/wifi/IWifi.aidl b/wifi/aidl/android/hardware/wifi/IWifi.aidl
new file mode 100644
index 0000000..1d86421
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/IWifi.aidl
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+import android.hardware.wifi.IWifiChip;
+import android.hardware.wifi.IWifiEventCallback;
+
+/**
+ * This is the root of the HAL module and is the interface returned when
+ * loading an implementation of the Wi-Fi HAL. There must be at most one
+ * module loaded in the system.
+ */
+@VintfStability
+interface IWifi {
+    /**
+     * Gets an AIDL interface object for the chip corresponding to the
+     * provided chipId.
+     *
+     * @param chipId ID of the chip.
+     * @return AIDL interface object representing the chip.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.NOT_STARTED|,
+     *         |WifiStatusCode.UNKNOWN|
+     */
+    @PropagateAllowBlocking IWifiChip getChip(int chipId);
+
+    /**
+     * Retrieves the list of all chip id's on the device.
+     * The corresponding |IWifiChip| object for any chip can be
+     * retrieved using the |getChip| method.
+     *
+     * @return List of all chip id's on the device.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.NOT_STARTED|,
+     *         |WifiStatusCode.UNKNOWN|
+     */
+    int[] getChipIds();
+
+    /**
+     * Get the current state of the HAL.
+     *
+     * @return true if started, false otherwise.
+     */
+    boolean isStarted();
+
+    /**
+     * Requests notifications of significant HAL events. Multiple calls to
+     * this must register multiple callbacks, each of which must receive all
+     * events. |IWifiEventCallback| object registration must be independent of the
+     * state of the rest of the HAL and must persist though stops/starts. These
+     * objects must be deleted when the corresponding client process is dead.
+     *
+     * @param callback An instance of the |IWifiEventCallback| AIDL interface
+     *        object.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.UNKNOWN|
+     */
+    void registerEventCallback(in IWifiEventCallback callback);
+
+    /**
+     * Perform any setup that is required to make use of the module.
+     * If the module is already started then this must be a noop.
+     * Must trigger |IWifiEventCallback.onStart| on success.
+     *
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.NOT_AVAILABLE|,
+     *         |WifiStatusCode.UNKNOWN|
+     */
+    void start();
+
+    /**
+     * Tear down any state, ongoing commands, etc. If the module is already
+     * stopped then this must be a noop. After calling this, all |IWifiChip|
+     * objects will be considered invalid.
+     * Must trigger |IWifiEventCallback.onStop| on success.
+     * Must trigger |IWifiEventCallback.onFailure| on failure.
+     *
+     * Calling stop() and then start() is a valid way of resetting state in
+     * the HAL, driver, and firmware.
+     *
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.NOT_STARTED|,
+     *         |WifiStatusCode.UNKNOWN|
+     */
+    void stop();
+}
diff --git a/wifi/aidl/android/hardware/wifi/IWifiApIface.aidl b/wifi/aidl/android/hardware/wifi/IWifiApIface.aidl
new file mode 100644
index 0000000..71ea385
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/IWifiApIface.aidl
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+import android.hardware.wifi.WifiBand;
+
+/**
+ * Represents a network interface in AP mode.
+ *
+ * This can be obtained through |IWifiChip.getApIface|.
+ */
+@VintfStability
+interface IWifiApIface {
+    /**
+     * Get the name of this interface.
+     *
+     * @return Name of this interface.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|
+     */
+    String getName();
+
+    /**
+     * Get the names of the bridged AP instances.
+     *
+     * @return Vector containing the names of the bridged AP
+     *         instances. Note: Returns an empty vector for a non-bridged AP.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    String[] getBridgedInstances();
+
+    /**
+     * Gets the factory MAC address of the interface.
+     *
+     * @return Factory MAC address of the interface.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    byte[6] getFactoryMacAddress();
+
+    /**
+     * Set country code for this iface.
+     *
+     * @param code 2 byte country code (as defined in ISO 3166) to set.
+     * @return status Status of the operation.
+     *         Possible status codes:
+     *         |WifiStatusCode.SUCCESS|,
+     *         |WifiStatusCode.FAILURE_UNKNOWN|,
+     *         |WifiStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void setCountryCode(in byte[2] code);
+
+    /**
+     * Used to query the list of valid frequencies (depending on country code set)
+     * for the provided band.
+     *
+     * @param band Band for which the frequency list is being generated.
+     * @return Vector of valid frequencies for the provided band.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    int[] getValidFrequenciesForBand(in WifiBand band);
+
+    /**
+     * Reset all of the AP interfaces' MAC address to the factory MAC address.
+     *
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void resetToFactoryMacAddress();
+
+    /**
+     * Changes the MAC address of the interface to the given MAC address.
+     *
+     * @param mac MAC address to change to.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void setMacAddress(in byte[6] mac);
+}
diff --git a/wifi/aidl/android/hardware/wifi/IWifiChip.aidl b/wifi/aidl/android/hardware/wifi/IWifiChip.aidl
new file mode 100644
index 0000000..fe9a6f3
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/IWifiChip.aidl
@@ -0,0 +1,1096 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+import android.hardware.wifi.IWifiApIface;
+import android.hardware.wifi.IWifiChipEventCallback;
+import android.hardware.wifi.IWifiNanIface;
+import android.hardware.wifi.IWifiP2pIface;
+import android.hardware.wifi.IWifiRttController;
+import android.hardware.wifi.IWifiStaIface;
+import android.hardware.wifi.IfaceConcurrencyType;
+import android.hardware.wifi.IfaceType;
+import android.hardware.wifi.WifiBand;
+import android.hardware.wifi.WifiDebugHostWakeReasonStats;
+import android.hardware.wifi.WifiDebugRingBufferStatus;
+import android.hardware.wifi.WifiDebugRingBufferVerboseLevel;
+import android.hardware.wifi.WifiIfaceMode;
+import android.hardware.wifi.WifiRadioCombinationMatrix;
+import android.hardware.wifi.WifiUsableChannel;
+
+/**
+ * Interface that represents a chip that must be configured as a single unit.
+ */
+@VintfStability
+interface IWifiChip {
+    /**
+     * Capabilities exposed by this chip.
+     */
+    @VintfStability
+    @Backing(type="int")
+    enum ChipCapabilityMask {
+        /**
+         * Memory dump of Firmware.
+         */
+        DEBUG_MEMORY_FIRMWARE_DUMP = 1 << 0,
+        /**
+         * Memory dump of Driver.
+         */
+        DEBUG_MEMORY_DRIVER_DUMP = 1 << 1,
+        /**
+         * Connectivity events reported via debug ring buffer.
+         */
+        DEBUG_RING_BUFFER_CONNECT_EVENT = 1 << 2,
+        /**
+         * Power events reported via debug ring buffer.
+         */
+        DEBUG_RING_BUFFER_POWER_EVENT = 1 << 3,
+        /**
+         * Wakelock events reported via debug ring buffer.
+         */
+        DEBUG_RING_BUFFER_WAKELOCK_EVENT = 1 << 4,
+        /**
+         * Vendor data reported via debug ring buffer.
+         * This mostly contains firmware event logs.
+         */
+        DEBUG_RING_BUFFER_VENDOR_DATA = 1 << 5,
+        /**
+         * Host wake reasons stats collection.
+         */
+        DEBUG_HOST_WAKE_REASON_STATS = 1 << 6,
+        /**
+         * Error alerts.
+         */
+        DEBUG_ERROR_ALERTS = 1 << 7,
+        /**
+         * Set/Reset Tx Power limits.
+         */
+        SET_TX_POWER_LIMIT = 1 << 8,
+        /**
+         * Device to Device RTT.
+         */
+        D2D_RTT = 1 << 9,
+        /**
+         * Device to AP RTT.
+         */
+        D2AP_RTT = 1 << 10,
+        /**
+         * Set/Reset Tx Power limits.
+         */
+        USE_BODY_HEAD_SAR = 1 << 11,
+        /**
+         * Set Latency Mode.
+         */
+        SET_LATENCY_MODE = 1 << 12,
+        /**
+         * Support P2P MAC randomization.
+         */
+        P2P_RAND_MAC = 1 << 13,
+        /**
+         * Chip can operate in the 60GHz band (WiGig chip).
+         */
+        WIGIG = 1 << 14,
+    }
+
+    /**
+     * Set of interface concurrency types, along with the maximum number of interfaces that can have
+     * one of the specified concurrency types for a given ChipConcurrencyCombination. See
+     * ChipConcurrencyCombination below for examples.
+     */
+    @VintfStability
+    parcelable ChipConcurrencyCombinationLimit {
+        IfaceConcurrencyType[] types;
+        int maxIfaces;
+    }
+
+    /**
+     * Set of interfaces that can operate concurrently when in a given mode. See
+     * ChipMode below.
+     *
+     * For example:
+     *   [{STA} <= 2]
+     *       At most two STA interfaces are supported
+     *       [], [STA], [STA+STA]
+     *
+     *   [{STA} <= 1, {NAN} <= 1, {AP_BRIDGED} <= 1]
+     *       Any combination of STA, NAN, AP_BRIDGED
+     *       [], [STA], [NAN], [AP_BRIDGED], [STA+NAN], [STA+AP_BRIDGED], [NAN+AP_BRIDGED],
+     *       [STA+NAN+AP_BRIDGED]
+     *
+     *   [{STA} <= 1, {NAN,P2P} <= 1]
+     *       Optionally a STA and either NAN or P2P
+     *       [], [STA], [STA+NAN], [STA+P2P], [NAN], [P2P]
+     *       Not included [NAN+P2P], [STA+NAN+P2P]
+     *
+     *   [{STA} <= 1, {STA,NAN} <= 1]
+     *       Optionally a STA and either a second STA or a NAN
+     *       [], [STA], [STA+NAN], [STA+STA], [NAN]
+     *       Not included [STA+STA+NAN]
+     */
+    @VintfStability
+    parcelable ChipConcurrencyCombination {
+        ChipConcurrencyCombinationLimit[] limits;
+    }
+
+    /**
+     * Information about the version of the driver and firmware running this chip.
+     *
+     * The information in these ASCII strings are vendor specific and does not
+     * need to follow any particular format. It may be dumped as part of the bug
+     * report.
+     */
+    @VintfStability
+    parcelable ChipDebugInfo {
+        String driverDescription;
+        String firmwareDescription;
+    }
+
+    /**
+     * Set of interface types, along with the maximum number of interfaces that can have
+     * one of the specified types for a given ChipIfaceCombination. See
+     * ChipIfaceCombination for examples.
+     */
+    @VintfStability
+    parcelable ChipIfaceCombinationLimit {
+        IfaceType[] types;
+        int maxIfaces;
+    }
+
+    /**
+     * Set of interfaces that can operate concurrently when in a given mode. See
+     * ChipMode below.
+     *
+     * For example:
+     *   [{STA} <= 2]
+     *       At most two STA interfaces are supported
+     *       [], [STA], [STA+STA]
+     *
+     *   [{STA} <= 1, {NAN} <= 1, {AP} <= 1]
+     *       Any combination of STA, NAN, AP
+     *       [], [STA], [NAN], [AP], [STA+NAN], [STA+AP], [NAN+AP], [STA+NAN+AP]
+     *
+     *   [{STA} <= 1, {NAN,P2P} <= 1]
+     *       Optionally a STA and either NAN or P2P
+     *       [], [STA], [STA+NAN], [STA+P2P], [NAN], [P2P]
+     *       Not included [NAN+P2P], [STA+NAN+P2P]
+     *
+     *   [{STA} <= 1, {STA,NAN} <= 1]
+     *       Optionally a STA and either a second STA or a NAN
+     *       [], [STA], [STA+NAN], [STA+STA], [NAN]
+     *       Not included [STA+STA+NAN]
+     */
+    @VintfStability
+    parcelable ChipIfaceCombination {
+        ChipIfaceCombinationLimit[] limits;
+    }
+
+    /**
+     * A mode that the chip can be put in. A mode defines a set of constraints on
+     * the interfaces that can exist while in that mode. Modes define a unit of
+     * configuration where all interfaces must be torn down to switch to a
+     * different mode. Some HALs may only have a single mode, but an example where
+     * multiple modes would be required is if a chip has different firmwares with
+     * different capabilities.
+     *
+     * When in a mode, it must be possible to perform any combination of creating
+     * and removing interfaces as long as at least one of the
+     * ChipConcurrencyCombinations is satisfied. This means that if a chip has two
+     * available combinations, [{STA} <= 1] and [{AP_BRIDGED} <= 1] then it is expected
+     * that exactly one STA type or one AP_BRIDGED type can be created, but it
+     * is not expected that both a STA and AP_BRIDGED type  could be created. If it
+     * was then there would be a single available combination
+     * [{STA} <=1, {AP_BRIDGED} <= 1].
+     *
+     * When switching between two available combinations it is expected that
+     * interfaces only supported by the initial combination must be removed until
+     * the target combination is also satisfied. At that point new interfaces
+     * satisfying only the target combination can be added (meaning the initial
+     * combination limits will no longer satisfied). The addition of these new
+     * interfaces must not impact the existence of interfaces that satisfy both
+     * combinations.
+     *
+     * For example, a chip with available combinations:
+     *     [{STA} <= 2, {NAN} <=1] and [{STA} <=1, {NAN} <= 1, {AP_BRIDGED} <= 1}]
+     * If the chip currently has 3 interfaces STA, STA and NAN and wants to add an
+     * AP_BRIDGED interface in place of one of the STAs, then one of the STA interfaces
+     * must be removed first, and then the AP interface can be created after
+     * the STA has been torn down. During this process the remaining STA and NAN
+     * interfaces must not be removed/recreated.
+     *
+     * If a chip does not support this kind of reconfiguration in this mode then
+     * the combinations must be separated into two separate modes. Before
+     * switching modes, all interfaces must be torn down, the mode switch must be
+     * enacted, and when it completes the new interfaces must be brought up.
+     */
+    @VintfStability
+    parcelable ChipMode {
+        /**
+         * Id that can be used to put the chip in this mode.
+         */
+        int id;
+        /**
+         * A list of the possible interface concurrency type combinations that the
+         * chip can have while in this mode.
+         */
+        ChipConcurrencyCombination[] availableCombinations;
+    }
+
+    /**
+     * Wi-Fi coex channel avoidance support.
+     */
+    const int NO_POWER_CAP_CONSTANT = 0x7FFFFFFF;
+
+    @VintfStability
+    @Backing(type="int")
+    enum CoexRestriction {
+        WIFI_DIRECT = 1 << 0,
+        SOFTAP = 1 << 1,
+        WIFI_AWARE = 1 << 2,
+    }
+
+    /**
+     * Representation of a Wi-Fi channel for Wi-Fi coex channel avoidance.
+     */
+    @VintfStability
+    parcelable CoexUnsafeChannel {
+        /*
+         * Band of the channel.
+         */
+        WifiBand band;
+        /*
+         * Channel number.
+         */
+        int channel;
+        /**
+         * The power cap will be a maximum power value in dbm that is allowed to be transmitted by
+         * the chip on this channel. A value of PowerCapConstant.NO_POWER_CAP means no limitation
+         * on transmitted power is needed by the chip for this channel.
+         */
+        int powerCapDbm;
+    }
+
+    /**
+     * This enum represents the different latency modes that can be set through |setLatencyMode|.
+     */
+    @VintfStability
+    @Backing(type="int")
+    enum LatencyMode {
+        NORMAL = 0,
+        LOW = 1,
+    }
+
+    /**
+     * When there are 2 or more simultaneous STA connections, this use case hint indicates what
+     * use-case is being enabled by the framework. This use case hint can be used by the firmware
+     * to modify various firmware configurations like:
+     *   - Allowed BSSIDs the firmware can choose for the initial connection/roaming attempts.
+     *   - Duty cycle to choose for the 2 STA connections if the radio is in MCC mode.
+     *   - Whether roaming, APF and other offloads need to be enabled or not.
+     * Note:
+     *   - This will be invoked before an active wifi connection is established on the second
+     *     interface.
+     *   - This use-case hint is implicitly void when the second STA interface is brought down.
+     *   - When there is only 1 STA interface, we should still retain the last use case
+     *     set, which must become active the next time multi STA is enabled.
+     *     1. Initialize with single STA.
+     *     2. Framework creates second STA.
+     *     3. Framework sets use case to DUAL_STA_NON_TRANSIENT_UNBIASED.
+     *     4. Framework destroys second STA. Only 1 STA remains.
+     *     5. Framework recreates second STA.
+     *     6. The active use case remains DUAL_STA_NON_TRANSIENT_UNBIASED (i.e. firmware should not
+     *        automatically change it during period of single STA unless requested by framework).
+     */
+    @VintfStability
+    @Backing(type="byte")
+    enum MultiStaUseCase {
+        /**
+         * Usage:
+         * - This will be sent down for make before break use-case.
+         * - Platform is trying to speculatively connect to a second network and evaluate it without
+         *  disrupting the primary connection.
+         * Requirements for Firmware:
+         * - Do not reduce the number of tx/rx chains of primary connection.
+         * - If using MCC, should set the MCC duty cycle of the primary connection to be higher than
+         *  the secondary connection (maybe 70/30 split).
+         * - Should pick the best BSSID for the secondary STA (disregard the chip mode) independent
+         *   of the primary STA:
+         *    - Don’t optimize for DBS vs MCC/SCC
+         * - Should not impact the primary connection’s bssid selection:
+         *    - Don’t downgrade chains of the existing primary connection.
+         *    - Don’t optimize for DBS vs MCC/SCC.
+         */
+        DUAL_STA_TRANSIENT_PREFER_PRIMARY = 0,
+        /**
+         * Usage:
+         * - This will be sent down for any app requested peer to peer connections.
+         * - In this case, both the connections need to be allocated equal resources.
+         * - For the peer to peer use case, BSSID for the secondary connection will be chosen by the
+         *   framework.
+         *
+         * Requirements for Firmware:
+         * - Can choose MCC or DBS mode depending on the MCC efficiency and HW capability.
+         * - If using MCC, set the MCC duty cycle of the primary connection to be equal to the
+         *   secondary connection.
+         * - Prefer BSSID candidates which will help provide the best "overall" performance for both
+         *   the connections.
+         */
+        DUAL_STA_NON_TRANSIENT_UNBIASED = 1,
+    }
+
+    /**
+     * List of preset wifi radio TX power levels for different scenarios.
+     * The actual power values (typically varies based on the channel,
+     * 802.11 connection type, number of MIMO streams, etc) for each scenario
+     * is defined by the OEM as a BDF file since it varies for each wifi chip
+     * vendor and device.
+     */
+    @VintfStability
+    @Backing(type="int")
+    enum TxPowerScenario {
+        VOICE_CALL = 0,
+        ON_HEAD_CELL_OFF = 1,
+        ON_HEAD_CELL_ON = 2,
+        ON_BODY_CELL_OFF = 3,
+        ON_BODY_CELL_ON = 4,
+    }
+
+    /**
+     * Usable Wifi channels filter masks.
+     */
+    @VintfStability
+    @Backing(type="int")
+    enum UsableChannelFilter {
+        /**
+         * Filter Wifi channels that should be avoided due to extreme
+         * cellular coexistence restrictions. Some Wifi channels can have
+         * extreme interference from/to cellular due to short frequency
+         * seperation with neighboring cellular channels, or when there
+         * is harmonic and intermodulation interference. Channels which
+         * only have some performance degradation (e.g. power back off is
+         * sufficient to deal with coexistence issue) can be included and
+         * should not be filtered out.
+         */
+        CELLULAR_COEXISTENCE = 1 << 0,
+        /**
+         * Filter based on concurrency state.
+         * Examples:
+         * - 5GHz SAP operation may be supported in standalone mode, but if
+         *  there is a STA connection on a 5GHz DFS channel, none of the 5GHz
+         *  channels are usable for SAP if device does not support DFS SAP mode.
+         * - P2P GO may not be supported on indoor channels in the EU during
+         *  standalone mode but if there is a STA connection on indoor channel.
+         *  P2P GO may be supported by some vendors on the same STA channel.
+         */
+        CONCURRENCY = 1 << 1,
+        /**
+         * Filter Wifi channels that are supported for NAN 3.1 Instant communication mode.
+         * This filter should only be applied to a NAN interface.
+         * - If 5G is supported, then default discovery channel 149/44 is considered.
+         * - If 5G is not supported, then channel 6 has to be considered.
+         */
+        NAN_INSTANT_MODE = 1 << 2,
+    }
+
+    /**
+     * Configure the Chip.
+     * This may NOT be called to reconfigure a chip due to an internal
+     * limitation. Calling this when chip is already configured in a different
+     * mode must trigger an ERROR_NOT_SUPPORTED failure.
+     * If you want to do reconfiguration, please call |IWifi.stop| and |IWifi.start|
+     * to restart Wifi HAL before calling this.
+     * Any existing |IWifiIface| objects must be marked invalid after this call.
+     * If this fails then the chip is now in an undefined state and
+     * configureChip must be called again.
+     * Must trigger |IWifiChipEventCallback.onChipReconfigured| on success.
+     * Must trigger |IWifiEventCallback.onFailure| on failure.
+     *
+     * @param modeId Mode that the chip must switch to, corresponding to the
+     *        id property of the target ChipMode.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void configureChip(in int modeId);
+
+    /**
+     * Create an AP iface on the chip.
+     *
+     * Depending on the mode the chip is configured in, the interface creation
+     * may fail (code: |WifiStatusCode.ERROR_NOT_AVAILABLE|) if we've already
+     * reached the maximum allowed (specified in |ChipIfaceCombination|) number
+     * of ifaces of the AP type.
+     *
+     * @return AIDL interface object representing the iface if
+     *         successful, null otherwise.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|
+     */
+    @PropagateAllowBlocking IWifiApIface createApIface();
+
+    /**
+     * Create a bridged AP iface on the chip.
+     *
+     * Depending on the mode the chip is configured in, the interface creation
+     * may fail (code: |WifiStatusCode.ERROR_NOT_AVAILABLE|) if we've already
+     * reached the maximum allowed (specified in |ChipIfaceCombination|) number
+     * of ifaces of the AP type.
+     *
+     * @return AIDL interface object representing the iface if
+     *         successful, null otherwise.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|
+     */
+    @PropagateAllowBlocking IWifiApIface createBridgedApIface();
+
+    /**
+     * Create a NAN iface on the chip.
+     *
+     * Depending on the mode the chip is configured in, the interface creation
+     * may fail (code: |WifiStatusCode.ERROR_NOT_AVAILABLE|) if we've already
+     * reached the maximum allowed (specified in |ChipIfaceCombination|) number
+     * of ifaces of the NAN type.
+     *
+     * @return AIDL interface object representing the iface if
+     *         successful, null otherwise.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|
+     */
+    @PropagateAllowBlocking IWifiNanIface createNanIface();
+
+    /**
+     * Create a P2P iface on the chip.
+     *
+     * Depending on the mode the chip is configured in, the interface creation
+     * may fail (code: |WifiStatusCode.ERROR_NOT_AVAILABLE|) if we've already
+     * reached the maximum allowed (specified in |ChipIfaceCombination|) number
+     * of ifaces of the P2P type.
+     *
+     * @return AIDL interface object representing the iface if
+     *         successful, null otherwise.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|
+     */
+    @PropagateAllowBlocking IWifiP2pIface createP2pIface();
+
+    /**
+     * Create an RTTController instance.
+     *
+     * RTT controller can be either:
+     * a) Bound to a specific STA iface by passing in the corresponding
+     * |IWifiStaIface| object in the |boundIface| param, OR
+     * b) Let the implementation decide the iface to use for RTT operations
+     * by passing null in the |boundIface| param.
+     *
+     * @param boundIface AIDL interface object representing the STA iface if
+     *        the responder must be bound to a specific iface, null otherwise.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|
+     */
+    @PropagateAllowBlocking IWifiRttController createRttController(in IWifiStaIface boundIface);
+
+    /**
+     * Create a STA iface on the chip.
+     *
+     * Depending on the mode the chip is configured in, the interface creation
+     * may fail (code: |WifiStatusCode.ERROR_NOT_AVAILABLE|) if we've already
+     * reached the maximum allowed (specified in |ChipIfaceCombination|) number
+     * of ifaces of the STA type.
+     *
+     * @return AIDL interface object representing the iface if
+     *         successful, null otherwise.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|
+     */
+    @PropagateAllowBlocking IWifiStaIface createStaIface();
+
+    /**
+     * API to enable/disable alert notifications from the chip.
+     * These alerts must be used to notify the framework of any fatal error events
+     * that the chip encounters via |IWifiChipEventCallback.onDebugErrorAlert| method.
+     * Must fail if |ChipCapabilityMask.DEBUG_ERROR_ALERTS| is not set.
+     *
+     * @param enable true to enable, false to disable.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.NOT_AVAILABLE|,
+     *         |WifiStatusCode.UNKNOWN|
+     */
+    void enableDebugErrorAlerts(in boolean enable);
+
+    /**
+     * API to flush debug ring buffer data to files.
+     *
+     * Force flush debug ring buffer using IBase::debug.
+     * This API helps to collect firmware/driver/pkt logs.
+     *
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.UNKNOWN|
+     */
+    void flushRingBufferToFile();
+
+    /**
+     * API to force dump data into the corresponding ring buffer.
+     * This is to be invoked during bugreport collection.
+     *
+     * @param ringName Name of the ring for which data collection should
+     *        be forced. This can be retrieved via the corresponding
+     *        |WifiDebugRingBufferStatus|.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_NOT_STARTED|,
+     *         |WifiStatusCode.NOT_AVAILABLE|,
+     *         |WifiStatusCode.UNKNOWN|
+     */
+    void forceDumpToDebugRingBuffer(in String ringName);
+
+    /**
+     * Gets an AIDL interface object for the AP Iface corresponding
+     * to the provided ifname.
+     *
+     * @param ifname Name of the iface.
+     * @return AIDL interface object representing the iface if
+     *         it exists, null otherwise.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|
+     */
+    @PropagateAllowBlocking IWifiApIface getApIface(in String ifname);
+
+    /**
+     * List all the AP iface names configured on the chip.
+     * The corresponding |IWifiApIface| object for any iface
+     * can be retrieved using the |getApIface| method.
+     *
+     * @return List of all AP iface names on the chip.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|
+     */
+    String[] getApIfaceNames();
+
+    /**
+     * Get the set of operation modes that the chip supports.
+     *
+     * @return List of modes supported by the device.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|
+     */
+    ChipMode[] getAvailableModes();
+
+    /**
+     * Get the capabilities supported by this chip.
+     *
+     * @return Bitset of |ChipCapabilityMask| values.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    ChipCapabilityMask getCapabilities();
+
+    /**
+     * API to retrieve the wifi wake up reason stats for debugging.
+     * The driver is expected to start maintaining these stats once the chip
+     * is configured using |configureChip|. These stats must be reset whenever
+     * the chip is reconfigured or the HAL is stopped.
+     *
+     * @return Instance of |WifiDebugHostWakeReasonStats|.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.NOT_AVAILABLE|,
+     *         |WifiStatusCode.UNKNOWN|
+     */
+    WifiDebugHostWakeReasonStats getDebugHostWakeReasonStats();
+
+    /**
+     * The WiFi debug ring buffer life cycle is as follows:
+     * - At initialization, the framework must call |getDebugRingBuffersStatus|.
+     *   to obtain the names and list of supported ring buffers.
+     *   The driver may expose several different rings, each holding a different
+     *   type of data (connection events, power events, etc).
+     * - When WiFi operations start, the framework must call
+     *   |startLoggingToDebugRingBuffer| to trigger log collection for a specific
+     *   ring. The vebose level for each ring buffer can be specified in this API.
+     * - During wifi operations, the driver must periodically report per ring data
+     *   to framework by invoking the
+     *   |IWifiChipEventCallback.onDebugRingBufferDataAvailable| callback.
+     * - When capturing a bug report, the framework must indicate to driver that
+     *   all the data has to be uploaded urgently by calling |forceDumpToDebugRingBuffer|.
+     *
+     * The data uploaded by driver must be stored by the framework in separate files,
+     * with one stream of file per ring. The framework must store the files in pcapng
+     * format, allowing for easy merging and parsing with network analyzer tools.
+     * TODO: Since we're no longer dumping the raw data, storing in separate
+     * pcapng files for parsing later must not work anymore.
+     */
+
+    /*
+     * API to get the status of all ring buffers supported by driver.
+     *
+     * @return Vector of |WifiDebugRingBufferStatus| corresponding to the
+     *         status of each ring buffer on the device.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.NOT_AVAILABLE|,
+     *         |WifiStatusCode.UNKNOWN|
+     */
+    WifiDebugRingBufferStatus[] getDebugRingBuffersStatus();
+
+    /**
+     * Get the Id assigned to this chip.
+     *
+     * @return Assigned chip Id.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|
+     */
+    int getId();
+
+    /**
+     * Get the current mode that the chip is in.
+     *
+     * @return Mode that the chip is currently configured to,
+     *         corresponding to the Id property of the target ChipMode.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|
+     */
+    int getMode();
+
+    /**
+     * Gets an AIDL interface object for the NAN Iface corresponding
+     * to the provided ifname.
+     *
+     * @param ifname Name of the iface.
+     * @return AIDL interface object representing the iface if
+     *         it exists, null otherwise.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|
+     */
+    @PropagateAllowBlocking IWifiNanIface getNanIface(in String ifname);
+
+    /**
+     * List all the NAN iface names configured on the chip.
+     * The corresponding |IWifiNanIface| object for any iface can
+     * be retrieved using the |getNanIface| method.
+     *
+     * @return List of all NAN iface names on the chip.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|
+     */
+    String[] getNanIfaceNames();
+
+    /**
+     * Gets an AIDL interface object for the P2P Iface corresponding
+     * to the provided ifname.
+     *
+     * @param ifname Name of the iface.
+     * @return AIDL interface object representing the iface if
+     *         it exists, null otherwise.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|
+     */
+    @PropagateAllowBlocking IWifiP2pIface getP2pIface(in String ifname);
+
+    /**
+     * List all the P2P iface names configured on the chip.
+     * The corresponding |IWifiP2pIface| object for any iface can
+     * be retrieved using the |getP2pIface| method.
+     *
+     * @return List of all P2P iface names on the chip.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|
+     */
+    String[] getP2pIfaceNames();
+
+    /**
+     * Gets an AIDL interface object for the STA Iface corresponding
+     * to the provided ifname.
+     *
+     * @param ifname Name of the iface.
+     * @return AIDL interface object representing the iface if
+     *         it exists, null otherwise.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|
+     */
+    @PropagateAllowBlocking IWifiStaIface getStaIface(in String ifname);
+
+    /**
+     * List all the STA iface names configured on the chip.
+     * The corresponding |IWifiStaIface| object for any iface can
+     * be retrieved using the |getStaIface| method.
+     *
+     * @param List of all STA iface names on the chip.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|
+     */
+    String[] getStaIfaceNames();
+
+    /**
+     * Retrieve the list of all the possible radio combinations supported by this
+     * chip.
+     *
+     * @return A list of all the possible radio combinations represented by
+     *         |WifiRadioCombinationMatrix|.
+     *         For example, in case of a chip which has two radios, where one radio is
+     *         capable of 2.4GHz 2X2 only and another radio which is capable of either
+     *         5GHz or 6GHz 2X2, the number of possible radio combinations in this case
+     *         is 5 and the possible combinations are:
+     *         {{{2G 2X2}}, //Standalone 2G
+     *         {{5G 2X2}}, //Standalone 5G
+     *         {{6G 2X2}}, //Standalone 6G
+     *         {{2G 2X2}, {5G 2X2}}, //2G+5G DBS
+     *         {{2G 2X2}, {6G 2X2}}} //2G+6G DBS
+     *         Note: Since this chip doesn’t support 5G+6G simultaneous operation,
+     *         as there is only one radio which can support both bands, it can only
+     *         do MCC 5G+6G. This table should not get populated with possible MCC
+     *         configurations. This is only for simultaneous radio configurations
+     *         (such as standalone, multi band simultaneous or single band simultaneous).
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.FAILURE_UNKNOWN|
+     *
+     */
+    WifiRadioCombinationMatrix getSupportedRadioCombinationsMatrix();
+
+    /**
+     * Retrieve a list of usable Wifi channels for the specified band &
+     * operational modes.
+     *
+     * The list of usable Wifi channels in a given band depends on factors
+     * like current country code, operational mode (e.g. STA, SAP, WFD-CLI,
+     * WFD-GO, TDLS, NAN) and other restrictons due to DFS, cellular coexistence
+     * and concurrency state of the device.
+     *
+     * @param band |WifiBand| for which list of usable channels is requested.
+     * @param ifaceModeMask Bitmask of the modes represented by |WifiIfaceMode|.
+     *        Bitmask respresents all the modes that the caller is interested
+     *        in (e.g. STA, SAP, CLI, GO, TDLS, NAN). E.g. If the caller is
+     *        interested in knowing usable channels for P2P CLI, P2P GO & NAN,
+     *        ifaceModeMask would be set to
+     *        IFACE_MODE_P2P_CLIENT|IFACE_MODE_P2P_GO|IFACE_MODE_NAN.
+     * @param filterMask Bitmask of filters represented by
+     *        |UsableChannelFilter|. Specifies whether driver should filter
+     *        channels based on additional criteria. If no filter is specified,
+     *        then the driver should return usable channels purely based on
+     *        regulatory constraints.
+     * @return List of channels represented by |WifiUsableChannel|.
+     *         Each entry represents a channel frequency, bandwidth and
+     *         bitmask of modes (e.g. STA, SAP, CLI, GO, TDLS, NAN) that are
+     *         allowed on that channel. E.g. If only STA mode can be supported
+     *         on an indoor channel, only the IFACE_MODE_STA bit would be set
+     *         for that channel. If 5GHz SAP cannot be supported, then none of
+     *         the 5GHz channels will have IFACE_MODE_SOFTAP bit set.
+     *         Note: Bits do not represent concurrency state. Each bit only
+     *         represents whether a particular mode is allowed on that channel.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|,
+     *         |WifiStatusCode.FAILURE_UNKNOWN|
+     */
+    WifiUsableChannel[] getUsableChannels(
+            in WifiBand band, in WifiIfaceMode ifaceModeMask, in UsableChannelFilter filterMask);
+
+    /**
+     * Requests notifications of significant events on this chip. Multiple calls
+     * to this must register multiple callbacks, each of which must receive all
+     * events.
+     *
+     * @param callback An instance of the |IWifiChipEventCallback| AIDL interface
+     *        object.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|
+     */
+    void registerEventCallback(in IWifiChipEventCallback callback);
+
+    /**
+     * Removes the AP Iface with the provided ifname.
+     * Any further calls on the corresponding |IWifiApIface| AIDL interface
+     * object must fail.
+     *
+     * @param ifname Name of the iface.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|
+     */
+    void removeApIface(in String ifname);
+
+    /**
+     * Removes an instance of AP iface with name |ifaceInstanceName| from the
+     * bridge AP with name |brIfaceName|.
+     *
+     * Use the API |removeApIface| with the brIfaceName to remove the bridge iface.
+     *
+     * @param brIfaceName Name of the bridged AP iface.
+     * @param ifaceInstanceName Name of the AP instance. The empty instance is
+     *        invalid.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|
+     */
+    void removeIfaceInstanceFromBridgedApIface(in String brIfaceName, in String ifaceInstanceName);
+
+    /**
+     * Removes the NAN Iface with the provided ifname.
+     * Any further calls on the corresponding |IWifiNanIface| AIDL interface
+     * object must fail.
+     *
+     * @param ifname Name of the iface.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|
+     */
+    void removeNanIface(in String ifname);
+
+    /**
+     * Removes the P2P Iface with the provided ifname.
+     * Any further calls on the corresponding |IWifiP2pIface| AIDL interface
+     * object must fail.
+     *
+     * @param ifname Name of the iface.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|
+     */
+    void removeP2pIface(in String ifname);
+
+    /**
+     * Removes the STA Iface with the provided ifname.
+     * Any further calls on the corresponding |IWifiStaIface| AIDL interface
+     * object must fail.
+     *
+     * @param ifname Name of the iface.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|
+     */
+    void removeStaIface(in String ifname);
+
+    /**
+     * Request information about the chip.
+     *
+     * @return Instance of |ChipDebugInfo|.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    ChipDebugInfo requestChipDebugInfo();
+
+    /**
+     * Request vendor debug info from the driver.
+     *
+     * @return Vector of bytes retrieved from the driver.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    byte[] requestDriverDebugDump();
+
+    /**
+     * Request vendor debug info from the firmware.
+     *
+     * @return Vector of bytes retrieved from the firmware.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    byte[] requestFirmwareDebugDump();
+
+    /**
+     * API to reset TX power levels.
+     * This is used to indicate the end of the previously selected TX power
+     * scenario and let the wifi chip fall back to the default power values.
+     *
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.NOT_AVAILABLE|,
+     *         |WifiStatusCode.UNKNOWN|
+     */
+    void resetTxPowerScenario();
+
+    /**
+     * API to select one of the preset TX power scenarios.
+     *
+     * The framework must invoke this method with the appropriate scenario to let
+     * the wifi chip change its transmitting power levels.
+     * OEM's should define various power profiles for each of the scenarios
+     * above (defined in |TxPowerScenario|) in a vendor extension.
+     *
+     * @param scenario One of the preselected scenarios defined in
+     *        |TxPowerScenario|.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.NOT_AVAILABLE|,
+     *         |WifiStatusCode.UNKNOWN|
+     */
+    void selectTxPowerScenario(in TxPowerScenario scenario);
+
+    /**
+     * Invoked to indicate that the provided |CoexUnsafeChannels| should be avoided with the
+     * specified restrictions.
+     *
+     * Channel avoidance is a suggestion and should be done on a best-effort approach. If a provided
+     * channel is used, then the specified power cap should be applied.
+     *
+     * In addition, hard restrictions on the Wifi modes may be indicated by |CoexRestriction| bits
+     * (WIFI_DIRECT, SOFTAP, WIFI_AWARE) in the |restrictions| bitfield. If a hard restriction is
+     * provided, then the channels should be completely avoided for the provided Wifi modes instead
+     * of by best-effort.
+     *
+     * @param unsafeChannels List of |CoexUnsafeChannels| to avoid.
+     * @param restrictions Bitset of |CoexRestriction| values indicating Wifi interfaces to
+     *         completely avoid.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|,
+     */
+    void setCoexUnsafeChannels(
+            in CoexUnsafeChannel[] unsafeChannels, in CoexRestriction restrictions);
+
+    /**
+     * Set country code for this Wifi chip.
+     *
+     * Country code is global setting across the Wifi chip and not Wifi
+     * interface (STA or AP) specific.
+     *
+     * @param code 2 byte country code (as defined in ISO 3166) to set.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.FAILURE_UNKNOWN|,
+     *         |WifiStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void setCountryCode(in byte[2] code);
+
+    /**
+     * API to set the wifi latency mode
+     *
+     * The latency mode is a hint to the HAL to enable or disable Wi-Fi latency
+     * optimization. The optimization should be enabled if the mode is set to |LOW|
+     * and should be disabled if the mode is set to |NORMAL|.
+     * Wi-Fi latency optimization may trade-off latency against other Wi-Fi
+     * functionality such as scanning, roaming, etc. but it should not result in
+     * completely halting this functionality.
+     *
+     * The low latency mode targets applications such as gaming and virtual reality.
+     */
+    void setLatencyMode(in LatencyMode mode);
+
+    /**
+     * Invoked to indicate that the provided iface is the primary STA iface when more
+     * than 1 STA ifaces are concurrently active.
+     * Notes:
+     * - If the wifi firmware/chip cannot support multiple instances of any offload
+     *   (like roaming, APF, rssi threshold, etc), the firmware should ensure that these
+     *   offloads are at least enabled for the primary interface. If the new primary interface is
+     *   already connected to a network, the firmware must switch all the offloads on
+     *   this new interface without disconnecting.
+     * - When there is only 1 STA interface, the firmware must still retain the last primary
+     *   connection, which must become active the next time multi STA is enabled.
+     *
+     * @param ifname Name of the STA iface.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|
+     */
+    void setMultiStaPrimaryConnection(in String ifName);
+
+    /**
+     * Invoked to indicate the STA + STA use-case that is active.
+     *
+     * Refer to documentation of |MultiStaUseCase| for details.
+     *
+     * @param useCase Use case that is active.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|
+     */
+    void setMultiStaUseCase(in MultiStaUseCase useCase);
+
+    /**
+     * API to trigger the debug data collection.
+     *
+     * @param ringName Name of the ring for which data collection
+     *        shall start. This can be retrieved via the corresponding
+     *        |WifiDebugRingBufferStatus|.
+     * @param verboseLevel Verbose level for logging.
+     * @parm maxIntervalInSec Maximum interval in seconds for driver to invoke
+     *       |onDebugRingBufferData|, ignore if zero.
+     * @parm minDataSizeInBytes: Minimum data size in buffer for driver to invoke
+     *       |onDebugRingBufferData|, ignore if zero.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.NOT_AVAILABLE|,
+     *         |WifiStatusCode.UNKNOWN|
+     */
+    void startLoggingToDebugRingBuffer(in String ringName,
+            in WifiDebugRingBufferVerboseLevel verboseLevel, in int maxIntervalInSec,
+            in int minDataSizeInBytes);
+
+    /**
+     * API to stop the debug data collection for all ring buffers.
+     *
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.NOT_AVAILABLE|,
+     *         |WifiStatusCode.UNKNOWN|
+     */
+    void stopLoggingToDebugRingBuffer();
+
+    /**
+     * Trigger subsystem restart.
+     *
+     * If the framework detects a problem (e.g. connection failure),
+     * it must call this function to attempt recovery.
+     *
+     * When the wifi HAL receives |triggerSubsystemRestart|, it must restart
+     * the wlan subsystem, especially the wlan firmware.
+     *
+     * Regarding the callback function for subsystem restart, refer to documentation of
+     * |IWifiEventCallback.onSubsystemRestart| for details.
+     *
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void triggerSubsystemRestart();
+}
diff --git a/wifi/aidl/android/hardware/wifi/IWifiChipEventCallback.aidl b/wifi/aidl/android/hardware/wifi/IWifiChipEventCallback.aidl
new file mode 100644
index 0000000..2bc4c0e
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/IWifiChipEventCallback.aidl
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+import android.hardware.wifi.IfaceType;
+import android.hardware.wifi.WifiBand;
+import android.hardware.wifi.WifiDebugRingBufferStatus;
+import android.hardware.wifi.WifiStatusCode;
+
+/**
+ * Wifi chip event callbacks.
+ */
+@VintfStability
+oneway interface IWifiChipEventCallback {
+    /**
+     * Struct describing the state of each iface operating on the radio chain
+     * (hardware MAC) on the device.
+     */
+    @VintfStability
+    parcelable IfaceInfo {
+        /**
+         * Name of the interface (ex. wlan0).
+         */
+        String name;
+        /**
+         * Wifi channel on which this interface is operating.
+         */
+        int channel;
+    }
+
+    /**
+     * Struct describing the state of each hardware radio chain (hardware MAC)
+     * on the device.
+     */
+    @VintfStability
+    parcelable RadioModeInfo {
+        /**
+         * Identifier for this radio chain. This is vendor dependent and used
+         * only for debugging purposes.
+         */
+        int radioId;
+        /**
+         * List of bands on which this radio chain is operating.
+         * Can be one of:
+         * a) |WifiBand.BAND_24GHZ| => 2.4Ghz.
+         * b) |WifiBand.BAND_5GHZ| => 5Ghz.
+         * c) |WifiBand.BAND_24GHZ_5GHZ| => 2.4Ghz + 5Ghz (Radio is time sharing
+         * across the 2 bands).
+         * d) |WifiBand.BAND_6GHZ| => 6Ghz.
+         * e) |WifiBand.BAND_5GHZ_6GHZ| => 5Ghz + 6Ghz (Radio is time sharing
+         * across the 2 bands).
+         * f) |WifiBand.BAND_24GHZ_5GHZ_6GHZ| => 2.4Ghz + 5Ghz + 6Ghz (Radio is
+         * time sharing across the 3 bands).
+         */
+        WifiBand bandInfo;
+        /**
+         * List of interfaces on this radio chain (hardware MAC).
+         */
+        IfaceInfo[] ifaceInfos;
+    }
+
+    /**
+     * Callback indicating that a chip reconfiguration failed. This is a fatal
+     * error and any iface objects available previously must be considered
+     * invalid. The client can attempt to recover by trying to reconfigure the
+     * chip again using |IWifiChip.configureChip|.
+     *
+     * @param status Failure reason code.
+     */
+    void onChipReconfigureFailure(in WifiStatusCode status);
+
+    /**
+     * Callback indicating that the chip has been reconfigured successfully. At
+     * this point the interfaces available in the mode must be able to be
+     * configured. When this is called, any previous iface objects must be
+     * considered invalid.
+     *
+     * @param modeId The mode that the chip switched to, corresponding to the id
+     *        property of the target ChipMode.
+     */
+    void onChipReconfigured(in int modeId);
+
+    /**
+     * Callback indicating that the chip has encountered a fatal error.
+     * Client must not attempt to parse either the errorCode or debugData.
+     * Must only be captured in a bugreport.
+     *
+     * @param errorCode Vendor defined error code.
+     * @param debugData Vendor defined data used for debugging.
+     */
+    void onDebugErrorAlert(in int errorCode, in byte[] debugData);
+
+    /**
+     * Callbacks for reporting debug ring buffer data.
+     *
+     * The ring buffer data collection is event based:
+     * - Driver calls this callback when new records are available, the
+     *   |WifiDebugRingBufferStatus| passed up to framework in the callback
+     *   indicates to framework if more data is available in the ring buffer.
+     *   It is not expected that driver will necessarily always empty the ring
+     *   immediately as data is available. Instead the driver will report data
+     *   every X seconds, or if N bytes are available, based on the parameters
+     *   set via |startLoggingToDebugRingBuffer|.
+     * - In the case where a bug report has to be captured, the framework will
+     *   require driver to upload all data immediately. This is indicated to
+     *   driver when framework calls |forceDumpToDebugRingBuffer|. The driver
+     *   will start sending all available data in the indicated ring by repeatedly
+     *   invoking this callback.
+     *
+     * @param status Status of the corresponding ring buffer. This should
+     *         contain the name of the ring buffer on which the data is
+     *         available.
+     * @param data Raw bytes of data sent by the driver. Must be dumped
+     *         out to a bugreport and post processed.
+     */
+    void onDebugRingBufferDataAvailable(in WifiDebugRingBufferStatus status, in byte[] data);
+
+    /**
+     * Callback indicating that a new iface has been added to the chip.
+     *
+     * @param type Type of iface added.
+     * @param name Name of iface added.
+     */
+    void onIfaceAdded(in IfaceType type, in String name);
+
+    /**
+     * Callback indicating that an existing iface has been removed from the chip.
+     *
+     * @param type Type of iface removed.
+     * @param name Name of iface removed.
+     */
+    void onIfaceRemoved(in IfaceType type, in String name);
+
+    /**
+     * Indicates a radio mode change.
+     * Radio mode change could be a result of:
+     * a) Bringing up concurrent interfaces (ex. STA + AP).
+     * b) Change in operating band of one of the concurrent interfaces
+     * ( ex. STA connection moved from 2.4G to 5G)
+     *
+     * @param radioModeInfos List of RadioModeInfo structures for each
+     *        radio chain (hardware MAC) on the device.
+     */
+    void onRadioModeChange(in RadioModeInfo[] radioModeInfos);
+}
diff --git a/wifi/aidl/android/hardware/wifi/IWifiEventCallback.aidl b/wifi/aidl/android/hardware/wifi/IWifiEventCallback.aidl
new file mode 100644
index 0000000..761bbf5
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/IWifiEventCallback.aidl
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+import android.hardware.wifi.WifiStatusCode;
+
+@VintfStability
+oneway interface IWifiEventCallback {
+    /**
+     * Called when the Wi-Fi system failed in a way that caused it be disabled.
+     * Calling start again must restart Wi-Fi as if stop then start was called
+     * (full state reset). When this event is received all IWifiChip & IWifiIface
+     * objects retrieved after the last call to start will be considered invalid.
+     *
+     * @param status Failure reason code.
+     */
+    void onFailure(in WifiStatusCode status);
+
+    /**
+     * Called in response to a call to start indicating that the operation
+     * completed. After this callback the HAL must be fully operational.
+     */
+    void onStart();
+
+    /**
+     * Called in response to a call to stop indicating that the operation
+     * completed. When this event is received all IWifiChip objects retrieved
+     * after the last call to start will be considered invalid.
+     */
+    void onStop();
+
+    /**
+     * Must be called when the Wi-Fi subsystem restart completes.
+     * Once this event is received, framework must fully reset the Wi-Fi stack state.
+     *
+     * @param status Status code.
+     */
+    void onSubsystemRestart(in WifiStatusCode status);
+}
diff --git a/wifi/aidl/android/hardware/wifi/IWifiNanIface.aidl b/wifi/aidl/android/hardware/wifi/IWifiNanIface.aidl
new file mode 100644
index 0000000..45644b4
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/IWifiNanIface.aidl
@@ -0,0 +1,251 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+import android.hardware.wifi.IWifiNanIfaceEventCallback;
+import android.hardware.wifi.NanConfigRequest;
+import android.hardware.wifi.NanConfigRequestSupplemental;
+import android.hardware.wifi.NanEnableRequest;
+import android.hardware.wifi.NanInitiateDataPathRequest;
+import android.hardware.wifi.NanPublishRequest;
+import android.hardware.wifi.NanRespondToDataPathIndicationRequest;
+import android.hardware.wifi.NanSubscribeRequest;
+import android.hardware.wifi.NanTransmitFollowupRequest;
+
+/**
+ * Interface used to represent a single NAN (Neighbour Aware Network) iface.
+ *
+ * References to "NAN Spec" are to the Wi-Fi Alliance "Wi-Fi Neighbor Awareness
+ * Networking (NAN) Technical Specification".
+ */
+@VintfStability
+interface IWifiNanIface {
+    /**
+     * Minimum length of Passphrase argument for a data-path configuration.
+     */
+    const int MIN_DATA_PATH_CONFIG_PASSPHRASE_LENGTH = 8;
+
+    /**
+     * Maximum length of Passphrase argument for a data-path configuration.
+     */
+    const int MAX_DATA_PATH_CONFIG_PASSPHRASE_LENGTH = 63;
+
+    /**
+     * Get the name of this iface.
+     *
+     * @return Name of this iface.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|
+     */
+    String getName();
+
+    /**
+     * Configures an existing NAN functionality (i.e. assumes
+     * |IWifiNanIface.enableRequest| already submitted and succeeded).
+     * Asynchronous response is with |IWifiNanIfaceEventCallback.notifyConfigResponse|.
+     *
+     * @param cmdId Command Id to use for this invocation.
+     * @param msg1 Instance of |NanConfigRequest|.
+     * @param msg2 Instance of |NanConfigRequestSupplemental|.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void configRequest(
+            in char cmdId, in NanConfigRequest msg1, in NanConfigRequestSupplemental msg2);
+
+    /**
+     * Create a NAN Data Interface.
+     * Asynchronous response is with |IWifiNanIfaceEventCallback.notifyCreateDataInterfaceResponse|.
+     *
+     * @param cmdId Command Id to use for this invocation.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void createDataInterfaceRequest(in char cmdId, in String ifaceName);
+
+    /**
+     * Delete a NAN Data Interface.
+     * Asynchronous response is with |IWifiNanIfaceEventCallback.notifyDeleteDataInterfaceResponse|.
+     *
+     * @param cmdId Command Id to use for this invocation.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void deleteDataInterfaceRequest(in char cmdId, in String ifaceName);
+
+    /**
+     * Disable NAN functionality.
+     * Asynchronous response is with |IWifiNanIfaceEventCallback.notifyDisableResponse|.
+     *
+     * @param cmdId Command Id to use for this invocation.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void disableRequest(in char cmdId);
+
+    /**
+     * Configures and activates NAN clustering (does not start
+     * a discovery session or set up data-interfaces or data-paths). Use the
+     * |IWifiNanIface.configureRequest| method to change the configuration of an already enabled
+     * NAN interface.
+     * Asynchronous response is with |IWifiNanIfaceEventCallback.notifyEnableResponse|.
+     *
+     * @param cmdId Command Id to use for this invocation.
+     * @param msg1 Instance of |NanEnableRequest|.
+     * @param msg2 Instance of |NanConfigRequestSupplemental|.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void enableRequest(
+            in char cmdId, in NanEnableRequest msg1, in NanConfigRequestSupplemental msg2);
+
+    /**
+     * Get NAN capabilities. Asynchronous response is with
+     * |IWifiNanIfaceEventCallback.notifyCapabilitiesResponse|.
+     *
+     * @param cmdId Command Id to use for this invocation.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void getCapabilitiesRequest(in char cmdId);
+
+    /**
+     * Initiate a data-path (NDP) setup operation: Initiator.
+     * Asynchronous response is with |IWifiNanIfaceEventCallback.notifyInitiateDataPathResponse|.
+     *
+     * @param cmdId Command Id to use for this invocation.
+     * @param msg Instance of |NanInitiateDataPathRequest|.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void initiateDataPathRequest(in char cmdId, in NanInitiateDataPathRequest msg);
+
+    /**
+     * Requests notifications of significant events on this iface. Multiple calls
+     * to this must register multiple callbacks, each of which must receive all
+     * events.
+     *
+     * @param callback An instance of the |IWifiNanIfaceEventCallback| AIDL interface
+     *        object.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|
+     */
+    void registerEventCallback(in IWifiNanIfaceEventCallback callback);
+
+    /**
+     * Respond to a received data indication as part of a data-path (NDP) setup operation.
+     * An indication is received by the Responder from the Initiator.
+     * Asynchronous response is with
+     * |IWifiNanIfaceEventCallback.notifyRespondToDataPathIndicationResponse|.
+     *
+     * @param cmdId Command Id to use for this invocation.
+     * @param msg Instance of |NanRespondToDataPathIndicationRequest|.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void respondToDataPathIndicationRequest(
+            in char cmdId, in NanRespondToDataPathIndicationRequest msg);
+
+    /**
+     * Publish request to start advertising a discovery service.
+     * Asynchronous response is with |IWifiNanIfaceEventCallback.notifyStartPublishResponse|.
+     *
+     * @param cmdId Command Id to use for this invocation.
+     * @param msg Instance of |NanPublishRequest|.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void startPublishRequest(in char cmdId, in NanPublishRequest msg);
+
+    /**
+     * Subscribe request to start searching for a discovery service.
+     * Asynchronous response is with |IWifiNanIfaceEventCallback.notifyStartSubscribeResponse|.
+     *
+     * @param cmdId Command Id to use for this invocation.
+     * @param msg Instance of |NanSubscribeRequest|.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void startSubscribeRequest(in char cmdId, in NanSubscribeRequest msg);
+
+    /**
+     * Stop publishing a discovery service.
+     * Asynchronous response is with |IWifiNanIfaceEventCallback.notifyStopPublishResponse|.
+     *
+     * @param cmdId Command Id to use for this invocation.
+     * @param sessionId ID of the publish discovery session to be stopped.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void stopPublishRequest(in char cmdId, in byte sessionId);
+
+    /**
+     * Stop subscribing to a discovery service.
+     * Asynchronous response is with |IWifiNanIfaceEventCallback.notifyStopSubscribeResponse|.
+     *
+     * @param cmdId Command Id to use for this invocation.
+     * @param sessionId ID of the subscribe discovery session to be stopped.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void stopSubscribeRequest(in char cmdId, in byte sessionId);
+
+    /**
+     * Data-path (NDP) termination request. Executed by either Initiator or Responder.
+     * Asynchronous response is with |IWifiNanIfaceEventCallback.notifyTerminateDataPathResponse|.
+     *
+     * @param cmdId Command Id to use for this invocation.
+     * @param ndpInstanceId Data-path instance ID to be terminated.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void terminateDataPathRequest(in char cmdId, in int ndpInstanceId);
+
+    /**
+     * NAN transmit follow up message request.
+     * Asynchronous response is with |IWifiNanIfaceEventCallback.notifyTransmitFollowupResponse|.
+     *
+     * @param cmdId Command Id to use for this invocation.
+     * @param msg Instance of |NanTransmitFollowupRequest|.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void transmitFollowupRequest(in char cmdId, in NanTransmitFollowupRequest msg);
+}
diff --git a/wifi/aidl/android/hardware/wifi/IWifiNanIfaceEventCallback.aidl b/wifi/aidl/android/hardware/wifi/IWifiNanIfaceEventCallback.aidl
new file mode 100644
index 0000000..470b7ba
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/IWifiNanIfaceEventCallback.aidl
@@ -0,0 +1,322 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+import android.hardware.wifi.NanCapabilities;
+import android.hardware.wifi.NanClusterEventInd;
+import android.hardware.wifi.NanDataPathConfirmInd;
+import android.hardware.wifi.NanDataPathRequestInd;
+import android.hardware.wifi.NanDataPathScheduleUpdateInd;
+import android.hardware.wifi.NanFollowupReceivedInd;
+import android.hardware.wifi.NanMatchInd;
+import android.hardware.wifi.NanStatus;
+
+/**
+ * NAN Response and Asynchronous Event Callbacks.
+ *
+ * References to "NAN Spec" are to the Wi-Fi Alliance "Wi-Fi Neighbor Awareness
+ * Networking (NAN) Technical Specification".
+ */
+@VintfStability
+oneway interface IWifiNanIfaceEventCallback {
+    /**
+     * Callback indicating that a cluster event has been received.
+     *
+     * @param event NanClusterEventInd containing event details.
+     */
+    void eventClusterEvent(in NanClusterEventInd event);
+
+    /**
+     * Callback indicating that a data-path (NDP) setup has been completed.
+     * Received by both Initiator and Responder.
+     *
+     * @param event NanDataPathConfirmInd containing event details.
+     */
+    void eventDataPathConfirm(in NanDataPathConfirmInd event);
+
+    /**
+     * Callback indicating that a data-path (NDP) setup has been requested by
+     * an Initiator peer (received by the intended Responder).
+     *
+     * @param event NanDataPathRequestInd containing event details.
+     */
+    void eventDataPathRequest(in NanDataPathRequestInd event);
+
+    /**
+     * Callback indicating that a data-path (NDP) schedule has been updated
+     * (e.g. channels have been changed).
+     *
+     * @param event NanDataPathScheduleUpdateInd containing event details.
+     */
+    void eventDataPathScheduleUpdate(in NanDataPathScheduleUpdateInd event);
+
+    /**
+     * Callback indicating that a list of data-paths (NDP) have been terminated.
+     * Received by both Initiator and Responder.
+     *
+     * @param ndpInstanceId Data-path ID of the terminated data-path.
+     */
+    void eventDataPathTerminated(in int ndpInstanceId);
+
+    /**
+     * Callback indicating that a NAN has been disabled.
+     *
+     * @param status NanStatus describing the reason for the disable event.
+     *               Possible status codes are:
+     *               |NanStatusCode.SUCCESS|
+     *               |NanStatusCode.UNSUPPORTED_CONCURRENCY_NAN_DISABLED|
+     */
+    void eventDisabled(in NanStatus status);
+
+    /**
+     * Callback indicating that a followup message has been received from a peer.
+     *
+     * @param event NanFollowupReceivedInd containing event details.
+     */
+    void eventFollowupReceived(in NanFollowupReceivedInd event);
+
+    /**
+     * Callback indicating that a match has occurred: i.e. a service has been
+     * discovered.
+     *
+     * @param event NanMatchInd containing event details.
+     */
+    void eventMatch(in NanMatchInd event);
+
+    /**
+     * Callback indicating that a previously discovered match (service) has expired.
+     *
+     * @param discoverySessionId Discovery session ID of the expired match.
+     * @param peerId Peer ID of the expired match.
+     */
+    void eventMatchExpired(in byte discoverySessionId, in int peerId);
+
+    /**
+     * Callback indicating that an active publish session has terminated.
+     *
+     * @param sessionId Discovery session ID of the terminated session.
+     * @param status NanStatus describing the reason for the session termination.
+     *               Possible status codes are:
+     *               |NanStatusCode.SUCCESS|
+     */
+    void eventPublishTerminated(in byte sessionId, in NanStatus status);
+
+    /**
+     * Callback indicating that an active subscribe session has terminated.
+     *
+     * @param sessionId Discovery session ID of the terminated session.
+     * @param status NanStatus describing the reason for the session termination.
+     *               Possible status codes are:
+     *               |NanStatusCode.SUCCESS|
+     */
+    void eventSubscribeTerminated(in byte sessionId, in NanStatus status);
+
+    /**
+     * Callback providing status on a completed followup message transmit operation.
+     *
+     * @param cmdId Command Id corresponding to the original |transmitFollowupRequest| request.
+     * @param status NanStatus of the operation. Possible status codes are:
+     *               |NanStatusCode.SUCCESS|
+     *               |NanStatusCode.NO_OTA_ACK|
+     *               |NanStatusCode.PROTOCOL_FAILURE|
+     */
+    void eventTransmitFollowup(in char id, in NanStatus status);
+
+    /**
+     * Callback invoked in response to a capability request
+     * |IWifiNanIface.getCapabilitiesRequest|.
+     *
+     * @param cmdId Command Id corresponding to the original request.
+     * @param status NanStatus of the operation. Possible status codes are:
+     *        |NanStatusCode.SUCCESS|
+     * @param capabilities Capability data.
+     */
+    void notifyCapabilitiesResponse(
+            in char id, in NanStatus status, in NanCapabilities capabilities);
+
+    /**
+     * Callback invoked in response to a config request |IWifiNanIface.configRequest|.
+     *
+     * @param cmdId Command Id corresponding to the original request.
+     * @param status NanStatus of the operation. Possible status codes are:
+     *        |NanStatusCode.SUCCESS|
+     *        |NanStatusCode.INVALID_ARGS|
+     *        |NanStatusCode.INTERNAL_FAILURE|
+     *        |NanStatusCode.PROTOCOL_FAILURE|
+     */
+    void notifyConfigResponse(in char id, in NanStatus status);
+
+    /**
+     * Callback invoked in response to a create data interface request
+     * |IWifiNanIface.createDataInterfaceRequest|.
+     *
+     * @param cmdId Command Id corresponding to the original request.
+     * @param status NanStatus of the operation. Possible status codes are:
+     *        |NanStatusCode.SUCCESS|
+     *        |NanStatusCode.INVALID_ARGS|
+     *        |NanStatusCode.INTERNAL_FAILURE|
+     */
+    void notifyCreateDataInterfaceResponse(in char id, in NanStatus status);
+
+    /**
+     * Callback invoked in response to a delete data interface request
+     * |IWifiNanIface.deleteDataInterfaceRequest|.
+     *
+     * @param cmdId Command Id corresponding to the original request.
+     * @param status NanStatus of the operation. Possible status codes are:
+     *        |NanStatusCode.SUCCESS|
+     *        |NanStatusCode.INVALID_ARGS|
+     *        |NanStatusCode.INTERNAL_FAILURE|
+     */
+    void notifyDeleteDataInterfaceResponse(in char id, in NanStatus status);
+
+    /**
+     * Callback invoked in response to a disable request |IWifiNanIface.disableRequest|.
+     *
+     * @param cmdId Command Id corresponding to the original request.
+     * @param status NanStatus of the operation. Possible status codes are:
+     *        |NanStatusCode.SUCCESS|
+     *        |NanStatusCode.PROTOCOL_FAILURE|
+     */
+    void notifyDisableResponse(in char id, in NanStatus status);
+
+    /**
+     * Callback invoked in response to an enable request |IWifiNanIface.enableRequest|.
+     *
+     * @param cmdId Command Id corresponding to the original request.
+     * @param status NanStatus of the operation. Possible status codes are:
+     *        |NanStatusCode.SUCCESS|
+     *        |NanStatusCode.ALREADY_ENABLED|
+     *        |NanStatusCode.INVALID_ARGS|
+     *        |NanStatusCode.INTERNAL_FAILURE|
+     *        |NanStatusCode.PROTOCOL_FAILURE|
+     *        |NanStatusCode.NAN_NOT_ALLOWED|
+     */
+    void notifyEnableResponse(in char id, in NanStatus status);
+
+    /**
+     * Callback invoked in response to an initiate data path request
+     * |IWifiNanIface.initiateDataPathRequest|.
+     *
+     * @param cmdId Command Id corresponding to the original request.
+     * @param status NanStatus of the operation. Possible status codes are:
+     *        |NanStatusCode.SUCCESS|
+     *        |NanStatusCode.INVALID_ARGS|
+     *        |NanStatusCode.INTERNAL_FAILURE|
+     *        |NanStatusCode.PROTOCOL_FAILURE|
+     *        |NanStatusCode.INVALID_PEER_ID|
+     * @param ndpInstanceId ID of the new data path being negotiated (on successful status).
+     */
+    void notifyInitiateDataPathResponse(in char id, in NanStatus status, in int ndpInstanceId);
+
+    /**
+     * Callback invoked in response to a respond to data path indication request
+     * |IWifiNanIface.respondToDataPathIndicationRequest|.
+     *
+     * @param cmdId Command Id corresponding to the original request.
+     * @param status NanStatus of the operation. Possible status codes are:
+     *        |NanStatusCode.SUCCESS|
+     *        |NanStatusCode.INVALID_ARGS|
+     *        |NanStatusCode.INTERNAL_FAILURE|
+     *        |NanStatusCode.PROTOCOL_FAILURE|
+     *        |NanStatusCode.INVALID_NDP_ID|
+     */
+    void notifyRespondToDataPathIndicationResponse(in char id, in NanStatus status);
+
+    /**
+     * Callback invoked to notify the status of the start publish request
+     * |IWifiNanIface.startPublishRequest|.
+     *
+     * @param cmdId Command Id corresponding to the original request.
+     * @param status NanStatus of the operation. Possible status codes are:
+     *        |NanStatusCode.SUCCESS|
+     *        |NanStatusCode.INVALID_ARGS|
+     *        |NanStatusCode.PROTOCOL_FAILURE|
+     *        |NanStatusCode.NO_RESOURCES_AVAILABLE|
+     *        |NanStatusCode.INVALID_SESSION_ID|
+     * @param sessionId ID of the new publish session (if successfully created).
+     */
+    void notifyStartPublishResponse(in char id, in NanStatus status, in byte sessionId);
+
+    /**
+     * Callback invoked to notify the status of the start subscribe request
+     * |IWifiNanIface.startSubscribeRequest|.
+     *
+     * @param cmdId Command Id corresponding to the original request.
+     * @param status NanStatus of the operation. Possible status codes are:
+     *        |NanStatusCode.SUCCESS|
+     *        |NanStatusCode.INVALID_ARGS|
+     *        |NanStatusCode.PROTOCOL_FAILURE|
+     *        |NanStatusCode.NO_RESOURCES_AVAILABLE|
+     *        |NanStatusCode.INVALID_SESSION_ID|
+     * @param sessionId ID of the new subscribe session (if successfully created).
+     */
+    void notifyStartSubscribeResponse(in char id, in NanStatus status, in byte sessionId);
+
+    /**
+     * Callback invoked in response to a stop publish request
+     * |IWifiNanIface.stopPublishRequest|.
+     *
+     * @param cmdId Command Id corresponding to the original request.
+     * @param status NanStatus of the operation. Possible status codes are:
+     *        |NanStatusCode.SUCCESS|
+     *        |NanStatusCode.INVALID_SESSION_ID|
+     *        |NanStatusCode.INTERNAL_FAILURE|
+     */
+    void notifyStopPublishResponse(in char id, in NanStatus status);
+
+    /**
+     * Callback invoked in response to a stop subscribe request
+     * |IWifiNanIface.stopSubscribeRequest|.
+     *
+     * @param cmdId Command Id corresponding to the original request.
+     * @param status NanStatus of the operation. Possible status codes are:
+     *        |NanStatusCode.SUCCESS|
+     *        |NanStatusCode.INVALID_SESSION_ID|
+     *        |NanStatusCode.INTERNAL_FAILURE|
+     */
+    void notifyStopSubscribeResponse(in char id, in NanStatus status);
+
+    /**
+     * Callback invoked in response to a terminate data path request
+     * |IWifiNanIface.terminateDataPathRequest|.
+     *
+     * @param cmdId Command Id corresponding to the original request.
+     * @param status NanStatus of the operation. Possible status codes are:
+     *        |NanStatusCode.SUCCESS|
+     *        |NanStatusCode.INVALID_ARGS|
+     *        |NanStatusCode.INTERNAL_FAILURE|
+     *        |NanStatusCode.PROTOCOL_FAILURE|
+     *        |NanStatusCode.INVALID_NDP_ID|
+     */
+    void notifyTerminateDataPathResponse(in char id, in NanStatus status);
+
+    /**
+     * Callback invoked in response to a transmit followup request
+     * |IWifiNanIface.transmitFollowupRequest|.
+     *
+     * @param cmdId Command Id corresponding to the original request.
+     * @param status NanStatus of the operation. Possible status codes are:
+     *        |NanStatusCode.SUCCESS|
+     *        |NanStatusCode.INVALID_ARGS|
+     *        |NanStatusCode.INTERNAL_FAILURE|
+     *        |NanStatusCode.INVALID_SESSION_ID|
+     *        |NanStatusCode.INVALID_PEER_ID|
+     *        |NanStatusCode.FOLLOWUP_TX_QUEUE_FULL|
+     */
+    void notifyTransmitFollowupResponse(in char id, in NanStatus status);
+}
diff --git a/wifi/aidl/android/hardware/wifi/IWifiP2pIface.aidl b/wifi/aidl/android/hardware/wifi/IWifiP2pIface.aidl
new file mode 100644
index 0000000..287f41d
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/IWifiP2pIface.aidl
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+/**
+ * Interface used to represent a single P2P iface.
+ */
+@VintfStability
+interface IWifiP2pIface {
+    /**
+     * Get the name of this iface.
+     *
+     * @return Name of this iface.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|
+     */
+    String getName();
+}
diff --git a/wifi/aidl/android/hardware/wifi/IWifiRttController.aidl b/wifi/aidl/android/hardware/wifi/IWifiRttController.aidl
new file mode 100644
index 0000000..99e1a81
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/IWifiRttController.aidl
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+import android.hardware.wifi.IWifiRttControllerEventCallback;
+import android.hardware.wifi.IWifiStaIface;
+import android.hardware.wifi.MacAddress;
+import android.hardware.wifi.RttCapabilities;
+import android.hardware.wifi.RttConfig;
+import android.hardware.wifi.RttLciInformation;
+import android.hardware.wifi.RttLcrInformation;
+import android.hardware.wifi.RttResponder;
+import android.hardware.wifi.WifiChannelInfo;
+
+/**
+ * Interface used to perform RTT (Round trip time) operations.
+ */
+@VintfStability
+interface IWifiRttController {
+    /**
+     * Disable RTT responder mode.
+     *
+     * @param cmdId Command Id corresponding to the original request.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_RTT_CONTROLLER_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void disableResponder(in int cmdId);
+
+    /**
+     * Enable RTT responder mode.
+     *
+     * @param cmdId Command Id to use for this invocation.
+     * @parm channelHint Hint for the channel information where RTT responder
+     *       must be enabled on.
+     * @param maxDurationInSeconds Timeout of responder mode.
+     * @param info Instance of |RttResponderInfo|.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_RTT_CONTROLLER_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void enableResponder(in int cmdId, in WifiChannelInfo channelHint, in int maxDurationInSeconds,
+            in RttResponder info);
+
+    /**
+     * Get the iface on which the RTT operations must be performed.
+     *
+     * @return AIDL interface object representing the iface if bound
+     *         to a specific iface, null otherwise
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_RTT_CONTROLLER_INVALID|
+     */
+    IWifiStaIface getBoundIface();
+
+    /**
+     * RTT capabilities of the device.
+     *
+     * @return Instance of |RttCapabilities|.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_RTT_CONTROLLER_INVALID|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    RttCapabilities getCapabilities();
+
+    /**
+     * Get RTT responder information (e.g. WiFi channel) to enable responder on.
+     *
+     * @return Instance of |RttResponderInfo|.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_RTT_CONTROLLER_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    RttResponder getResponderInfo();
+
+    /**
+     * API to cancel RTT measurements.
+     *
+     * @param cmdId Command Id corresponding to the original request.
+     * @param addrs Vector of addresses for which to cancel.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_RTT_CONTROLLER_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void rangeCancel(in int cmdId, in MacAddress[] addrs);
+
+    /**
+     * API to request RTT measurement.
+     *
+     * @param cmdId Command Id to use for this invocation.
+     * @param rttConfigs Vector of |RttConfig| parameters.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_RTT_CONTROLLER_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void rangeRequest(in int cmdId, in RttConfig[] rttConfigs);
+
+    /**
+     * Requests notifications of significant events on this RTT controller.
+     * Multiple calls to this must register multiple callbacks, each of which
+     * must receive all events.
+     *
+     * @param callback An instance of the |IWifiRttControllerEventCallback| AIDL
+     *        interface object.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|
+     */
+    void registerEventCallback(in IWifiRttControllerEventCallback callback);
+
+    /**
+     * API to configure the LCI (Location civic information).
+     * Used in RTT Responder mode only.
+     *
+     * @param cmdId Command Id to use for this invocation.
+     * @param lci Instance of |RttLciInformation|.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_RTT_CONTROLLER_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void setLci(in int cmdId, in RttLciInformation lci);
+
+    /**
+     * API to configure the LCR (Location civic records).
+     * Used in RTT Responder mode only.
+     *
+     * @param cmdId Command Id to use for this invocation.
+     * @param lcr Instance of |RttLcrInformation|.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_RTT_CONTROLLER_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void setLcr(in int cmdId, in RttLcrInformation lcr);
+}
diff --git a/wifi/aidl/android/hardware/wifi/IWifiRttControllerEventCallback.aidl b/wifi/aidl/android/hardware/wifi/IWifiRttControllerEventCallback.aidl
new file mode 100644
index 0000000..89f0ed8
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/IWifiRttControllerEventCallback.aidl
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+import android.hardware.wifi.RttResult;
+
+/**
+ * RTT Response and Event Callbacks.
+ */
+@VintfStability
+oneway interface IWifiRttControllerEventCallback {
+    /**
+     * Invoked when an RTT result is available.
+     *
+     * @param cmdId Command Id corresponding to the original request.
+     * @param results Vector of |RttResult| instances.
+     */
+    void onResults(in int cmdId, in RttResult[] results);
+}
diff --git a/wifi/aidl/android/hardware/wifi/IWifiStaIface.aidl b/wifi/aidl/android/hardware/wifi/IWifiStaIface.aidl
new file mode 100644
index 0000000..2dd57b2
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/IWifiStaIface.aidl
@@ -0,0 +1,555 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+import android.hardware.wifi.IWifiStaIfaceEventCallback;
+import android.hardware.wifi.StaApfPacketFilterCapabilities;
+import android.hardware.wifi.StaBackgroundScanCapabilities;
+import android.hardware.wifi.StaBackgroundScanParameters;
+import android.hardware.wifi.StaLinkLayerStats;
+import android.hardware.wifi.StaRoamingCapabilities;
+import android.hardware.wifi.StaRoamingConfig;
+import android.hardware.wifi.StaRoamingState;
+import android.hardware.wifi.WifiBand;
+import android.hardware.wifi.WifiDebugRxPacketFateReport;
+import android.hardware.wifi.WifiDebugTxPacketFateReport;
+
+/**
+ * Interface used to represent a single STA iface.
+ */
+@VintfStability
+interface IWifiStaIface {
+    /**
+     * Mask of capabilities supported by this iface.
+     */
+    @VintfStability
+    @Backing(type="int")
+    enum StaIfaceCapabilityMask {
+        /**
+         * Support for APF APIs. APF (Android Packet Filter) is a
+         * BPF-like packet filtering bytecode executed by the firmware.
+         */
+        APF = 1 << 0,
+        /**
+         * Support for Background Scan APIs. Background scan allows the host
+         * to send a number of buckets down to the firmware. Each bucket
+         * contains a set of channels, a period, and some parameters about
+         * how and when to report results.
+         */
+        BACKGROUND_SCAN = 1 << 1,
+        /**
+         * Support for link layer stats APIs.
+         */
+        LINK_LAYER_STATS = 1 << 2,
+        /**
+         * Support for RSSI monitor APIs.
+         */
+        RSSI_MONITOR = 1 << 3,
+        /**
+         * Support for roaming APIs.
+         */
+        CONTROL_ROAMING = 1 << 4,
+        /**
+         * Support for Probe IE allow-listing.
+         */
+        PROBE_IE_ALLOWLIST = 1 << 5,
+        /**
+         * Support for MAC & Probe Sequence Number randomization.
+         */
+        SCAN_RAND = 1 << 6,
+        /**
+         * Support for 5 GHz Band.
+         */
+        STA_5G = 1 << 7,
+        /**
+         * Support for GAS/ANQP queries.
+         */
+        HOTSPOT = 1 << 8,
+        /**
+         * Support for Preferred Network Offload.
+         */
+        PNO = 1 << 9,
+        /**
+         * Support for Tunneled Direct Link Setup.
+         */
+        TDLS = 1 << 10,
+        /**
+         * Support for Tunneled Direct Link Setup off channel.
+         */
+        TDLS_OFFCHANNEL = 1 << 11,
+        /**
+         * Support for neighbour discovery offload.
+         */
+        ND_OFFLOAD = 1 << 12,
+        /**
+         * Support for keep alive packet offload.
+         */
+        KEEP_ALIVE = 1 << 13,
+        /**
+         * Support for tracking connection packets' fate.
+         */
+        DEBUG_PACKET_FATE = 1 << 14,
+    }
+
+    /**
+     * Get the name of this iface.
+     *
+     * @return Name of this iface.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|
+     */
+    String getName();
+
+    /**
+     * Configure roaming control parameters.
+     * Must fail if |StaIfaceCapabilityMask.CONTROL_ROAMING| is not set.
+     *
+     * @param config Instance of |StaRoamingConfig|.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void configureRoaming(in StaRoamingConfig config);
+
+    /**
+     * Disable link layer stats collection.
+     * Must fail if |StaIfaceCapabilityMask.LINK_LAYER_STATS| is not set.
+     *
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_NOT_STARTED|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void disableLinkLayerStatsCollection();
+
+    /**
+     * Enable link layer stats collection.
+     * Must fail if |StaIfaceCapabilityMask.LINK_LAYER_STATS| is not set.
+     *
+     * Radio statistics (once started) must not stop until disabled.
+     * Iface statistics (once started) reset and start afresh after each
+     * connection until disabled.
+     *
+     * @param debug true to enable field debug mode, false to disable. Driver
+     *        must collect all statistics regardless of performance impact.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void enableLinkLayerStatsCollection(in boolean debug);
+
+    /**
+     * Enable/Disable neighbour discovery offload functionality in the firmware.
+     *
+     * @param enable true to enable, false to disable.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void enableNdOffload(in boolean enable);
+
+    /**
+     * Used to query additional information about the chip's APF capabilities.
+     * Must fail if |StaIfaceCapabilityMask.APF| is not set.
+     *
+     * @return Instance of |StaApfPacketFilterCapabilities|.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    StaApfPacketFilterCapabilities getApfPacketFilterCapabilities();
+
+    /**
+     * Used to query additional information about the chip's Background Scan capabilities.
+     * Must fail if |StaIfaceCapabilityMask.BACKGROUND_SCAN| is not set.
+     *
+     * @return Instance of |StaBackgroundScanCapabilities|
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    StaBackgroundScanCapabilities getBackgroundScanCapabilities();
+
+    /**
+     * Get the capabilities supported by this STA iface.
+     *
+     * @return Bitset of |StaIfaceCapabilityMask| values.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    StaIfaceCapabilityMask getCapabilities();
+
+    /**
+     * API to retrieve the fates of inbound packets.
+     * - HAL implementation must return the fates of
+     *   all the frames received for the most recent association.
+     *   The fate reports must follow the same order as their respective
+     *   packets.
+     * - HAL implementation may choose (but is not required) to include
+     *   reports for management frames.
+     * - Packets reported by firmware, but not recognized by driver,
+     *   must be included. However, the ordering of the corresponding
+     *   reports is at the discretion of HAL implementation.
+     * - Framework must be able to call this API multiple times for the same
+     *   association.
+     *
+     * @return Vector of |WifiDebugRxPacketFateReport| instances corresponding
+     *         to the packet fates.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_NOT_STARTED|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    WifiDebugRxPacketFateReport[] getDebugRxPacketFates();
+
+    /**
+     * API to retrieve fates of outbound packets.
+     * - HAL implementation must return the fates of
+     *   all the frames transmitted for the most recent association.
+     *   The fate reports must follow the same order as their respective
+     *   packets.
+     * - HAL implementation may choose (but is not required) to include
+     *   reports for management frames.
+     * - Packets reported by firmware, but not recognized by driver,
+     *   must be included. However, the ordering of the corresponding
+     *   reports is at the discretion of HAL implementation.
+     * - Framework must be able to call this API multiple times for the same
+     *   association.
+     *
+     * @return Vector of |WifiDebugTxPacketFateReport| instances corresponding
+     *         to the packet fates.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_NOT_STARTED|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    WifiDebugTxPacketFateReport[] getDebugTxPacketFates();
+
+    /**
+     * Gets the factory MAC address of the STA interface.
+     *
+     * @return Factory MAC address of the STA interface.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    byte[6] getFactoryMacAddress();
+
+    /**
+     * Retrieve the latest link layer stats.
+     * Must fail if |StaIfaceCapabilityMask.LINK_LAYER_STATS| is not set or if
+     * link layer stats collection hasn't been explicitly enabled.
+     *
+     * @return Instance of |LinkLayerStats|.
+     * @throws ServiceSpecificException with one of the following values:
+     *     |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *     |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *     |WifiStatusCode.ERROR_NOT_STARTED|,
+     *     |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *     |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    StaLinkLayerStats getLinkLayerStats();
+
+    /**
+     * Get roaming control capabilities.
+     * Must fail if |StaIfaceCapabilityMask.CONTROL_ROAMING| is not set.
+     *
+     * @return Instance of |StaRoamingCapabilities|.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    StaRoamingCapabilities getRoamingCapabilities();
+
+    /**
+     * Used to query the list of valid frequencies (depending on the country
+     * code set) for the provided band. These channels may be specified in the
+     * |BackgroundScanBucketParameters.frequenciesInMhz| for a background scan
+     * request.
+     *
+     * @param band Band for which the frequency list is being generated.
+     * @return Vector of valid frequencies for the provided band.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    int[] getValidFrequenciesForBand(in WifiBand band);
+
+    /**
+     * Installs an APF program on this iface, replacing an existing
+     * program if present.
+     * Must fail if |StaIfaceCapabilityMask.APF| is not set.
+     *
+     * APF docs
+     * ==========================================================================
+     * APF functionality, instructions and bytecode/binary format is described in:
+     * http://android.googlesource.com/platform/hardware/google/apf/
+     * +/b75c9f3714cfae3dad3d976958e063150781437e/apf.h
+     *
+     * The interpreter API is described here:
+     * http://android.googlesource.com/platform/hardware/google/apf/+/
+     * b75c9f3714cfae3dad3d976958e063150781437e/apf_interpreter.h#32
+     *
+     * The assembler/generator API is described in javadocs here:
+     * http://android.googlesource.com/platform/frameworks/base/+/
+     * 4456f33a958a7f09e608399da83c4d12b2e7d191/services/net/java/android/net/
+     * apf/ApfGenerator.java
+     *
+     * Disassembler usage is described here:
+     * http://android.googlesource.com/platform/hardware/google/apf/+/
+     * b75c9f3714cfae3dad3d976958e063150781437e/apf_disassembler.c#65
+     *
+     * The BPF to APF translator usage is described here:
+     * http://android.googlesource.com/platform/frameworks/base/+/
+     * 4456f33a958a7f09e608399da83c4d12b2e7d191/tests/net/java/android/net/
+     * apf/Bpf2Apf.java
+     * ==========================================================================
+     *
+     * @param program APF Program to be set.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void installApfPacketFilter(in byte[] program);
+
+    /**
+     * Fetches a consistent snapshot of the entire APF program and working
+     * memory buffer and returns it to the host. The returned buffer contains
+     * both code and data. Its length must match the most recently returned
+     * |StaApfPacketFilterCapabilities.maxLength|.
+     *
+     * While the snapshot is being fetched, the APF interpreter must not execute
+     * and all incoming packets must be passed to the host as if there was no
+     * APF program installed.
+     *
+     * Must fail with |WifiStatusCode.ERROR_NOT_SUPPORTED| if
+     * |StaIfaceCapabilityMask.APF| is not set.
+     *
+     * @return The entire APF working memory buffer when status is
+     *         |WifiStatusCode.SUCCESS|, empty otherwise.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     * @see getApfPacketFilterCapabilities()
+     * @see installApfPacketFilter()
+     */
+    byte[] readApfPacketFilterData();
+
+    /**
+     * Requests notifications of significant events on this iface. Multiple calls
+     * to this must register multiple callbacks, each of which must receive all
+     * events.
+     *
+     * @param callback An instance of the |IWifiStaIfaceEventCallback| AIDL
+     *        interface object.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|
+     */
+    void registerEventCallback(in IWifiStaIfaceEventCallback callback);
+
+    /**
+     * Changes the MAC address of the STA Interface to the given
+     * MAC address.
+     *
+     * @param mac MAC address to change to.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void setMacAddress(in byte[6] mac);
+
+    /**
+     * Set the roaming control state with the parameters configured
+     * using |configureRoaming|. Depending on the roaming state set, the
+     * driver/firmware would enable/disable control over roaming decisions.
+     * Must fail if |StaIfaceCapabilityMask.CONTROL_ROAMING| is not set.
+     *
+     * @param state State of the roaming control.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_BUSY|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void setRoamingState(in StaRoamingState state);
+
+    /**
+     * Turn on/off scan only mode for the interface.
+     *
+     * @param enable True to enable scan only mode, false to disable.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.FAILURE_UNKNOWN|
+     */
+    void setScanMode(in boolean enable);
+
+    /**
+     * Start a background scan using the given cmdId as an identifier. Only one
+     * active background scan need be supported.
+     * Must fail if |StaIfaceCapabilityMask.BACKGROUND_SCAN| is not set.
+     *
+     * When this is called all requested buckets must be scanned, starting the
+     * beginning of the cycle.
+     *
+     * For example:
+     * If there are two buckets specified
+     *  - Bucket 1: period=10s
+     *  - Bucket 2: period=20s
+     *  - Bucket 3: period=30s
+     * Then the following scans must occur
+     *  - t=0  buckets 1, 2, and 3 are scanned
+     *  - t=10 bucket 1 is scanned
+     *  - t=20 bucket 1 and 2 are scanned
+     *  - t=30 bucket 1 and 3 are scanned
+     *  - t=40 bucket 1 and 2 are scanned
+     *  - t=50 bucket 1 is scanned
+     *  - t=60 buckets 1, 2, and 3 are scanned
+     *  - and the pattern repeats
+     *
+     * If any scan does not occur or is incomplete (error, interrupted, etc),
+     * then a cached scan result must still be recorded with the
+     * WIFI_SCAN_FLAG_INTERRUPTED flag set.
+     *
+     * @param cmdId Command Id to use for this invocation.
+     * @param params Background scan parameters.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void startBackgroundScan(in int cmdId, in StaBackgroundScanParameters params);
+
+    /**
+     * API to start packet fate monitoring.
+     * - Once started, monitoring must remain active until HAL is stopped or the
+     *   chip is reconfigured.
+     * - When HAL is unloaded, all packet fate buffers must be cleared.
+     * - The packet fates are used to monitor the state of packets transmitted/
+     *   received during association.
+     *
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void startDebugPacketFateMonitoring();
+
+    /**
+     * Start RSSI monitoring on the currently connected access point.
+     * Once the monitoring is enabled, the
+     * |IWifiStaIfaceEventCallback.onRssiThresholdBreached| callback must be
+     * invoked to indicate if the RSSI goes above |maxRssi| or below |minRssi|.
+     * Must fail if |StaIfaceCapabilityMask.RSSI_MONITOR| is not set.
+     *
+     * @param cmdId Command Id to use for this invocation.
+     * @param maxRssi Maximum RSSI threshold.
+     * @param minRssi Minimum RSSI threshold.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_ARGS_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void startRssiMonitoring(in int cmdId, in int maxRssi, in int minRssi);
+
+    /**
+     * Start sending the specified keep alive packets periodically.
+     *
+     * @param cmdId Command Id to use for this invocation.
+     * @param ipPacketData IP packet contents to be transmitted.
+     * @param etherType 16 bit ether type to be set in the ethernet frame
+     *        transmitted.
+     * @param srcAddress Source MAC address of the packet.
+     * @param dstAddress Destination MAC address of the packet.
+     * @param periodInMs Interval at which this packet must be transmitted.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void startSendingKeepAlivePackets(in int cmdId, in byte[] ipPacketData, in char etherType,
+            in byte[6] srcAddress, in byte[6] dstAddress, in int periodInMs);
+
+    /**
+     * Stop the current background scan.
+     * Must fail if |StaIfaceCapabilityMask.BACKGROUND_SCAN| is not set.
+     *
+     * @param cmdId Command Id corresponding to the request.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_NOT_STARTED|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void stopBackgroundScan(in int cmdId);
+
+    /**
+     * Stop RSSI monitoring.
+     * Must fail if |StaIfaceCapabilityMask.RSSI_MONITOR| is not set.
+     *
+     * @param cmdId Command Id corresponding to the request.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_NOT_STARTED|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void stopRssiMonitoring(in int cmdId);
+
+    /**
+     * Stop sending the specified keep alive packets.
+     *
+     * @param cmdId Command Id corresponding to the request.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    void stopSendingKeepAlivePackets(in int cmdId);
+}
diff --git a/wifi/aidl/android/hardware/wifi/IWifiStaIfaceEventCallback.aidl b/wifi/aidl/android/hardware/wifi/IWifiStaIfaceEventCallback.aidl
new file mode 100644
index 0000000..93a255f
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/IWifiStaIfaceEventCallback.aidl
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+import android.hardware.wifi.StaScanData;
+import android.hardware.wifi.StaScanResult;
+
+@VintfStability
+oneway interface IWifiStaIfaceEventCallback {
+    /**
+     * Called for each received beacon/probe response for a scan with the
+     * |REPORT_EVENTS_FULL_RESULTS| flag set in
+     * |StaBackgroundScanBucketParameters.eventReportScheme|.
+     *
+     * @param cmdId Command Id corresponding to the request.
+     * @param bucketsScanned Bitset where each bit indicates if the bucket with
+     *        that index (starting at 0) was scanned.
+     * @param result Full scan result for an AP.
+     */
+    void onBackgroundFullScanResult(in int cmdId, in int bucketsScanned, in StaScanResult result);
+
+    /**
+     * Callback indicating that an ongoing background scan request has failed.
+     * The background scan needs to be restarted to continue scanning.
+     *
+     * @param cmdId Command Id corresponding to the request.
+     */
+    void onBackgroundScanFailure(in int cmdId);
+
+    /**
+     * Called when the |StaBackgroundScanBucketParameters.eventReportScheme| flags
+     * for at least one bucket that was just scanned was
+     * |REPORT_EVENTS_EACH_SCAN|, or one of the configured thresholds was
+     * breached.
+     *
+     * @param cmdId Command Id corresponding to the request.
+     * @param scanDatas List of scan result for all AP's seen since last callback.
+     */
+    void onBackgroundScanResults(in int cmdId, in StaScanData[] scanDatas);
+
+    /**
+     * Called when the RSSI of the currently connected access point goes beyond the
+     * thresholds set via |IWifiStaIface.startRssiMonitoring|.
+     *
+     * @param cmdId Command Id corresponding to the request.
+     * @param currBssid BSSID of the currently connected access point.
+     * @param currRssi RSSI of the currently connected access point.
+     */
+    void onRssiThresholdBreached(in int cmdId, in byte[6] currBssid, in int currRssi);
+}
diff --git a/wifi/aidl/android/hardware/wifi/IfaceConcurrencyType.aidl b/wifi/aidl/android/hardware/wifi/IfaceConcurrencyType.aidl
new file mode 100644
index 0000000..26c183c
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/IfaceConcurrencyType.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+/**
+ * List of interface concurrency types, used in reporting device concurrency capabilities.
+ */
+@VintfStability
+@Backing(type="int")
+enum IfaceConcurrencyType {
+    /**
+     * Concurrency type for station mode.
+     */
+    STA,
+    /**
+     * Concurrency type of single-port AP mode.
+     */
+    AP,
+    /**
+     * Concurrency type of two-port bridged AP mode.
+     */
+    AP_BRIDGED,
+    /**
+     * Concurrency type of peer-to-peer mode.
+     */
+    P2P,
+    /**
+     * Concurrency type of neighborhood area network mode.
+     */
+    NAN_IFACE,
+}
diff --git a/wifi/aidl/android/hardware/wifi/IfaceType.aidl b/wifi/aidl/android/hardware/wifi/IfaceType.aidl
new file mode 100644
index 0000000..c89d94b
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/IfaceType.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+/**
+ * List of supported interface types.
+ */
+@VintfStability
+@Backing(type="int")
+enum IfaceType {
+    STA,
+    AP,
+    P2P,
+    /**
+     * NAN control interface. Datapath support must be queried and created
+     * through this interface. Declared as 'NAN_IFACE' instead of 'NAN'
+     * because the compiler complains that NAN is already defined by math.h
+     */
+    NAN_IFACE,
+}
diff --git a/wifi/aidl/android/hardware/wifi/MacAddress.aidl b/wifi/aidl/android/hardware/wifi/MacAddress.aidl
new file mode 100644
index 0000000..d59dfe3
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/MacAddress.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+/**
+ * Byte array representing a Mac Address. Use when we need to
+ * pass an array of Mac Addresses to a method, as variable-sized
+ * 2D arrays are not supported in AIDL.
+ *
+ * TODO (b/210705533): Replace this type with a 2D byte array.
+ */
+@VintfStability
+parcelable MacAddress {
+    byte[6] data;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanBandIndex.aidl b/wifi/aidl/android/hardware/wifi/NanBandIndex.aidl
new file mode 100644
index 0000000..5da5869
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanBandIndex.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+/**
+ * The discovery bands supported by NAN.
+ */
+@VintfStability
+@Backing(type="int")
+enum NanBandIndex {
+    NAN_BAND_24GHZ = 0,
+    NAN_BAND_5GHZ,
+    /**
+     * Index for 6 GHz band.
+     */
+    NAN_BAND_6GHZ = 2,
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanBandSpecificConfig.aidl b/wifi/aidl/android/hardware/wifi/NanBandSpecificConfig.aidl
new file mode 100644
index 0000000..2e13486
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanBandSpecificConfig.aidl
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+/**
+ * NAN band-specific configuration.
+ */
+@VintfStability
+parcelable NanBandSpecificConfig {
+    /**
+     * RSSI values controlling clustering behavior per spec. RSSI values are specified without a
+     * sign, e.g. a value of -65dBm would be specified as 65.
+     */
+    byte rssiClose;
+    byte rssiMiddle;
+    /**
+     * RSSI value determining whether discovery is near (used if enabled in discovery by
+     * |NanDiscoveryCommonConfig.useRssiThreshold|).
+     * RSSI values are specified without a sign, e.g. a value of -65dBm would be specified as 65.
+     * NAN Spec: RSSI_close_proximity
+     */
+    byte rssiCloseProximity;
+    /**
+     * Dwell time of each discovery channel in milliseconds. If set to 0, then the firmware
+     * determines the dwell time to use.
+     */
+    char dwellTimeMs;
+    /**
+     * Scan period of each discovery channel in seconds. If set to 0, then the firmware determines
+     * the scan period to use.
+     */
+    char scanPeriodSec;
+    /**
+     * Specifies the discovery window interval for Sync beacons and SDF's.
+     * Valid values of DW Interval are: 1, 2, 3, 4 and 5 corresponding to 1, 2, 4, 8, and 16 DWs.
+     * Value of 0:
+     *  - reserved in 2.4GHz band
+     *  - no wakeup at all in 5GHz band
+     * The publish/subscribe period values don't override the device level configurations if
+     * they are specified.
+     * Configuration is only used only if |validDiscoveryWindowIntervalVal| is set to true.
+     * NAN Spec: Device Capability Attribute / 2.4 GHz DW, Device Capability Attribute / 5 GHz DW
+     */
+    boolean validDiscoveryWindowIntervalVal;
+    byte discoveryWindowIntervalVal;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanCapabilities.aidl b/wifi/aidl/android/hardware/wifi/NanCapabilities.aidl
new file mode 100644
index 0000000..6042a05
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanCapabilities.aidl
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+import android.hardware.wifi.NanCipherSuiteType;
+
+/**
+ * NDP Capabilities response.
+ */
+@VintfStability
+parcelable NanCapabilities {
+    /**
+     * Maximum number of clusters which the device can join concurrently.
+     */
+    int maxConcurrentClusters;
+    /**
+     * Maximum number of concurrent publish discovery sessions.
+     */
+    int maxPublishes;
+    /**
+     * Maximum number of concurrent subscribe discovery sessions.
+     */
+    int maxSubscribes;
+    /**
+     * Maximum length (in bytes) of service name.
+     */
+    int maxServiceNameLen;
+    /**
+     * Maximum length (in bytes) of individual match filters.
+     */
+    int maxMatchFilterLen;
+    /**
+     * Maximum length (in bytes) of aggregate match filters across all active sessions.
+     */
+    int maxTotalMatchFilterLen;
+    /**
+     * Maximum length (in bytes) of the service specific info field.
+     */
+    int maxServiceSpecificInfoLen;
+    /**
+     * Maximum length (in bytes) of the extended service specific info field.
+     */
+    int maxExtendedServiceSpecificInfoLen;
+    /**
+     * Maximum number of data interfaces (NDI) which can be created concurrently on the device.
+     */
+    int maxNdiInterfaces;
+    /**
+     * Maximum number of data paths (NDP) which can be created concurrently on the device, across
+     * all data interfaces (NDI).
+     */
+    int maxNdpSessions;
+    /**
+     * Maximum length (in bytes) of application info field (used in data-path negotiations).
+     */
+    int maxAppInfoLen;
+    /**
+     * Maximum number of transmitted followup messages which can be queued by the firmware.
+     */
+    int maxQueuedTransmitFollowupMsgs;
+    /**
+     * Maximum number MAC interface addresses which can be specified to a subscribe discovery
+     * session.
+     */
+    int maxSubscribeInterfaceAddresses;
+    /**
+     * The set of supported Cipher suites. The |NanCipherSuiteType| bit fields are used.
+     */
+    NanCipherSuiteType supportedCipherSuites;
+    /**
+     * Flag to indicate id instant communication mode is supported.
+     */
+    boolean instantCommunicationModeSupportFlag;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanCipherSuiteType.aidl b/wifi/aidl/android/hardware/wifi/NanCipherSuiteType.aidl
new file mode 100644
index 0000000..9e3d684
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanCipherSuiteType.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+/**
+ * Cipher suite flags.
+ */
+@VintfStability
+@Backing(type="int")
+enum NanCipherSuiteType {
+    NONE = 0,
+    SHARED_KEY_128_MASK = 1 << 0,
+    SHARED_KEY_256_MASK = 1 << 1,
+    /**
+     *  NCS-PK-128
+     */
+    PUBLIC_KEY_128_MASK = 1 << 2,
+    /**
+     *  NCS-PK-256
+     */
+    PUBLIC_KEY_256_MASK = 1 << 3,
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanClusterEventInd.aidl b/wifi/aidl/android/hardware/wifi/NanClusterEventInd.aidl
new file mode 100644
index 0000000..76a3034
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanClusterEventInd.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+import android.hardware.wifi.NanClusterEventType;
+
+/**
+ * Cluster event indication structure. Triggered on events impacting how this device is
+ * visible to peers - cluster forming, joining a new cluster, or changing of the MAC address.
+ */
+@VintfStability
+parcelable NanClusterEventInd {
+    /**
+     * Event type causing the cluster event indication to be triggered.
+     */
+    NanClusterEventType eventType;
+    /**
+     * MAC Address associated with the corresponding event.
+     */
+    byte[6] addr;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanClusterEventType.aidl b/wifi/aidl/android/hardware/wifi/NanClusterEventType.aidl
new file mode 100644
index 0000000..c07bf17
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanClusterEventType.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+/**
+ * Event types for a cluster event indication.
+ */
+@VintfStability
+@Backing(type="int")
+enum NanClusterEventType {
+    /**
+     * Management/discovery interface MAC address has changed
+     * (e.g. due to randomization or at startup).
+     */
+    DISCOVERY_MAC_ADDRESS_CHANGED = 0,
+    /**
+     * A new cluster has been formed by this device.
+     */
+    STARTED_CLUSTER,
+    /**
+     * This device has joined an existing cluster.
+     */
+    JOINED_CLUSTER,
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanConfigRequest.aidl b/wifi/aidl/android/hardware/wifi/NanConfigRequest.aidl
new file mode 100644
index 0000000..82a7b6e
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanConfigRequest.aidl
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+import android.hardware.wifi.NanBandSpecificConfig;
+
+/**
+ * Configuration parameters of NAN. Used when enabling and re-configuring a NAN cluster.
+ */
+@VintfStability
+parcelable NanConfigRequest {
+    /**
+     * Master preference of this device.
+     * NAN Spec: Master Indication Attribute / Master Preference
+     */
+    byte masterPref;
+    /**
+     * Controls whether or not the |IWifiNanIfaceEventCallback.eventClusterEvent| will be delivered
+     * for |NanClusterEventType.DISCOVERY_MAC_ADDRESS_CHANGED|.
+     */
+    boolean disableDiscoveryAddressChangeIndication;
+    /**
+     * Controls whether or not the |IWifiNanIfaceEventCallback.eventClusterEvent| will be delivered
+     * for |NanClusterEventType.STARTED_CLUSTER|.
+     */
+    boolean disableStartedClusterIndication;
+    /**
+     * Controls whether or not the |IWifiNanIfaceEventCallback.eventClusterEvent| will be delivered
+     * for |NanClusterEventType.JOINED_CLUSTER|.
+     */
+    boolean disableJoinedClusterIndication;
+    /**
+     * Control whether publish service IDs are included in Sync/Discovery beacons.
+     * NAN Spec: Service ID List Attribute
+     */
+    boolean includePublishServiceIdsInBeacon;
+    /**
+     * If |includePublishServiceIdsInBeacon| is true, then specifies the number of publish service
+     * IDs to include in the Sync/Discovery beacons. Value = 0: include as many service IDs as will
+     * fit into the maximum allowed beacon frame size. Value must fit within 7 bits - i.e. <= 127.
+     */
+    byte numberOfPublishServiceIdsInBeacon;
+    /**
+     * Control whether subscribe service IDs are included in Sync/Discovery beacons.
+     * Spec: Subscribe Service ID List Attribute
+     */
+    boolean includeSubscribeServiceIdsInBeacon;
+    /**
+     * If |includeSubscribeServiceIdsInBeacon| is true, then specifies the number of subscribe
+     * service IDs to include in the Sync/Discovery beacons. Value = 0: include as many service IDs
+     * as will fit into the maximum allowed beacon frame size. Value must fit within 7 bits - i.e.
+     * <= 127.
+     */
+    byte numberOfSubscribeServiceIdsInBeacon;
+    /**
+     * Number of samples used to calculate RSSI.
+     */
+    char rssiWindowSize;
+    /**
+     * Specifies the interval in seconds that the NAN management interface MAC address is
+     * randomized. A value of 0 is used to disable the MAC address randomization.
+     */
+    int macAddressRandomizationIntervalSec;
+    /**
+     * Additional configuration provided per band. Indexed by |NanBandIndex|.
+     */
+    NanBandSpecificConfig[3] bandSpecificConfig;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanConfigRequestSupplemental.aidl b/wifi/aidl/android/hardware/wifi/NanConfigRequestSupplemental.aidl
new file mode 100644
index 0000000..eb01a9f
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanConfigRequestSupplemental.aidl
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+/**
+ * Additional NAN configuration request parameters.
+ */
+@VintfStability
+parcelable NanConfigRequestSupplemental {
+    /**
+     * Specify the Discovery Beacon interval in ms. Specification only applicable if the device
+     * transmits Discovery Beacons (based on the Wi-Fi Aware protocol selection criteria). The value
+     * can be increased to reduce power consumption (on devices which would transmit Discovery
+     * Beacons). However, cluster synchronization time will likely increase.
+     * Values are:
+     *  - A value of 0 indicates that the HAL sets the interval to a default (implementation
+     * specific).
+     *  - A positive value.
+     */
+    int discoveryBeaconIntervalMs;
+    /**
+     * The number of spatial streams to be used for transmitting NAN management frames (does NOT
+     * apply to data-path packets). A small value may reduce power consumption for small discovery
+     * packets. Values are:
+     *  - A value of 0 indicates that the HAL sets the number to a default (implementation
+     * specific).
+     *  - A positive value.
+     */
+    int numberOfSpatialStreamsInDiscovery;
+    /**
+     * Controls whether the device may terminate listening on a Discovery Window (DW) earlier than
+     * the DW termination (16ms) if no information is received. Enabling the feature will result in
+     * lower power consumption, but may result in some missed messages and hence increased latency.
+     */
+    boolean enableDiscoveryWindowEarlyTermination;
+    /**
+     * Controls whether NAN RTT (ranging) is permitted. Global flag on any NAN RTT operations are
+     * allowed. Controls ranging in the context of discovery as well as direct RTT.
+     */
+    boolean enableRanging;
+    /**
+     * Controls whether NAN instant communication mode is enabled.
+     */
+    boolean enableInstantCommunicationMode;
+    /**
+     * Controls which channel NAN instant communication mode operates on.
+     */
+    int instantModeChannel;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanDataPathChannelCfg.aidl b/wifi/aidl/android/hardware/wifi/NanDataPathChannelCfg.aidl
new file mode 100644
index 0000000..3aaea40
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanDataPathChannelCfg.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+/**
+ * NAN DP (data-path) channel config options.
+ */
+@VintfStability
+@Backing(type="int")
+enum NanDataPathChannelCfg {
+    CHANNEL_NOT_REQUESTED = 0,
+    REQUEST_CHANNEL_SETUP,
+    FORCE_CHANNEL_SETUP,
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanDataPathChannelInfo.aidl b/wifi/aidl/android/hardware/wifi/NanDataPathChannelInfo.aidl
new file mode 100644
index 0000000..e5c3538
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanDataPathChannelInfo.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+import android.hardware.wifi.WifiChannelWidthInMhz;
+
+/**
+ * NAN data path channel information provided to the framework.
+ */
+@VintfStability
+parcelable NanDataPathChannelInfo {
+    /**
+     * Channel frequency in MHz.
+     */
+    int channelFreq;
+    /**
+     * Channel bandwidth in MHz.
+     */
+    WifiChannelWidthInMhz channelBandwidth;
+    /**
+     * Number of spatial streams used in the channel.
+     */
+    int numSpatialStreams;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanDataPathConfirmInd.aidl b/wifi/aidl/android/hardware/wifi/NanDataPathConfirmInd.aidl
new file mode 100644
index 0000000..621f036
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanDataPathConfirmInd.aidl
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+import android.hardware.wifi.NanDataPathChannelInfo;
+import android.hardware.wifi.NanStatus;
+
+/**
+ * NAN Data path confirmation indication structure. Event indication is
+ * received on both initiator and responder side when negotiation for a
+ * data-path finishes on success or failure.
+ */
+@VintfStability
+parcelable NanDataPathConfirmInd {
+    /**
+     * ID of the data-path.
+     */
+    int ndpInstanceId;
+    /**
+     * Indicates whether the data-path setup succeeded (true) or failed (false).
+     */
+    boolean dataPathSetupSuccess;
+    /**
+     * MAC address of the peer's data-interface (not its management/discovery interface).
+     */
+    byte[6] peerNdiMacAddr;
+    /**
+     * Arbitrary information communicated from the peer as part of the data-path setup process -
+     * there is no semantic meaning to these bytes. They are passed-through from sender to receiver
+     * as-is with no parsing. Max length: |NanCapabilities.maxAppInfoLen|. NAN Spec: Data Path
+     * Attributes / NDP Attribute / NDP Specific Info
+     */
+    byte[] appInfo;
+    /**
+     * Failure reason if |dataPathSetupSuccess| is false.
+     */
+    NanStatus status;
+    /**
+     * The channel(s) on which the NDP is scheduled to operate.
+     * Updates to the operational channels are provided using the |eventDataPathScheduleUpdate|
+     * event.
+     */
+    NanDataPathChannelInfo[] channelInfo;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanDataPathRequestInd.aidl b/wifi/aidl/android/hardware/wifi/NanDataPathRequestInd.aidl
new file mode 100644
index 0000000..de9ee32
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanDataPathRequestInd.aidl
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+/**
+ * NAN Data path request indication message structure.
+ * Event indication received by an intended Responder when a NAN
+ * data request initiated by an Initiator.
+ */
+@VintfStability
+parcelable NanDataPathRequestInd {
+    /**
+     * ID of an active publish or subscribe discovery session. The data-path
+     * request is in the context of this discovery session.
+     * NAN Spec: Data Path Attributes / NDP Attribute / Publish ID
+     */
+    byte discoverySessionId;
+    /**
+     * MAC address of the Initiator peer. This is the MAC address of the peer's
+     * management/discovery NAN interface.
+     */
+    byte[6] peerDiscMacAddr;
+    /**
+     * ID of the data-path. Used to identify the data-path in further negotiation/APIs.
+     */
+    int ndpInstanceId;
+    /**
+     * Specifies whether or not security is required by the peer for the data-path being created.
+     * NAN Spec: Data Path Attributes / NDP Attribute / NDP Control / Security Present
+     */
+    boolean securityRequired;
+    /**
+     * Arbitrary information communicated from the peer as part of the data-path setup process.
+     * Therer is no semantic meaning to these bytes. They are passed-through from sender to
+     * receiver as-is with no parsing.
+     * Max length: |NanCapabilities.maxAppInfoLen|.
+     * NAN Spec: Data Path Attributes / NDP Attribute / NDP Specific Info
+     */
+    byte[] appInfo;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanDataPathScheduleUpdateInd.aidl b/wifi/aidl/android/hardware/wifi/NanDataPathScheduleUpdateInd.aidl
new file mode 100644
index 0000000..0f41d8f
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanDataPathScheduleUpdateInd.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+import android.hardware.wifi.NanDataPathChannelInfo;
+
+/**
+ * NAN data path channel information update indication structure.
+ * Event indication is received by all NDP owners whenever the channels on
+ * which the NDP operates are updated.
+ * Note: Multiple NDPs may share the same schedule. The indication specifies
+ * all NDPs to which it applies.
+ */
+@VintfStability
+parcelable NanDataPathScheduleUpdateInd {
+    /**
+     * The discovery address (NMI) of the peer to which the NDP is connected.
+     */
+    byte[6] peerDiscoveryAddress;
+    /**
+     * The updated channel(s) information.
+     */
+    NanDataPathChannelInfo[] channelInfo;
+    /**
+     * The list of NDPs to which this update applies.
+     */
+    int[] ndpInstanceIds;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanDataPathSecurityConfig.aidl b/wifi/aidl/android/hardware/wifi/NanDataPathSecurityConfig.aidl
new file mode 100644
index 0000000..42a5616
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanDataPathSecurityConfig.aidl
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+import android.hardware.wifi.NanCipherSuiteType;
+import android.hardware.wifi.NanDataPathSecurityType;
+
+/**
+ * Configuration of NAN data-path security.
+ */
+@VintfStability
+parcelable NanDataPathSecurityConfig {
+    /**
+     * Security configuration of the data-path (NDP). Security is enabled if not equal to
+     * |NanDataPathSecurityType.OPEN|.
+     * NAN Spec: Service Discovery Extension Attribute (SDEA) / Control / Security Required
+     */
+    NanDataPathSecurityType securityType;
+    /**
+     * Cipher type for data-paths. If |securityType| is |NanDataPathSecurityType.OPEN| then must
+     * be set to |NanCipherSuiteType.NONE|. Otherwise a non-|NanCipherSuiteType.NONE| cipher suite
+     * must be specified.
+     */
+    NanCipherSuiteType cipherType;
+    /**
+     * Optional Pairwise Master Key (PMK). Must be specified (and is only used) if |securityType| is
+     * set to |NanDataPathSecurityType.PMK|.
+     * Ref: IEEE 802.11i
+     */
+    byte[32] pmk;
+    /**
+     * Optional Passphrase. Must be specified (and is only used) if |securityType| is set to
+     * |NanDataPathSecurityType.PASSPHRASE|.
+     * Min length: |IWifiNanIface.MIN_DATA_PATH_CONFIG_PASSPHRASE_LENGTH|
+     * Max length: |IWifiNanIface.MAX_DATA_PATH_CONFIG_PASSPHRASE_LENGTH|
+     * NAN Spec: Appendix: Mapping passphrase to PMK for NCS-SK Cipher Suites
+     */
+    byte[] passphrase;
+    /**
+     * Security Context Identifier attribute contains PMKID. Shall be included in NDP setup and
+     * response messages. Security Context Identifier identifies the Security Context. When
+     * security is enabled this field contains the 16 octet PMKID identifying the PMK used for
+     * setting up the Secure Data Path.
+     */
+    byte[16] scid;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanDataPathSecurityType.aidl b/wifi/aidl/android/hardware/wifi/NanDataPathSecurityType.aidl
new file mode 100644
index 0000000..da23ffa
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanDataPathSecurityType.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+/**
+ * NAN DP (data-path) security configuration options.
+ */
+@VintfStability
+@Backing(type="int")
+enum NanDataPathSecurityType {
+    OPEN,
+    PMK,
+    PASSPHRASE,
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanDebugConfig.aidl b/wifi/aidl/android/hardware/wifi/NanDebugConfig.aidl
new file mode 100644
index 0000000..d8fab0d
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanDebugConfig.aidl
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+/**
+ * Debug configuration parameters. Many of these allow non-standard-compliant operation and are
+ * not intended for normal operational mode.
+ */
+@VintfStability
+parcelable NanDebugConfig {
+    /**
+     * Specification of the lower 2 bytes of the cluster ID. The cluster ID is 50-60-9a-01-00-00 to
+     * 50-60-9a-01-FF-FF. Configuration is of the bottom and top values of the range (which default
+     * to 0x0000 and 0xFFFF respectively).
+     * Configuration is only used if |validClusterIdVals| is set to true.
+     */
+    boolean validClusterIdVals;
+    char clusterIdBottomRangeVal;
+    char clusterIdTopRangeVal;
+    /**
+     * NAN management interface address. If specified (|validIntfAddrVal| is true), then overrides
+     * any other configuration (specifically the default randomization configured by
+     * |NanConfigRequest.macAddressRandomizationIntervalSec|).
+     */
+    boolean validIntfAddrVal;
+    byte[6] intfAddrVal;
+    /**
+     * Combination of the 24 bit Organizationally Unique ID (OUI) and the 8 bit OUI type.
+     * Used if |validOuiVal| is set to true.
+     */
+    boolean validOuiVal;
+    int ouiVal;
+    /**
+     * Force the Random Factor to the specified value for all transmitted Sync/Discovery beacons.
+     * Used if |validRandomFactorForceVal| is set to true.
+     * NAN Spec: Master Indication Attribute / Random Factor
+     */
+    boolean validRandomFactorForceVal;
+    byte randomFactorForceVal;
+    /**
+     * Forces the hop-count for all transmitted Sync and Discovery Beacons NO matter the real
+     * hop-count being received over the air. Used if the |validHopCountForceVal| flag is set to
+     * true.
+     * NAN Spec: Cluster Attribute / Anchor Master Information / Hop Count to Anchor Master
+     */
+    boolean validHopCountForceVal;
+    byte hopCountForceVal;
+    /**
+     * Frequency in MHz to of the discovery channel in the specified band. Indexed by
+     * |NanBandIndex|. Used if the |validDiscoveryChannelVal| is set to true.
+     */
+    boolean validDiscoveryChannelVal;
+    int[3] discoveryChannelMhzVal;
+    /**
+     * Specifies whether sync/discovery beacons are transmitted in the specified band. Indexed by
+     * |NanBandIndex|. Used if the |validUseBeaconsInBandVal| is set to true.
+     */
+    boolean validUseBeaconsInBandVal;
+    boolean[3] useBeaconsInBandVal;
+    /**
+     * Specifies whether SDF (service discovery frames) are transmitted in the specified band.
+     * Indexed by |NanBandIndex|. Used if the |validUseSdfInBandVal| is set to true.
+     */
+    boolean validUseSdfInBandVal;
+    boolean[3] useSdfInBandVal;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanDiscoveryCommonConfig.aidl b/wifi/aidl/android/hardware/wifi/NanDiscoveryCommonConfig.aidl
new file mode 100644
index 0000000..ca1e016
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanDiscoveryCommonConfig.aidl
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+import android.hardware.wifi.NanDataPathSecurityConfig;
+import android.hardware.wifi.NanMatchAlg;
+import android.hardware.wifi.NanRangingIndication;
+
+/**
+ * Configurations of NAN discovery sessions. Common to publish and subscribe discovery.
+ */
+@VintfStability
+parcelable NanDiscoveryCommonConfig {
+    /**
+     * The ID of the discovery session being configured. A value of 0 specifies a request to create
+     * a new discovery session. The new discovery session ID is returned with
+     * |IWifiNanIfaceEventCallback.notifyStartPublishResponse| or
+     * |IWifiNanIfaceEventCallback.notifyStartSubscribeResponse|.
+     * NAN Spec: Service Descriptor Attribute (SDA) / Instance ID
+     */
+    byte sessionId;
+    /**
+     * The lifetime of the discovery session in seconds. A value of 0 means run forever or until
+     * canceled using |IWifiIface.stopPublishRequest| or |IWifiIface.stopSubscribeRequest|.
+     */
+    char ttlSec;
+    /**
+     * Indicates the interval between two Discovery Windows in which the device supporting the
+     * service is awake to transmit or receive the Service Discovery frames. Valid values of Awake
+     * DW Interval are: 1, 2, 4, 8 and 16. A value of 0 will default to 1. Does not override
+     * |NanBandSpecificConfig.discoveryWindowIntervalVal| configurations if those are specified.
+     */
+    char discoveryWindowPeriod;
+    /**
+     * The lifetime of the discovery session in number of transmitted SDF discovery packets. A value
+     * of 0 means forever or until canceled using |IWifiIface.stopPublishRequest| or
+     * |IWifiIface.stopSubscribeRequest|.
+     */
+    byte discoveryCount;
+    /**
+     * UTF-8 encoded string identifying the service.
+     * Max length: |NanCapabilities.maxServiceNameLen|.
+     * NAN Spec: The only acceptable single-byte UTF-8 symbols for a Service Name are alphanumeric
+     * values (A-Z, a-z, 0-9), the hyphen ('-'), and the period ('.'). All valid multi-byte UTF-8
+     * characters are acceptable in a Service Name.
+     */
+    byte[] serviceName;
+    /**
+     * Specifies how often to trigger |IWifiNanIfaceEventCallback.eventMatch| when continuously
+     * discovering the same discovery session (with no changes).
+     */
+    NanMatchAlg discoveryMatchIndicator;
+    /**
+     * Arbitrary information communicated in discovery packets - there is no semantic meaning to
+     * these bytes. They are passed-through from publisher to subscriber as-is with no parsing. Max
+     * length: |NanCapabilities.maxServiceSpecificInfoLen|. NAN Spec: Service Descriptor Attribute
+     * (SDA) / Service Info
+     */
+    byte[] serviceSpecificInfo;
+    /**
+     * Arbitrary information communicated in discovery packets - there is no semantic meaning to
+     * these bytes. They are passed-through from publisher to subscriber as-is with no parsing. Max
+     * length: |NanCapabilities.maxExtendedServiceSpecificInfoLen|. Spec: Service Descriptor
+     * Extension Attribute (SDEA) / Service Info
+     */
+    byte[] extendedServiceSpecificInfo;
+    /**
+     * Ordered sequence of <length, value> pairs (|length| uses 1 byte and contains the number of
+     * bytes in the |value| field) which specify further match criteria (beyond the service name).
+     * The match behavior is specified in details in the NAN spec.
+     * Publisher: used in SOLICITED or SOLICITED_UNSOLICITED sessions.
+     * Subscriber: used in ACTIVE or PASSIVE sessions.
+     * Max length: |NanCapabilities.maxMatchFilterLen|.
+     * NAN Spec: matching_filter_rx
+     */
+    byte[] rxMatchFilter;
+    /**
+     * Ordered sequence of <length, value> pairs (|length| uses 1 byte and contains the number of
+     * bytes in the |value| field) which specify further match criteria (beyond the service name).
+     * The match behavior is specified in details in the NAN spec.
+     * Publisher: used if provided.
+     * Subscriber: used (if provided) only in ACTIVE sessions.
+     * Max length: |NanCapabilities.maxMatchFilterLen|.
+     * NAN Spec: matching_filter_tx and Service Descriptor Attribute (SDA) / Matching Filter
+     */
+    byte[] txMatchFilter;
+    /**
+     * Specifies whether or not the discovery session uses the
+     * |NanBandSpecificConfig.rssiCloseProximity| value (configured in enable/configure requests) to
+     * filter out matched discovered peers.
+     * NAN Spec: Service Descriptor Attribute / Service Control / Discovery Range Limited.
+     */
+    boolean useRssiThreshold;
+    /**
+     * Controls whether or not the |IWifiNanIfaceEventCallback.eventPublishTerminated| (for publish
+     * discovery sessions) or |IWifiNanIfaceEventCallback.eventSubscribeTerminated| (for subscribe
+     * discovery sessions) will be delivered.
+     */
+    boolean disableDiscoveryTerminationIndication;
+    /**
+     * Controls whether or not |IWifiNanIfaceEventCallback.eventMatchExpired| will be delivered.
+     */
+    boolean disableMatchExpirationIndication;
+    /**
+     * Controls whether or not |IWifiNanIfaceEventCallback.eventFollowupReceived| will be delivered.
+     */
+    boolean disableFollowupReceivedIndication;
+    /**
+     * Security configuration of data-paths created in the context of this discovery session.
+     * Security parameters can be overridden during the actual construction of the data-path -
+     * allowing individual data-paths to have unique PMKs or passphrases.
+     */
+    NanDataPathSecurityConfig securityConfig;
+    /**
+     * Specifies whether or not there is a ranging requirement in this discovery session.
+     * Ranging is only performed if all other match criteria with the peer are met. Ranging must
+     * be performed if both peers in the discovery session (publisher and subscriber) set this
+     * flag to true. Otherwise, if either peer sets this flag to false, ranging must not be
+     * performed and must not impact discovery decisions. Note: Specifying that ranging is required
+     * also implies that this device must automatically accept ranging requests from peers. NAN
+     * Spec: Service Discovery Extension Attribute (SDEA) / Control / Ranging Require.
+     */
+    boolean rangingRequired;
+    /**
+     * Interval in ms between two ranging measurements. Only relevant if |rangingRequired| is true.
+     * If the Awake DW interval specified either in |discoveryWindowPeriod| or in
+     * |NanBandSpecificConfig.discoveryWindowIntervalVal| is larger than the ranging interval then
+     * priority is given to Awake DW interval.
+     */
+    int rangingIntervalMs;
+    /**
+     * The type of ranging feedback to be provided by discovery session matches
+     * |IWifiNanIfaceEventCallback.eventMatch|. Only relevant if |rangingRequired| is true.
+     */
+    NanRangingIndication configRangingIndications;
+    /**
+     * The ingress and egress distance in cm. If ranging is enabled (|rangingEnabled| is true) then
+     * |configRangingIndications| is used to determine whether ingress and/or egress (or neither)
+     * are used to determine whether a match has occurred.
+     * NAN Spec: Service Discovery Extension Attribute (SDEA) / Ingress & Egress Range Limit
+     */
+    char distanceIngressCm;
+    char distanceEgressCm;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanEnableRequest.aidl b/wifi/aidl/android/hardware/wifi/NanEnableRequest.aidl
new file mode 100644
index 0000000..8c28fe1
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanEnableRequest.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+import android.hardware.wifi.NanConfigRequest;
+import android.hardware.wifi.NanDebugConfig;
+
+/**
+ * Enable requests for NAN. Start-up configuration for |IWifiNanIface.enableRequest|.
+ */
+@VintfStability
+parcelable NanEnableRequest {
+    /**
+     * Enable operation in a specific band. Indexed by |NanBandIndex|.
+     */
+    boolean[3] operateInBand;
+    /**
+     * Specify extent of cluster by specifying the max hop count.
+     */
+    byte hopCountMax;
+    /**
+     * Configurations of NAN cluster operation. Can also be modified at run-time using
+     * |IWifiNanIface.configRequest|.
+     */
+    NanConfigRequest configParams;
+    /**
+     * Non-standard configurations of NAN cluster operation. Useful for debugging operations.
+     */
+    NanDebugConfig debugConfigs;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanFollowupReceivedInd.aidl b/wifi/aidl/android/hardware/wifi/NanFollowupReceivedInd.aidl
new file mode 100644
index 0000000..20bc9b1
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanFollowupReceivedInd.aidl
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+/**
+ * Follow up message received from peer indication structure.
+ */
+@VintfStability
+parcelable NanFollowupReceivedInd {
+    /**
+     * Discovery session (publish or subscribe) ID of a previously created discovery session. The
+     * message is received in the context of this discovery session.
+     * NAN Spec: Service Descriptor Attribute (SDA) / Instance ID
+     */
+    byte discoverySessionId;
+    /**
+     * A unique ID of the peer. Can be subsequently used in |IWifiNanIface.transmitFollowupRequest|
+     * or to set up a data-path.
+     */
+    int peerId;
+    /**
+     * The NAN Discovery (management) MAC address of the peer.
+     */
+    byte[6] addr;
+    /**
+     * Indicates whether received in a further availability window (FAW) if true, or in a discovery
+     * window (DW) if false.
+     */
+    boolean receivedInFaw;
+    /**
+     * Received message from the peer. There is no semantic meaning to these bytes. They are
+     * passed-through from sender to receiver as-is with no parsing.
+     * Max length: |NanCapabilities.maxServiceSpecificInfoLen|.
+     * NAN Spec: Service Descriptor Attribute (SDA) / Service Info
+     */
+    byte[] serviceSpecificInfo;
+    /**
+     * Arbitrary information communicated in discovery packets. There is no semantic meaning to
+     * these bytes. They are passed-through from publisher to subscriber as-is with no parsing. Max
+     * length: |NanCapabilities.maxExtendedServiceSpecificInfoLen|. Spec: Service Descriptor
+     * Extension Attribute (SDEA) / Service Info
+     */
+    byte[] extendedServiceSpecificInfo;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanInitiateDataPathRequest.aidl b/wifi/aidl/android/hardware/wifi/NanInitiateDataPathRequest.aidl
new file mode 100644
index 0000000..264a873
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanInitiateDataPathRequest.aidl
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+import android.hardware.wifi.NanDataPathChannelCfg;
+import android.hardware.wifi.NanDataPathSecurityConfig;
+
+/**
+ *  Data Path Initiator requesting a data-path.
+ */
+@VintfStability
+parcelable NanInitiateDataPathRequest {
+    /**
+     * ID of the peer. Obtained as part of an earlier |IWifiNanIfaceEventCallback.eventMatch| or
+     * |IWifiNanIfaceEventCallback.eventFollowupReceived|.
+     */
+    int peerId;
+    /**
+     * NAN management interface MAC address of the peer. Obtained as part of an earlier
+     * |IWifiNanIfaceEventCallback.eventMatch| or
+     * |IWifiNanIfaceEventCallback.eventFollowupReceived|.
+     */
+    byte[6] peerDiscMacAddr;
+    /**
+     * Config flag for channel request.
+     */
+    NanDataPathChannelCfg channelRequestType;
+    /**
+     * Channel frequency in MHz to start data-path. Not relevant if |channelRequestType| is
+     * |NanDataPathChannelCfg.CHANNEL_NOT_REQUESTED|.
+     */
+    int channel;
+    /**
+     * NAN data interface name on which this data-path session is to be initiated.
+     * This must be an interface created using |IWifiNanIface.createDataInterfaceRequest|.
+     */
+    String ifaceName;
+    /**
+     * Security configuration of the requested data-path.
+     */
+    NanDataPathSecurityConfig securityConfig;
+    /**
+     * Arbitrary information communicated to the peer as part of the data-path setup process. There
+     * is no semantic meaning to these bytes. They are passed-through from sender to receiver as-is
+     * with no parsing.
+     * Max length: |NanCapabilities.maxAppInfoLen|.
+     * NAN Spec: Data Path Attributes / NDP Attribute / NDP Specific Info
+     */
+    byte[] appInfo;
+    /**
+     * A service name to be used with |passphrase| to construct a Pairwise Master Key (PMK) for the
+     * data-path. Only relevant when a data-path is requested which is not associated with a NAN
+     * discovery session - e.g. using out-of-band discovery.
+     * Constraints: same as |NanDiscoveryCommonConfig.serviceName|
+     * NAN Spec: Appendix: Mapping pass-phrase to PMK for NCS-SK Cipher Suites
+     */
+    byte[] serviceNameOutOfBand;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanMatchAlg.aidl b/wifi/aidl/android/hardware/wifi/NanMatchAlg.aidl
new file mode 100644
index 0000000..dc96a47
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanMatchAlg.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+/**
+ * NAN Match indication type. Controls how often to trigger |IWifiNanIfaceEventCallback.eventMatch|
+ * for a single discovery session - i.e. continuously discovering the same publisher with no new
+ * data.
+ */
+@VintfStability
+@Backing(type="int")
+enum NanMatchAlg {
+    MATCH_ONCE = 0,
+    MATCH_CONTINUOUS,
+    MATCH_NEVER,
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanMatchInd.aidl b/wifi/aidl/android/hardware/wifi/NanMatchInd.aidl
new file mode 100644
index 0000000..896cde0
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanMatchInd.aidl
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+import android.hardware.wifi.NanCipherSuiteType;
+import android.hardware.wifi.NanRangingIndication;
+
+/**
+ * Match indication structure.
+ */
+@VintfStability
+parcelable NanMatchInd {
+    /**
+     * Publish or subscribe discovery session ID of an existing discovery session.
+     * NAN Spec: Service Descriptor Attribute (SDA) / Instance ID
+     */
+    byte discoverySessionId;
+    /**
+     * A unique ID of the peer. Can be subsequently used in |IWifiNanIface.transmitFollowupRequest|
+     * or to set up a data-path.
+     */
+    int peerId;
+    /**
+     * The NAN Discovery (management) MAC address of the peer.
+     */
+    byte[6] addr;
+    /**
+     * The arbitrary information contained in the |NanDiscoveryCommonConfig.serviceSpecificInfo| of
+     * the peer's discovery session configuration.
+     * Max length: |NanCapabilities.maxServiceSpecificInfoLen|.
+     * NAN Spec: Service Descriptor Attribute (SDA) / Service Info
+     */
+    byte[] serviceSpecificInfo;
+    /**
+     * Arbitrary information communicated in discovery packets. There is no semantic meaning to
+     * these bytes. They are passed-through from publisher to subscriber as-is with no parsing. Max
+     * length: |NanCapabilities.maxExtendedServiceSpecificInfoLen|. Spec: Service Descriptor
+     * Extension Attribute (SDEA) / Service Info
+     */
+    byte[] extendedServiceSpecificInfo;
+    /**
+     * The match filter from the discovery packet (publish or subscribe) which caused service
+     * discovery. Matches the |NanDiscoveryCommonConfig.txMatchFilter| of the peer's Unsolicited
+     * publish message or of the local device's Active subscribe message.
+     * Max length: |NanCapabilities.maxMatchFilterLen|.
+     * NAN Spec: Service Descriptor Attribute (SDA) / Matching Filter
+     */
+    byte[] matchFilter;
+    /**
+     * Indicates the type of discovery: true if match occurred on a Beacon frame, false if the match
+     * occurred on a Service Discovery Frame (SDF).
+     */
+    boolean matchOccurredInBeaconFlag;
+    /**
+     * Flag to indicate firmware is out of resources and that it can no longer track this Service
+     * Name. Indicates that while |IWifiNanIfaceEventCallback.eventMatch| will be received, the
+     * |NanDiscoveryCommonConfig.discoveryMatchIndicator| configuration will not be honored.
+     */
+    boolean outOfResourceFlag;
+    /**
+     * If RSSI filtering was enabled using |NanDiscoveryCommonConfig.useRssiThreshold| in discovery
+     * session setup, then this field contains the received RSSI value. It will contain 0 if RSSI
+     * filtering was not enabled.
+     * RSSI values are returned without sign, e.g. -70dBm will be returned as 70.
+     */
+    byte rssiValue;
+    /**
+     * Cipher type for data-paths constructed in the context of this discovery session. Valid if
+     * |peerRequiresSecurityEnabledInNdp| is true.
+     */
+    NanCipherSuiteType peerCipherType;
+    /**
+     * Indicates whether or not the peer requires security enabled in any data-path (NDP)
+     * constructed in the context of this discovery session. The |cipherType| specifies the cipher
+     * type for such data-paths. NAN Spec: Service Discovery Extension Attribute (SDEA) / Control /
+     * Security Required
+     */
+    boolean peerRequiresSecurityEnabledInNdp;
+    /**
+     * Indicates whether or not the peer requires (and hence allows) ranging in the context of this
+     * discovery session.
+     * Note that ranging is only performed if all other match criteria with the peer are met.
+     * NAN Spec: Service Discovery Extension Attribute (SDEA) / Control / Ranging Require.
+     */
+    boolean peerRequiresRanging;
+    /**
+     * Ranging indication supersedes the NanMatchAlg specification.
+     * Ex: If NanMatchAlg is MATCH_ONCE, but ranging indication is continuous, then continuous
+     * match notifications will be received (with ranging information).
+     * Ranging indication data is provided if Ranging required is enabled in the discovery
+     * specification and:
+     *   1) continuous ranging is specified.
+     *   2) ingress/egress is specified and:
+     *       - notify once for ingress >= ingress_distance and egress <= egress_distance,
+     *       - same for ingress_egress_both
+     * If the Awake DW intervals are larger than the ranging intervals, then priority is given
+     * to the device DW intervals.
+     *
+     * If ranging was required and executed, this contains the distance to the peer in mm. The
+     * |rangingIndicationType| field specifies the event which triggered ranging.
+     */
+    int rangingMeasurementInMm;
+    /**
+     * The ranging event(s) which triggered the ranging. e.g. can indicate that continuous ranging
+     * was requested, or else that an ingress event occurred.
+     */
+    NanRangingIndication rangingIndicationType;
+    /**
+     * Security Context Identifier attribute contains PMKID. Shall be included in NDP setup and
+     * response messages. Security Context Identifie identifies the Security Context. For NAN
+     * Shared Key Cipher Suite, this field contains the 16 octet PMKID identifying the PMK used for
+     * setting up the Secure Data Path.
+     */
+    byte[] scid;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanPublishRequest.aidl b/wifi/aidl/android/hardware/wifi/NanPublishRequest.aidl
new file mode 100644
index 0000000..6dd079c
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanPublishRequest.aidl
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+import android.hardware.wifi.NanDiscoveryCommonConfig;
+import android.hardware.wifi.NanPublishType;
+import android.hardware.wifi.NanTxType;
+
+/**
+ * Publish request. Specifies a publish discovery operation.
+ */
+@VintfStability
+parcelable NanPublishRequest {
+    /**
+     * Common configuration of discovery sessions.
+     */
+    NanDiscoveryCommonConfig baseConfigs;
+    /**
+     * Type of the publish discovery session.
+     */
+    NanPublishType publishType;
+    /**
+     * For publishType of |NanPublishType.SOLICITED| or |NanPublishType.UNSOLICITED_SOLICITED|,
+     * this specifies the type of transmission used for responding to the probing subscribe
+     * discovery peer.
+     */
+    NanTxType txType;
+    /**
+     * Specifies whether data-path requests |IWifiNanIfaceEventCallback.eventDataPathRequest| (in
+     * the context of this discovery session) are automatically accepted (if true) - in which case
+     * the Responder must not call the |IWifiNanIface.respondToDataPathIndicationRequest| method and
+     * the device must automatically accept the data-path request and complete the negotiation.
+     */
+    boolean autoAcceptDataPathRequests;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanPublishType.aidl b/wifi/aidl/android/hardware/wifi/NanPublishType.aidl
new file mode 100644
index 0000000..a7a1c48
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanPublishType.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+/**
+ * NAN publish discovery session types.
+ */
+@VintfStability
+@Backing(type="int")
+enum NanPublishType {
+    UNSOLICITED = 0,
+    SOLICITED,
+    UNSOLICITED_SOLICITED,
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanRangingIndication.aidl b/wifi/aidl/android/hardware/wifi/NanRangingIndication.aidl
new file mode 100644
index 0000000..731cbfc
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanRangingIndication.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+/**
+ * Ranging in the context of discovery session indication controls. Controls
+ * the frequency of ranging-driven |IWifiNanIfaceEventCallback.eventMatch|.
+ */
+@VintfStability
+@Backing(type="int")
+enum NanRangingIndication {
+    CONTINUOUS_INDICATION_MASK = 1 << 0,
+    INGRESS_MET_MASK = 1 << 1,
+    EGRESS_MET_MASK = 1 << 2,
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanRespondToDataPathIndicationRequest.aidl b/wifi/aidl/android/hardware/wifi/NanRespondToDataPathIndicationRequest.aidl
new file mode 100644
index 0000000..6960e71
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanRespondToDataPathIndicationRequest.aidl
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+import android.hardware.wifi.NanDataPathSecurityConfig;
+
+/**
+ * Response to a data-path request from a peer.
+ */
+@VintfStability
+parcelable NanRespondToDataPathIndicationRequest {
+    /**
+     * Accept (true) or reject (false) the request.
+     * NAN Spec: Data Path Attributes / NDP Attribute / Type and Status
+     */
+    boolean acceptRequest;
+    /**
+     * ID of the data-path (NDP) for which we're responding. Obtained as part of the request in
+     * |IWifiNanIfaceEventCallback.eventDataPathRequest|.
+     */
+    int ndpInstanceId;
+    /**
+     * NAN data interface name on which this data-path session is to be started.
+     * This must be an interface created using |IWifiNanIface.createDataInterfaceRequest|.
+     */
+    String ifaceName;
+    /**
+     * Security configuration of the requested data-path.
+     */
+    NanDataPathSecurityConfig securityConfig;
+    /**
+     * Arbitrary information communicated to the peer as part of the data-path setup process. There
+     * is no semantic meaning to these bytes. They are passed-through from sender to receiver as-is
+     * with no parsing.
+     * Max length: |NanCapabilities.maxAppInfoLen|.
+     * NAN Spec: Data Path Attributes / NDP Attribute / NDP Specific Info
+     */
+    byte[] appInfo;
+    /**
+     * A service name to be used with |passphrase| to construct a Pairwise Master Key (PMK) for the
+     * data-path. Only relevant when a data-path is requested which is not associated with a NAN
+     * discovery session - e.g. using out-of-band discovery.
+     * Constraints: same as |NanDiscoveryCommonConfig.serviceName|
+     * NAN Spec: Appendix: Mapping pass-phrase to PMK for NCS-SK Cipher Suites
+     */
+    byte[] serviceNameOutOfBand;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanSrfType.aidl b/wifi/aidl/android/hardware/wifi/NanSrfType.aidl
new file mode 100644
index 0000000..4063b17
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanSrfType.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+/**
+ * NAN Service Response Filter Attribute Bit.
+ */
+@VintfStability
+@Backing(type="int")
+enum NanSrfType {
+    BLOOM_FILTER = 0,
+    PARTIAL_MAC_ADDR,
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanStatus.aidl b/wifi/aidl/android/hardware/wifi/NanStatus.aidl
new file mode 100644
index 0000000..ad29e5b
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanStatus.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+import android.hardware.wifi.NanStatusCode;
+
+/**
+ * Status information returned in NAN notifications.
+ */
+@VintfStability
+parcelable NanStatus {
+    /**
+     * Status of the command request.
+     */
+    NanStatusCode status;
+    /**
+     * Further description of the issue causing a failure.
+     */
+    String description;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanStatusCode.aidl b/wifi/aidl/android/hardware/wifi/NanStatusCode.aidl
new file mode 100644
index 0000000..d63a50e
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanStatusCode.aidl
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+/**
+ * NAN API response codes used in request notifications and events.
+ */
+@VintfStability
+@Backing(type="int")
+enum NanStatusCode {
+    SUCCESS = 0,
+    /**
+     * NAN Discovery Engine/Host driver failures.
+     */
+    INTERNAL_FAILURE = 1,
+    /**
+     * NAN OTA failures.
+     */
+    PROTOCOL_FAILURE = 2,
+    /**
+     * The publish/subscribe discovery session id is invalid.
+     */
+    INVALID_SESSION_ID = 3,
+    /**
+     * Out of resources to fufill request.
+     */
+    NO_RESOURCES_AVAILABLE = 4,
+    /**
+     * Invalid arguments passed.
+     */
+    INVALID_ARGS = 5,
+    /**
+     * Invalid peer id.
+     */
+    INVALID_PEER_ID = 6,
+    /**
+     * Invalid NAN data-path (ndp) id.
+     */
+    INVALID_NDP_ID = 7,
+    /**
+     * Attempting to enable NAN when not available, e.g. wifi is disabled.
+     */
+    NAN_NOT_ALLOWED = 8,
+    /**
+     * Over the air ACK not received.
+     */
+    NO_OTA_ACK = 9,
+    /**
+     * Attempting to enable NAN when already enabled.
+     */
+    ALREADY_ENABLED = 10,
+    /**
+     * Can't queue tx followup message for transmission.
+     */
+    FOLLOWUP_TX_QUEUE_FULL = 11,
+    /**
+     * Unsupported concurrency of NAN and another feature - NAN disabled.
+     */
+    UNSUPPORTED_CONCURRENCY_NAN_DISABLED = 12,
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanSubscribeRequest.aidl b/wifi/aidl/android/hardware/wifi/NanSubscribeRequest.aidl
new file mode 100644
index 0000000..12c1170
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanSubscribeRequest.aidl
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+import android.hardware.wifi.MacAddress;
+import android.hardware.wifi.NanDiscoveryCommonConfig;
+import android.hardware.wifi.NanSrfType;
+import android.hardware.wifi.NanSubscribeType;
+
+/**
+ * Subscribe request. Specifies a subscribe discovery operation.
+ */
+@VintfStability
+parcelable NanSubscribeRequest {
+    /**
+     * Common configuration of discovery sessions.
+     */
+    NanDiscoveryCommonConfig baseConfigs;
+    /**
+     * The type of the subscribe discovery session.
+     */
+    NanSubscribeType subscribeType;
+    /**
+     * For |NanSubscribeType.ACTIVE| subscribe discovery sessions, specifies how the Service
+     * Response Filter (SRF) attribute is populated. Relevant only if |shouldUseSrf| is set to true.
+     * NAN Spec: Service Descriptor Attribute (SDA) / Service Response Filter / SRF Control / SRF
+     * Type
+     */
+    NanSrfType srfType;
+    /**
+     * Configure whether inclusion of an address in |intfAddr| indicates that those devices should
+     * respond or the reverse. Relevant only if |shouldUseSrf| is set to true and |srfType| is set
+     * to |NanSrfType.PARTIAL_MAC_ADDR|. NAN Spec: Service Descriptor Attribute (SDA) / Service
+     * Response Filter / SRF Control / Include
+     */
+    boolean srfRespondIfInAddressSet;
+    /**
+     * Control whether the Service Response Filter (SRF) is used.
+     * NAN Spec: Service Descriptor Attribute (SDA) / Service Control /
+     *           Service Response Filter Present
+     */
+    boolean shouldUseSrf;
+    /**
+     * Control whether the presence of |NanDiscoveryCommonConfig.serviceSpecificInfo| data is needed
+     * in the publisher in order to trigger service discovery, i.e. a
+     * |IWifiNanIfaceEventCallback.eventMatch|. The test is for presence of data - not for the
+     * specific contents of the data.
+     */
+    boolean isSsiRequiredForMatch;
+    /**
+     * NAN Interface Addresses constituting the Service Response Filter (SRF).
+     * Max length (number of addresses): |NanCapabilities.maxSubscribeInterfaceAddresses|.
+     * NAN Spec: Service Descriptor Attribute (SDA) / Service Response Filter / Address Set
+     */
+    MacAddress[] intfAddr;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanSubscribeType.aidl b/wifi/aidl/android/hardware/wifi/NanSubscribeType.aidl
new file mode 100644
index 0000000..a5e8182
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanSubscribeType.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+/**
+ * NAN subscribe discovery session types.
+ */
+@VintfStability
+@Backing(type="int")
+enum NanSubscribeType {
+    PASSIVE = 0,
+    ACTIVE,
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanTransmitFollowupRequest.aidl b/wifi/aidl/android/hardware/wifi/NanTransmitFollowupRequest.aidl
new file mode 100644
index 0000000..c88b4ff
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanTransmitFollowupRequest.aidl
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+/**
+ * Transmit follow up message request.
+ */
+@VintfStability
+parcelable NanTransmitFollowupRequest {
+    /**
+     * ID of an active publish or subscribe discovery session. Follow-up message is transmitted in
+     * the context of the discovery session. NAN Spec: Service Descriptor Attribute (SDA) / Instance
+     * ID
+     */
+    byte discoverySessionId;
+    /**
+     * ID of the peer. Obtained as part of an earlier |IWifiNanIfaceEventCallback.eventMatch| or
+     * |IWifiNanIfaceEventCallback.eventFollowupReceived|.
+     */
+    int peerId;
+    /**
+     * MAC address of the peer. Obtained as part of an earlier
+     * |IWifiNanIfaceEventCallback.eventMatch| or
+     * |IWifiNanIfaceEventCallback.eventFollowupReceived|.
+     */
+    byte[6] addr;
+    /**
+     * Whether the follow-up message should be transmitted with a high priority.
+     */
+    boolean isHighPriority;
+    /**
+     * Whether the follow-up message should be transmitted in a discovery window (true) or a further
+     * availability window (false).
+     */
+    boolean shouldUseDiscoveryWindow;
+    /**
+     * Arbitrary information communicated to the peer. There is no semantic meaning to these
+     * bytes. They are passed-through from sender to receiver as-is with no parsing.
+     * Max length: |NanCapabilities.maxServiceSpecificInfoLen|.
+     * NAN Spec: Service Descriptor Attribute (SDA) / Service Info
+     */
+    byte[] serviceSpecificInfo;
+    /**
+     * Arbitrary information communicated in discovery packets. There is no semantic meaning to
+     * these bytes. They are passed-through from publisher to subscriber as-is with no parsing. Max
+     * length: |NanCapabilities.maxExtendedServiceSpecificInfoLen|. Spec: Service Descriptor
+     * Extension Attribute (SDEA) / Service Info
+     */
+    byte[] extendedServiceSpecificInfo;
+    /**
+     * Disable |IWifiNanIfaceEventCallback.eventTransmitFollowup| - i.e. do not get indication on
+     * whether the follow-up was transmitted and received successfully.
+     */
+    boolean disableFollowupResultIndication;
+}
diff --git a/wifi/aidl/android/hardware/wifi/NanTxType.aidl b/wifi/aidl/android/hardware/wifi/NanTxType.aidl
new file mode 100644
index 0000000..904a7f4
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/NanTxType.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+/**
+ * NAN transmit type used in |NanPublishType.SOLICITED| or |NanPublishType.UNSOLICITED_SOLICITED|
+ * publish discovery sessions. Describes the addressing of the packet responding to an ACTIVE
+ * subscribe query.
+ */
+@VintfStability
+@Backing(type="int")
+enum NanTxType {
+    BROADCAST = 0,
+    UNICAST,
+}
diff --git a/wifi/aidl/android/hardware/wifi/RttBw.aidl b/wifi/aidl/android/hardware/wifi/RttBw.aidl
new file mode 100644
index 0000000..9d42dc0
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/RttBw.aidl
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+/**
+ * RTT Measurement Bandwidth.
+ */
+@VintfStability
+@Backing(type="int")
+enum RttBw {
+    BW_5MHZ = 0x01,
+    BW_10MHZ = 0x02,
+    BW_20MHZ = 0x04,
+    BW_40MHZ = 0x08,
+    BW_80MHZ = 0x10,
+    BW_160MHZ = 0x20,
+    BW_320MHZ = 0x40,
+}
diff --git a/wifi/aidl/android/hardware/wifi/RttCapabilities.aidl b/wifi/aidl/android/hardware/wifi/RttCapabilities.aidl
new file mode 100644
index 0000000..7c47ed5
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/RttCapabilities.aidl
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+import android.hardware.wifi.RttBw;
+import android.hardware.wifi.RttPreamble;
+
+/**
+ * RTT Capabilities.
+ */
+@VintfStability
+parcelable RttCapabilities {
+    /**
+     * Whether 1-sided rtt data collection is supported.
+     */
+    boolean rttOneSidedSupported;
+    /**
+     * Whether ftm rtt data collection is supported.
+     */
+    boolean rttFtmSupported;
+    /**
+     * Whether initiator supports LCI request. Applies to 2-sided RTT.
+     */
+    boolean lciSupported;
+    /**
+     * Whether initiator supports LCR request. Applies to 2-sided RTT.
+     */
+    boolean lcrSupported;
+    /**
+     * Whether 11mc responder mode is supported.
+     */
+    boolean responderSupported;
+    /**
+     * Bit mask indicating what preamble is supported by initiator.
+     * Combination of |RttPreamble| values.
+     */
+    RttPreamble preambleSupport;
+    /**
+     * Bit mask indicating what BW is supported by initiator.
+     * Combination of |RttBw| values.
+     */
+    RttBw bwSupport;
+    /**
+     * Draft 11mc spec version supported by chip.
+     * For instance, version 4.0 must be 40 and version 4.3 must be 43 etc.
+     */
+    byte mcVersion;
+}
diff --git a/wifi/aidl/android/hardware/wifi/RttConfig.aidl b/wifi/aidl/android/hardware/wifi/RttConfig.aidl
new file mode 100644
index 0000000..fc2c2e0
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/RttConfig.aidl
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+import android.hardware.wifi.RttBw;
+import android.hardware.wifi.RttPeerType;
+import android.hardware.wifi.RttPreamble;
+import android.hardware.wifi.RttType;
+import android.hardware.wifi.WifiChannelInfo;
+
+/**
+ * RTT configuration.
+ */
+@VintfStability
+parcelable RttConfig {
+    /**
+     * Peer device mac address.
+     */
+    byte[6] addr;
+    /**
+     * 1-sided or 2-sided RTT.
+     */
+    RttType type;
+    /**
+     * Optional peer device hint (STA, P2P, AP).
+     */
+    RttPeerType peer;
+    /**
+     * Required for STA-AP mode, optional for P2P, NBD etc.
+     */
+    WifiChannelInfo channel;
+    /**
+     * Time interval between bursts (units: 100 ms).
+     * Applies to 1-sided and 2-sided RTT multi-burst requests.
+     * Range: 0-31, 0: no preference by initiator (2-sided RTT).
+     */
+    int burstPeriod;
+    /**
+     * Total number of RTT bursts to be executed. Will be
+     * specified in the same way as the parameter "Number of
+     * Burst Exponent" found in the FTM frame format. This
+     * applies to both 1-sided RTT and 2-sided RTT. Valid
+     * values are 0 to 15 as defined in 802.11mc std.
+     * 0 means single shot.
+     * The implication of this parameter on the maximum
+     * number of RTT results is the following:
+     * for 1-sided RTT: max num of RTT results = (2^num_burst)*(num_frames_per_burst)
+     * for 2-sided RTT: max num of RTT results = (2^num_burst)*(num_frames_per_burst - 1)
+     */
+    int numBurst;
+    /**
+     * Number of frames per burst.
+     * Minimum value = 1, Maximum value = 31
+     * For 2-sided, this equals the number of FTM frames
+     * to be attempted in a single burst. This also
+     * equals the number of FTM frames that the
+     * initiator will request that the responder sends
+     * in a single frame.
+     */
+    int numFramesPerBurst;
+    /**
+     * Number of retries for a failed RTT frame.
+     * Applies to 1-sided RTT only. Minimum value = 0, Maximum value = 3
+     */
+    int numRetriesPerRttFrame;
+    /**
+     * The following fields are only valid for 2-side RTT.
+     *
+     *
+     * Maximum number of retries that the initiator can
+     * retry an FTMR frame.
+     * Minimum value = 0, Maximum value = 3
+     */
+    int numRetriesPerFtmr;
+    /**
+     * Whether to request location civic info or not.
+     */
+    boolean mustRequestLci;
+    /**
+     * Whether to request location civic records or not.
+     */
+    boolean mustRequestLcr;
+    /**
+     * Applies to 1-sided and 2-sided RTT. Valid values will
+     * be 2-11 and 15 as specified by the 802.11mc std for
+     * the FTM parameter burst duration. In a multi-burst
+     * request, if responder overrides with larger value,
+     * the initiator will return failure. In a single-burst
+     * request, if responder overrides with larger value,
+     * the initiator will send TMR_STOP to terminate RTT
+     * at the end of the burst_duration it requested.
+     */
+    int burstDuration;
+    /**
+     * RTT preamble to be used in the RTT frames.
+     */
+    RttPreamble preamble;
+    /**
+     * RTT BW to be used in the RTT frames.
+     */
+    RttBw bw;
+}
diff --git a/wifi/aidl/android/hardware/wifi/RttLciInformation.aidl b/wifi/aidl/android/hardware/wifi/RttLciInformation.aidl
new file mode 100644
index 0000000..5a49de5
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/RttLciInformation.aidl
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+import android.hardware.wifi.RttMotionPattern;
+
+/**
+ * Movement pattern unknown.
+ */
+@VintfStability
+parcelable RttLciInformation {
+    /**
+     * Latitude in degrees * 2^25 , 2's complement.
+     */
+    long latitude;
+    /**
+     * Longitude in degrees * 2^25 , 2's complement.
+     */
+    long longitude;
+    /**
+     * Altitude in units of 1/256 m.
+     */
+    int altitude;
+    /**
+     * As defined in Section 2.3.2 of IETF RFC 6225.
+     */
+    byte latitudeUnc;
+    /**
+     * As defined in Section 2.3.2 of IETF RFC 6225.
+     */
+    byte longitudeUnc;
+    /**
+     * As defined in Section 2.4.5 from IETF RFC 6225.
+     */
+    byte altitudeUnc;
+    /**
+     * The following elements are for configuring the Z subelement.
+     *
+     *
+     * Motion pattern type.
+     */
+    RttMotionPattern motionPattern;
+    /**
+     * Floor in units of 1/16th of floor. 0x80000000 if unknown.
+     */
+    int floor;
+    /**
+     * In units of 1/64 m.
+     */
+    int heightAboveFloor;
+    /**
+     * In units of 1/64 m. 0 if unknown.
+     */
+    int heightUnc;
+}
diff --git a/wifi/aidl/android/hardware/wifi/RttLcrInformation.aidl b/wifi/aidl/android/hardware/wifi/RttLcrInformation.aidl
new file mode 100644
index 0000000..b3bb13a
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/RttLcrInformation.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+@VintfStability
+parcelable RttLcrInformation {
+    /**
+     * Country code symbol.
+     */
+    byte[2] countryCode;
+    /**
+     * Civic info to be copied in FTM frame.
+     */
+    String civicInfo;
+}
diff --git a/wifi/aidl/android/hardware/wifi/RttMotionPattern.aidl b/wifi/aidl/android/hardware/wifi/RttMotionPattern.aidl
new file mode 100644
index 0000000..00517ac
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/RttMotionPattern.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+@VintfStability
+@Backing(type="int")
+enum RttMotionPattern {
+    /**
+     * Not expected to change location.
+     */
+    NOT_EXPECTED = 0,
+    /**
+     * Expected to change location.
+     */
+    EXPECTED = 1,
+    /**
+     * Movement pattern unknown.
+     */
+    UNKNOWN = 2,
+}
diff --git a/wifi/aidl/android/hardware/wifi/RttPeerType.aidl b/wifi/aidl/android/hardware/wifi/RttPeerType.aidl
new file mode 100644
index 0000000..148a8cc
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/RttPeerType.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+/**
+ * RTT peer types.
+ */
+@VintfStability
+@Backing(type="int")
+enum RttPeerType {
+    AP = 1,
+    STA = 2,
+    P2P_GO = 3,
+    P2P_CLIENT = 4,
+    NAN_TYPE = 5,
+}
diff --git a/wifi/aidl/android/hardware/wifi/RttPreamble.aidl b/wifi/aidl/android/hardware/wifi/RttPreamble.aidl
new file mode 100644
index 0000000..e460a94
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/RttPreamble.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+/**
+ * RTT Measurement Preamble.
+ */
+@VintfStability
+@Backing(type="int")
+enum RttPreamble {
+    LEGACY = 0x1,
+    HT = 0x2,
+    VHT = 0x4,
+    /**
+     * Preamble type for 11ax
+     */
+    HE = 0x8,
+    /**
+     * Preamble type for 11be
+     */
+    EHT = 0x10,
+}
diff --git a/wifi/aidl/android/hardware/wifi/RttResponder.aidl b/wifi/aidl/android/hardware/wifi/RttResponder.aidl
new file mode 100644
index 0000000..a16f274
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/RttResponder.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+import android.hardware.wifi.RttPreamble;
+import android.hardware.wifi.WifiChannelInfo;
+
+/**
+ * RTT Responder information.
+ */
+@VintfStability
+parcelable RttResponder {
+    WifiChannelInfo channel;
+    RttPreamble preamble;
+}
diff --git a/wifi/aidl/android/hardware/wifi/RttResult.aidl b/wifi/aidl/android/hardware/wifi/RttResult.aidl
new file mode 100644
index 0000000..565cce7
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/RttResult.aidl
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+import android.hardware.wifi.RttStatus;
+import android.hardware.wifi.RttType;
+import android.hardware.wifi.WifiInformationElement;
+import android.hardware.wifi.WifiRateInfo;
+
+/**
+ * RTT results.
+ */
+@VintfStability
+parcelable RttResult {
+    /**
+     * Peer device mac address.
+     */
+    byte[6] addr;
+    /**
+     * Burst number in a multi-burst request.
+     */
+    int burstNum;
+    /**
+     * Total RTT measurement frames attempted.
+     */
+    int measurementNumber;
+    /**
+     * Total successful RTT measurement frames.
+     */
+    int successNumber;
+    /**
+     * Maximum number of "FTM frames per burst" supported by
+     * the responder STA. Applies to 2-sided RTT only.
+     * If reponder overrides with larger value:
+     * - for single-burst request, initiator will truncate the
+     * larger value and send a TMR_STOP after receiving as
+     * many frames as originally requested.
+     * - for multi-burst request, initiator will return
+     * failure right away.
+     */
+    byte numberPerBurstPeer;
+    /**
+     * Ranging status.
+     */
+    RttStatus status;
+    /**
+     * If status is RTT_STATUS_FAIL_BUSY_TRY_LATER,
+     * this will be the time provided by the responder as to
+     * when the request can be tried again. Applies to 2-sided
+     * RTT only. In sec, 1-31 sec.
+     */
+    byte retryAfterDuration;
+    /**
+     * RTT type.
+     */
+    RttType type;
+    /**
+     * Average rssi in 0.5 dB steps (e.g. 143 implies -71.5 dB).
+     */
+    int rssi;
+    /**
+     * Rssi spread in 0.5 dB steps (e.g. 5 implies 2.5 dB spread) - optional.
+     */
+    int rssiSpread;
+    /**
+     * 1-sided RTT: TX rate of RTT frame.
+     * 2-sided RTT: TX rate of initiator's Ack in response to FTM frame.
+     */
+    WifiRateInfo txRate;
+    /**
+     * 1-sided RTT: TX rate of Ack from other side.
+     * 2-sided RTT: TX rate of FTM frame coming from responder.
+     */
+    WifiRateInfo rxRate;
+    /**
+     * Round trip time in picoseconds.
+     */
+    long rtt;
+    /**
+     * Rtt standard deviation in picoseconds.
+     */
+    long rttSd;
+    /**
+     * Difference between max and min rtt times recorded in picoseconds.
+     */
+    long rttSpread;
+    /**
+     * Distance in mm (optional).
+     */
+    int distanceInMm;
+    /**
+     * Standard deviation in mm (optional).
+     */
+    int distanceSdInMm;
+    /**
+     * Difference between max and min distance recorded in mm (optional).
+     */
+    int distanceSpreadInMm;
+    /**
+     * Time of the measurement (in microseconds since boot).
+     */
+    long timeStampInUs;
+    /**
+     * Actual time taken by the FW to finish one burst
+     * measurement (in ms). Applies to 1-sided and 2-sided RTT.
+     */
+    int burstDurationInMs;
+    /**
+     * Number of bursts allowed by the responder. Applies
+     * to 2-sided RTT only.
+     */
+    int negotiatedBurstNum;
+    /**
+     * For 11mc only.
+     */
+    WifiInformationElement lci;
+    /**
+     * For 11mc only.
+     */
+    WifiInformationElement lcr;
+}
diff --git a/wifi/aidl/android/hardware/wifi/RttStatus.aidl b/wifi/aidl/android/hardware/wifi/RttStatus.aidl
new file mode 100644
index 0000000..600165c
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/RttStatus.aidl
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+/**
+ * Ranging status.
+ */
+@VintfStability
+@Backing(type="int")
+enum RttStatus {
+    SUCCESS = 0,
+    /**
+     * General failure status.
+     */
+    FAILURE = 1,
+    /**
+     * Target STA does not respond to request.
+     */
+    FAIL_NO_RSP = 2,
+    /**
+     * Request rejected. Applies to 2-sided RTT only.
+     */
+    FAIL_REJECTED = 3,
+    FAIL_NOT_SCHEDULED_YET = 4,
+    /**
+     * Timing measurement times out.
+     */
+    FAIL_TM_TIMEOUT = 5,
+    /**
+     * Target on different channel, cannot range.
+     */
+    FAIL_AP_ON_DIFF_CHANNEL = 6,
+    /**
+     * Ranging not supported.
+     */
+    FAIL_NO_CAPABILITY = 7,
+    /**
+     * Request aborted for an unknown reason.
+     */
+    ABORTED = 8,
+    /**
+     * Invalid T1-T4 timestamp.
+     */
+    FAIL_INVALID_TS = 9,
+    /**
+     * 11mc protocol failed.
+     */
+    FAIL_PROTOCOL = 10,
+    /**
+     * Request could not be scheduled.
+     */
+    FAIL_SCHEDULE = 11,
+    /**
+     * Responder cannot collaborate at time of request.
+     */
+    FAIL_BUSY_TRY_LATER = 12,
+    /**
+     * Bad request args.
+     */
+    INVALID_REQ = 13,
+    /**
+     * WiFi not enabled.
+     */
+    NO_WIFI = 14,
+    /**
+     * Responder overrides param info, cannot range with new params.
+     */
+    FAIL_FTM_PARAM_OVERRIDE = 15,
+    /**
+     * NAN ranging negotiation failure.
+     */
+    NAN_RANGING_PROTOCOL_FAILURE = 16,
+    /**
+     * NAN concurrency not supported (NDP + RTT).
+     */
+    NAN_RANGING_CONCURRENCY_NOT_SUPPORTED = 17,
+}
diff --git a/wifi/aidl/android/hardware/wifi/RttType.aidl b/wifi/aidl/android/hardware/wifi/RttType.aidl
new file mode 100644
index 0000000..e95a928
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/RttType.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+/**
+ * RTT Types.
+ */
+@VintfStability
+@Backing(type="int")
+enum RttType {
+    ONE_SIDED = 1,
+    TWO_SIDED = 2,
+}
diff --git a/wifi/aidl/android/hardware/wifi/Ssid.aidl b/wifi/aidl/android/hardware/wifi/Ssid.aidl
new file mode 100644
index 0000000..fd985a3
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/Ssid.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+/**
+ * Byte array representing an Ssid. Use when we need to
+ * pass an array of Ssid's to a method, as variable-sized
+ * 2D arrays are not supported in AIDL.
+ *
+ * TODO (b/210705533): Replace this type with a 2D byte array.
+ */
+@VintfStability
+parcelable Ssid {
+    byte[32] data;
+}
diff --git a/wifi/aidl/android/hardware/wifi/StaApfPacketFilterCapabilities.aidl b/wifi/aidl/android/hardware/wifi/StaApfPacketFilterCapabilities.aidl
new file mode 100644
index 0000000..5063b49
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/StaApfPacketFilterCapabilities.aidl
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+/**
+ * Parameters to specify the APF capabilities of this iface.
+ */
+@VintfStability
+parcelable StaApfPacketFilterCapabilities {
+    /**
+     * Version of the packet filter interpreter supported.
+     */
+    int version;
+    /**
+     * Maximum size of the filter bytecode in bytes for an iface.
+     */
+    int maxLength;
+}
diff --git a/wifi/aidl/android/hardware/wifi/StaBackgroundScanBucketEventReportSchemeMask.aidl b/wifi/aidl/android/hardware/wifi/StaBackgroundScanBucketEventReportSchemeMask.aidl
new file mode 100644
index 0000000..92e2928
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/StaBackgroundScanBucketEventReportSchemeMask.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+/**
+ * Mask of event reporting schemes that can be specified in background scan
+ * requests.
+ */
+@VintfStability
+@Backing(type="int")
+enum StaBackgroundScanBucketEventReportSchemeMask {
+    /**
+     * Report a scan completion event after scan. If this is not set, then scan
+     * completion events must be reported if report_threshold_percent or
+     * report_threshold_num_scans is reached.
+     */
+    EACH_SCAN = 1 << 0,
+    /**
+     * Forward scan results (beacons/probe responses + IEs) in real time to HAL,
+     * in addition to completion events.
+     * Note: To keep backward compatibility, fire completion events regardless
+     * of REPORT_EVENTS_EACH_SCAN.
+     */
+    FULL_RESULTS = 1 << 1,
+    /**
+     * Controls if scans for this bucket must be placed in the results buffer.
+     */
+    NO_BATCH = 1 << 2,
+}
diff --git a/wifi/aidl/android/hardware/wifi/StaBackgroundScanBucketParameters.aidl b/wifi/aidl/android/hardware/wifi/StaBackgroundScanBucketParameters.aidl
new file mode 100644
index 0000000..7bd87b2
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/StaBackgroundScanBucketParameters.aidl
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+import android.hardware.wifi.StaBackgroundScanBucketEventReportSchemeMask;
+import android.hardware.wifi.WifiBand;
+
+/**
+ * Background Scan parameters per bucket that can be specified in background
+ * scan requests.
+ */
+@VintfStability
+parcelable StaBackgroundScanBucketParameters {
+    /**
+     * Bucket index. This index is used to report results in
+     * |StaScanData.bucketsScanned|.
+     */
+    int bucketIdx;
+    /**
+     * Bands to scan or |BAND_UNSPECIFIED| if frequencies list must be used
+     * instead.
+     */
+    WifiBand band;
+    /**
+     * Channel frequencies (in Mhz) to scan if |band| is set to
+     * |BAND_UNSPECIFIED|.
+     * Max length: |StaBackgroundScanLimits.MAX_CHANNELS|.
+     */
+    int[] frequencies;
+    /**
+     * Period at which this bucket must be scanned (in milliseconds). Must be an integer
+     * multiple of the |basePeriodInMs| specified in the BackgroundScanParameters.
+     */
+    int periodInMs;
+    /**
+     * Bitset of |StaBackgroundScanBucketEventReportSchemeMask| values controlling
+     * when events for this bucket must be reported.
+     */
+    StaBackgroundScanBucketEventReportSchemeMask eventReportScheme;
+    /**
+     * For exponential back off. If |exponentialMaxPeriodInMs| is non-zero or
+     * different than period, then this bucket is an exponential backoff bucket
+     * and the scan period must grow exponentially as per formula:
+     *   actual_period(N) = period * (base ^ (N/step_count))
+     * to this maximum period (in milliseconds).
+     */
+    int exponentialMaxPeriodInMs;
+    /**
+     * For exponential back off. Multiplier: new_period=old_period * base
+     */
+    int exponentialBase;
+    /**
+     * For exponential back off. Number of scans to perform for a given
+     * period.
+     */
+    int exponentialStepCount;
+}
diff --git a/wifi/aidl/android/hardware/wifi/StaBackgroundScanCapabilities.aidl b/wifi/aidl/android/hardware/wifi/StaBackgroundScanCapabilities.aidl
new file mode 100644
index 0000000..8dd9141
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/StaBackgroundScanCapabilities.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+/**
+ * Parameters to specify the Background Scan capabilities of this iface.
+ */
+@VintfStability
+parcelable StaBackgroundScanCapabilities {
+    /**
+     * Maximum number of bytes available for cached scan results.
+     */
+    int maxCacheSize;
+    /**
+     * Maximum number of buckets that can be supplied for a scan.
+     */
+    int maxBuckets;
+    /**
+     * Maximum number of APs that must be stored for each scan.
+     */
+    int maxApCachePerScan;
+    /**
+     * Max reporting number of scans threshold that can be specified in the scan
+     * parameters.
+     */
+    int maxReportingThreshold;
+}
diff --git a/wifi/aidl/android/hardware/wifi/StaBackgroundScanLimits.aidl b/wifi/aidl/android/hardware/wifi/StaBackgroundScanLimits.aidl
new file mode 100644
index 0000000..b6fc44c
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/StaBackgroundScanLimits.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+/**
+ * Max limits for background scan.
+ */
+@VintfStability
+@Backing(type="int")
+enum StaBackgroundScanLimits {
+    MAX_CHANNELS = 16,
+    MAX_BUCKETS = 16,
+    MAX_AP_CACHE_PER_SCAN = 32,
+}
diff --git a/wifi/aidl/android/hardware/wifi/StaBackgroundScanParameters.aidl b/wifi/aidl/android/hardware/wifi/StaBackgroundScanParameters.aidl
new file mode 100644
index 0000000..0b56069
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/StaBackgroundScanParameters.aidl
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+import android.hardware.wifi.StaBackgroundScanBucketParameters;
+
+/**
+ * Background Scan parameters that can be specified in background scan
+ * requests.
+ */
+@VintfStability
+parcelable StaBackgroundScanParameters {
+    /**
+     * GCD of all bucket periods (in milliseconds).
+     */
+    int basePeriodInMs;
+    /**
+     * Maximum number of APs that must be stored for each scan. If the maximum
+     * is reached, then the highest RSSI results must be returned.
+     * Max length: |StaBackgroundScanLimits.MAX_AP_CACHE_PER_SCAN|.
+     */
+    int maxApPerScan;
+    /**
+     * % cache buffer filled threshold at which the host must be notified of
+     * batched scan results.
+     */
+    int reportThresholdPercent;
+    /**
+     * Threshold at which the AP must be woken up, in number of scans.
+     */
+    int reportThresholdNumScans;
+    /**
+     * List of buckets to be scheduled.
+     * Max length: |StaBackgroundScanLimits.MAX_BUCKETS|.
+     */
+    StaBackgroundScanBucketParameters[] buckets;
+}
diff --git a/wifi/aidl/android/hardware/wifi/StaLinkLayerIfaceContentionTimeStats.aidl b/wifi/aidl/android/hardware/wifi/StaLinkLayerIfaceContentionTimeStats.aidl
new file mode 100644
index 0000000..51f6916
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/StaLinkLayerIfaceContentionTimeStats.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+/**
+ * Contention time statistics for different traffic categories.
+ */
+@VintfStability
+parcelable StaLinkLayerIfaceContentionTimeStats {
+    /**
+     * Data packet min contention time (usec). This includes both the internal contention time
+     * among different access categories within the chipset and the contention time for the medium.
+     */
+    int contentionTimeMinInUsec;
+    /**
+     * Data packet max contention time (usec). This includes both the internal contention time
+     * among different access categories within the chipset and the contention time for the medium.
+     */
+    int contentionTimeMaxInUsec;
+    /**
+     * Data packet average contention time (usec). This includes both the internal contention time
+     * among different access categories within the chipset and the contention time for the medium.
+     */
+    int contentionTimeAvgInUsec;
+    /**
+     * Number of data packets used for contention statistics.
+     */
+    int contentionNumSamples;
+}
diff --git a/wifi/aidl/android/hardware/wifi/StaLinkLayerIfacePacketStats.aidl b/wifi/aidl/android/hardware/wifi/StaLinkLayerIfacePacketStats.aidl
new file mode 100644
index 0000000..c0e2c7b
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/StaLinkLayerIfacePacketStats.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+/**
+ * Packet stats for different traffic categories.
+ */
+@VintfStability
+parcelable StaLinkLayerIfacePacketStats {
+    /**
+     * Number of received unicast data packets.
+     */
+    long rxMpdu;
+    /**
+     * Number of successfully transmitted unicast data pkts (ACK rcvd).
+     */
+    long txMpdu;
+    /**
+     * Number of transmitted unicast data pkt losses (no ACK).
+     */
+    long lostMpdu;
+    /**
+     * Number of transmitted unicast data retry pkts.
+     */
+    long retries;
+}
diff --git a/wifi/aidl/android/hardware/wifi/StaLinkLayerIfaceStats.aidl b/wifi/aidl/android/hardware/wifi/StaLinkLayerIfaceStats.aidl
new file mode 100644
index 0000000..78f8caa
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/StaLinkLayerIfaceStats.aidl
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+import android.hardware.wifi.StaLinkLayerIfaceContentionTimeStats;
+import android.hardware.wifi.StaLinkLayerIfacePacketStats;
+import android.hardware.wifi.StaPeerInfo;
+
+/**
+ * Iface statistics for the current connection.
+ */
+@VintfStability
+parcelable StaLinkLayerIfaceStats {
+    /**
+     * Number beacons received from the connected AP.
+     */
+    int beaconRx;
+    /**
+     * Access Point Beacon and Management frames RSSI (averaged).
+     */
+    int avgRssiMgmt;
+    /**
+     * WME Best Effort Access Category packet counters.
+     */
+    StaLinkLayerIfacePacketStats wmeBePktStats;
+    /**
+     * WME Background Access Category packet counters.
+     */
+    StaLinkLayerIfacePacketStats wmeBkPktStats;
+    /**
+     * WME Video Access Category packet counters.
+     */
+    StaLinkLayerIfacePacketStats wmeViPktStats;
+    /**
+     * WME Voice Access Category packet counters.
+     */
+    StaLinkLayerIfacePacketStats wmeVoPktStats;
+    /**
+     * Duty cycle for the iface.
+     * If this iface is being served using time slicing on a radio with one or more ifaces
+     * (i.e MCC), then the duty cycle assigned to this iface in %.
+     * If not using time slicing (i.e SCC or DBS), set to 100.
+     */
+    byte timeSliceDutyCycleInPercent;
+    /**
+     * WME Best Effort (BE) Access Category (AC) contention time statistics.
+     */
+    StaLinkLayerIfaceContentionTimeStats wmeBeContentionTimeStats;
+    /**
+     * WME Background (BK) Access Category (AC) contention time statistics.
+     */
+    StaLinkLayerIfaceContentionTimeStats wmeBkContentionTimeStats;
+    /**
+     * WME Video (VI) Access Category (AC) contention time statistics.
+     */
+    StaLinkLayerIfaceContentionTimeStats wmeViContentionTimeStats;
+    /**
+     * WME Voice (VO) Access Category (AC) contention time statistics.
+     */
+    StaLinkLayerIfaceContentionTimeStats wmeVoContentionTimeStats;
+    /**
+     * Per peer statistics.
+     */
+    StaPeerInfo[] peers;
+}
diff --git a/wifi/aidl/android/hardware/wifi/StaLinkLayerRadioStats.aidl b/wifi/aidl/android/hardware/wifi/StaLinkLayerRadioStats.aidl
new file mode 100644
index 0000000..6105172
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/StaLinkLayerRadioStats.aidl
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+import android.hardware.wifi.WifiChannelStats;
+
+@VintfStability
+parcelable StaLinkLayerRadioStats {
+    /**
+     * Time for which the radio is awake.
+     */
+    int onTimeInMs;
+    /**
+     * Total time for which the radio is in active transmission.
+     */
+    int txTimeInMs;
+    /**
+     * Time for which the radio is in active tranmission per tx level.
+     */
+    int[] txTimeInMsPerLevel;
+    /**
+     * Time for which the radio is in active receive.
+     */
+    int rxTimeInMs;
+    /**
+     *  Total time for which the radio is awake due to scan.
+     */
+    int onTimeInMsForScan;
+    /**
+     * Total time for which the radio is awake due to NAN scan since boot or crash.
+     */
+    int onTimeInMsForNanScan;
+    /**
+     * Total time for which the radio is awake due to background scan since boot or crash.
+     */
+    int onTimeInMsForBgScan;
+    /**
+     * Total time for which the radio is awake due to roam scan since boot or crash.
+     */
+    int onTimeInMsForRoamScan;
+    /**
+     * Total time for which the radio is awake due to PNO scan since boot or crash.
+     */
+    int onTimeInMsForPnoScan;
+    /**
+     * Total time for which the radio is awake due to Hotspot 2.0 scans and GAS exchange since boot
+     * or crash.
+     */
+    int onTimeInMsForHs20Scan;
+    /**
+     * List of channel stats associated with this radio.
+     */
+    WifiChannelStats[] channelStats;
+    /**
+     * Radio ID: An implementation specific value identifying the radio interface for which the
+     * stats are produced. Framework must not interpret this value. It must use this value for
+     * persistently identifying the statistics between calls,
+     * e.g. if the HAL provides them in different order.
+     */
+    int radioId;
+}
diff --git a/wifi/aidl/android/hardware/wifi/StaLinkLayerStats.aidl b/wifi/aidl/android/hardware/wifi/StaLinkLayerStats.aidl
new file mode 100644
index 0000000..32be121
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/StaLinkLayerStats.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+import android.hardware.wifi.StaLinkLayerIfaceStats;
+import android.hardware.wifi.StaLinkLayerRadioStats;
+
+/**
+ * Link layer stats retrieved via |IWifiStaIface.getLinkLayerStats|.
+ */
+@VintfStability
+parcelable StaLinkLayerStats {
+    StaLinkLayerIfaceStats iface;
+    StaLinkLayerRadioStats[] radios;
+    /**
+     * Timestamp for each stats sample. This is the absolute milliseconds
+     * from boot when these stats were sampled.
+     */
+    long timeStampInMs;
+}
diff --git a/wifi/aidl/android/hardware/wifi/StaPeerInfo.aidl b/wifi/aidl/android/hardware/wifi/StaPeerInfo.aidl
new file mode 100644
index 0000000..2032802
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/StaPeerInfo.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+import android.hardware.wifi.StaRateStat;
+
+/**
+ * Per peer statistics. Types of peers include the Access Point (AP), Tunneled Direct Link
+ * Setup (TDLS), Group Owner (GO), Neighbor Awareness Networking (NAN), etc.
+ */
+@VintfStability
+parcelable StaPeerInfo {
+    /**
+     * Station count: The total number of stations currently associated with the peer.
+     */
+    char staCount;
+    /**
+     * Channel utilization: The percentage of time (normalized to 255, i.e., x% corresponds to
+     * (int) x * 255 / 100) that the medium is sensed as busy measured by either physical or
+     * virtual carrier sense (CS) mechanism.
+     */
+    char chanUtil;
+    /**
+     * Per rate statistics.
+     */
+    StaRateStat[] rateStats;
+}
diff --git a/wifi/aidl/android/hardware/wifi/StaRateStat.aidl b/wifi/aidl/android/hardware/wifi/StaRateStat.aidl
new file mode 100644
index 0000000..8326884
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/StaRateStat.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+import android.hardware.wifi.WifiRateInfo;
+
+/**
+ * Per rate statistics. The rate is characterized by the combination of preamble, number
+ * of spatial streams, transmission bandwidth, and modulation and coding scheme (MCS).
+ */
+@VintfStability
+parcelable StaRateStat {
+    /**
+     * Wifi rate information: preamble, number of spatial streams, bandwidth, MCS, etc.
+     */
+    WifiRateInfo rateInfo;
+    /**
+     * Number of successfully transmitted data packets (ACK received).
+     */
+    int txMpdu;
+    /**
+     * Number of received data packets.
+     */
+    int rxMpdu;
+    /**
+     * Number of data packet losses (no ACK).
+     */
+    int mpduLost;
+    /**
+     * Number of data packet retries.
+     */
+    int retries;
+}
diff --git a/wifi/aidl/android/hardware/wifi/StaRoamingCapabilities.aidl b/wifi/aidl/android/hardware/wifi/StaRoamingCapabilities.aidl
new file mode 100644
index 0000000..7642612
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/StaRoamingCapabilities.aidl
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+/**
+ * Structure describing the roaming control capabilities supported.
+ */
+@VintfStability
+parcelable StaRoamingCapabilities {
+    /**
+     * Maximum number of BSSIDs that may be blocklisted.
+     */
+    int maxBlocklistSize;
+    /**
+     * Maximum number of SSIDs that may be allowlisted.
+     */
+    int maxAllowlistSize;
+}
diff --git a/wifi/aidl/android/hardware/wifi/StaRoamingConfig.aidl b/wifi/aidl/android/hardware/wifi/StaRoamingConfig.aidl
new file mode 100644
index 0000000..c59c531
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/StaRoamingConfig.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+import android.hardware.wifi.MacAddress;
+import android.hardware.wifi.Ssid;
+
+/**
+ * Structure describing the roaming control configuration.
+ */
+@VintfStability
+parcelable StaRoamingConfig {
+    /**
+     * List of BSSIDs that are blocklisted for roaming.
+     */
+    MacAddress[] bssidBlocklist;
+    /**
+     * List of SSIDs that are allowlisted for roaming.
+     */
+    Ssid[] ssidAllowlist;
+}
diff --git a/wifi/aidl/android/hardware/wifi/StaRoamingState.aidl b/wifi/aidl/android/hardware/wifi/StaRoamingState.aidl
new file mode 100644
index 0000000..d75d323
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/StaRoamingState.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+/**
+ * Enum describing the various states to set the roaming
+ * control to.
+ */
+@VintfStability
+@Backing(type="byte")
+enum StaRoamingState {
+    /**
+     * Driver/Firmware must not perform any roaming.
+     */
+    DISABLED = 0,
+    /**
+     * Driver/Firmware is allowed to perform roaming while respecting
+     * the |StaRoamingConfig| parameters set using |configureRoaming|.
+     */
+    ENABLED = 1,
+}
diff --git a/wifi/aidl/android/hardware/wifi/StaScanData.aidl b/wifi/aidl/android/hardware/wifi/StaScanData.aidl
new file mode 100644
index 0000000..9d6bd53
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/StaScanData.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+import android.hardware.wifi.StaScanDataFlagMask;
+import android.hardware.wifi.StaScanResult;
+
+/**
+ * Structure describing all of the access points seen during
+ * the scan.
+ */
+@VintfStability
+parcelable StaScanData {
+    /**
+     * Bitset containing |ScanDataFlagMask| values.
+     */
+    StaScanDataFlagMask flags;
+    /**
+     * Bitset where each bit indicates if the bucket with that index (starting at
+     * 0) was scanned.
+     */
+    int bucketsScanned;
+    /**
+     * List of scan results.
+     */
+    StaScanResult[] results;
+}
diff --git a/wifi/aidl/android/hardware/wifi/StaScanDataFlagMask.aidl b/wifi/aidl/android/hardware/wifi/StaScanDataFlagMask.aidl
new file mode 100644
index 0000000..ea87df5
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/StaScanDataFlagMask.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+/**
+ * Mask of flags set in the |ScanData| instance.
+ */
+@VintfStability
+@Backing(type="int")
+enum StaScanDataFlagMask {
+    /**
+     * Indicates that a scan was interrupted/did not occur, so results may be
+     * incomplete.
+     */
+    INTERRUPTED = 1 << 0,
+}
diff --git a/wifi/aidl/android/hardware/wifi/StaScanResult.aidl b/wifi/aidl/android/hardware/wifi/StaScanResult.aidl
new file mode 100644
index 0000000..9f6f415
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/StaScanResult.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+import android.hardware.wifi.WifiInformationElement;
+
+/**
+ * Structure describing all the information about a single access point seen
+ * during the scan.
+ */
+@VintfStability
+parcelable StaScanResult {
+    long timeStampInUs;
+    byte[] ssid;
+    byte[6] bssid;
+    int rssi;
+    int frequency;
+    char beaconPeriodInMs;
+    char capability;
+    WifiInformationElement[] informationElements;
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiAntennaMode.aidl b/wifi/aidl/android/hardware/wifi/WifiAntennaMode.aidl
new file mode 100644
index 0000000..e21dd87
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiAntennaMode.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+/**
+ * Antenna configuration.
+ */
+@VintfStability
+@Backing(type="int")
+enum WifiAntennaMode {
+    WIFI_ANTENNA_MODE_UNSPECIFIED = 0,
+    WIFI_ANTENNA_MODE_1X1 = 1,
+    WIFI_ANTENNA_MODE_2X2 = 2,
+    WIFI_ANTENNA_MODE_3X3 = 3,
+    WIFI_ANTENNA_MODE_4X4 = 4,
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiBand.aidl b/wifi/aidl/android/hardware/wifi/WifiBand.aidl
new file mode 100644
index 0000000..cfdf944
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiBand.aidl
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+/**
+ * Wifi bands defined in the 80211 spec.
+ */
+@VintfStability
+@Backing(type="int")
+enum WifiBand {
+    BAND_UNSPECIFIED = 0,
+    /**
+     * 2.4 GHz.
+     */
+    BAND_24GHZ = 1,
+    /**
+     * 5 GHz without DFS.
+     */
+    BAND_5GHZ = 2,
+    /**
+     * 5 GHz DFS only.
+     */
+    BAND_5GHZ_DFS = 4,
+    /**
+     * 5 GHz with DFS.
+     */
+    BAND_5GHZ_WITH_DFS = 6,
+    /**
+     * 2.4 GHz + 5 GHz; no DFS.
+     */
+    BAND_24GHZ_5GHZ = 3,
+    /**
+     * 2.4 GHz + 5 GHz with DFS.
+     */
+    BAND_24GHZ_5GHZ_WITH_DFS = 7,
+    /**
+     * 6 GHz.
+     */
+    BAND_6GHZ = 8,
+    /**
+     * 5 GHz no DFS + 6 GHz.
+     */
+    BAND_5GHZ_6GHZ = 10,
+    /**
+     * 2.4 GHz + 5 GHz no DFS + 6 GHz.
+     */
+    BAND_24GHZ_5GHZ_6GHZ = 11,
+    /**
+     * 2.4 GHz + 5 GHz with DFS + 6 GHz.
+     */
+    BAND_24GHZ_5GHZ_WITH_DFS_6GHZ = 15,
+    /**
+     * 60 GHz.
+     */
+    BAND_60GHZ = 16,
+    /**
+     * 2.4 GHz + 5 GHz no DFS + 6 GHz + 60 GHz.
+     */
+    BAND_24GHZ_5GHZ_6GHZ_60GHZ = 27,
+    /**
+     * 2.4 GHz + 5 GHz with DFS + 6 GHz + 60 GHz.
+     */
+    BAND_24GHZ_5GHZ_WITH_DFS_6GHZ_60GHZ = 31,
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiChannelInfo.aidl b/wifi/aidl/android/hardware/wifi/WifiChannelInfo.aidl
new file mode 100644
index 0000000..8fee7eb
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiChannelInfo.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+import android.hardware.wifi.WifiChannelWidthInMhz;
+
+/**
+ * Channel information.
+ */
+@VintfStability
+parcelable WifiChannelInfo {
+    /**
+     * Channel width (20, 40, 80, 80+80, 160, 320).
+     */
+    WifiChannelWidthInMhz width;
+    /**
+     * Primary 20 MHz channel.
+     */
+    int centerFreq;
+    /**
+     * Center frequency (MHz) first segment.
+     */
+    int centerFreq0;
+    /**
+     * Center frequency (MHz) second segment.
+     */
+    int centerFreq1;
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiChannelStats.aidl b/wifi/aidl/android/hardware/wifi/WifiChannelStats.aidl
new file mode 100644
index 0000000..f77821b
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiChannelStats.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+import android.hardware.wifi.WifiChannelInfo;
+
+@VintfStability
+parcelable WifiChannelStats {
+    /**
+     * Channel information.
+     */
+    WifiChannelInfo channel;
+    /**
+     * Total time for which the radio is awake on this channel.
+     */
+    int onTimeInMs;
+    /**
+     * Total time for which CCA is held busy on this channel.
+     */
+    int ccaBusyTimeInMs;
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiChannelWidthInMhz.aidl b/wifi/aidl/android/hardware/wifi/WifiChannelWidthInMhz.aidl
new file mode 100644
index 0000000..e456530
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiChannelWidthInMhz.aidl
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+/**
+ * Channel operating width in Mhz.
+ */
+@VintfStability
+@Backing(type="int")
+enum WifiChannelWidthInMhz {
+    WIDTH_INVALID = -1,
+    WIDTH_20 = 0,
+    WIDTH_40 = 1,
+    WIDTH_80 = 2,
+    WIDTH_160 = 3,
+    WIDTH_80P80 = 4,
+    WIDTH_5 = 5,
+    WIDTH_10 = 6,
+    /**
+     * 320 MHz
+     */
+    WIDTH_320 = 7,
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiDebugHostWakeReasonRxIcmpPacketDetails.aidl b/wifi/aidl/android/hardware/wifi/WifiDebugHostWakeReasonRxIcmpPacketDetails.aidl
new file mode 100644
index 0000000..8cf4819
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiDebugHostWakeReasonRxIcmpPacketDetails.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+/**
+ * Struct capturing the count of all rx ICMP packets that caused
+ * host wakeup.
+ */
+@VintfStability
+parcelable WifiDebugHostWakeReasonRxIcmpPacketDetails {
+    /**
+     * Wake icmp packet count.
+     */
+    int icmpPkt;
+    /**
+     * Wake icmp6 packet count.
+     */
+    int icmp6Pkt;
+    /**
+     * Wake icmp6 RA packet count.
+     */
+    int icmp6Ra;
+    /**
+     * Wake icmp6 NA packet count.
+     */
+    int icmp6Na;
+    /**
+     * Wake icmp6 NS packet count.
+     */
+    int icmp6Ns;
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiDebugHostWakeReasonRxMulticastPacketDetails.aidl b/wifi/aidl/android/hardware/wifi/WifiDebugHostWakeReasonRxMulticastPacketDetails.aidl
new file mode 100644
index 0000000..51faf66
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiDebugHostWakeReasonRxMulticastPacketDetails.aidl
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+/**
+ * Struct capturing the count of all rx multicast packets that caused
+ * host wakeup.
+ */
+@VintfStability
+parcelable WifiDebugHostWakeReasonRxMulticastPacketDetails {
+    /**
+     * Rx wake packet was ipv4 multicast.
+     */
+    int ipv4RxMulticastAddrCnt;
+    /**
+     * Rx wake packet was ipv6 multicast.
+     */
+    int ipv6RxMulticastAddrCnt;
+    /**
+     * Rx wake packet was non-ipv4 and non-ipv6.
+     */
+    int otherRxMulticastAddrCnt;
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiDebugHostWakeReasonRxPacketDetails.aidl b/wifi/aidl/android/hardware/wifi/WifiDebugHostWakeReasonRxPacketDetails.aidl
new file mode 100644
index 0000000..b5c6a5e
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiDebugHostWakeReasonRxPacketDetails.aidl
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+/**
+ * Struct capturing the count of all rx packets that caused
+ * host wakeup.
+ */
+@VintfStability
+parcelable WifiDebugHostWakeReasonRxPacketDetails {
+    /**
+     * Total rx unicast packet which woke up host.
+     */
+    int rxUnicastCnt;
+    /**
+     * Total rx multicast packet which woke up host.
+     */
+    int rxMulticastCnt;
+    /**
+     * Total rx broadcast packet which woke up host.
+     */
+    int rxBroadcastCnt;
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiDebugHostWakeReasonStats.aidl b/wifi/aidl/android/hardware/wifi/WifiDebugHostWakeReasonStats.aidl
new file mode 100644
index 0000000..82d5d3e
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiDebugHostWakeReasonStats.aidl
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+import android.hardware.wifi.WifiDebugHostWakeReasonRxIcmpPacketDetails;
+import android.hardware.wifi.WifiDebugHostWakeReasonRxMulticastPacketDetails;
+import android.hardware.wifi.WifiDebugHostWakeReasonRxPacketDetails;
+
+/**
+ * Structure capturing the count of all the wireless related host wakeup.
+ * This is used to capture all the reasons why the host processor
+ * (WLAN driver) was woken up by the WLAN firmware.
+ * These stats may be used to debug any power issues caused due to frequent
+ * wakeup of the host processor by the WLAN firmware.
+ */
+@VintfStability
+parcelable WifiDebugHostWakeReasonStats {
+    /**
+     * Total count of cmd/event wakes.
+     * These must account for all wakeups due to WLAN management
+     * commands/events received over the air.
+     */
+    int totalCmdEventWakeCnt;
+    /**
+     * Vector of wake counts per cmd/event type.
+     * The number of command types and their meaning is only understood by the
+     * vendor.
+     */
+    int[] cmdEventWakeCntPerType;
+    /**
+     * Total count of driver/firmware wakes.
+     * These must account for all wakeups due to local driver/firmware
+     * interactions. These include all vendor implementation specific
+     * interactions like any heart-beat monitoring, bus management, etc.
+     */
+    int totalDriverFwLocalWakeCnt;
+    /**
+     * Vector of wake counts per driver/firmware interaction type.
+     * The number of command types and their meaning is only understood by the
+     * vendor.
+     */
+    int[] driverFwLocalWakeCntPerType;
+    /**
+     * Total data rx packets that woke up host.
+     */
+    int totalRxPacketWakeCnt;
+    WifiDebugHostWakeReasonRxPacketDetails rxPktWakeDetails;
+    WifiDebugHostWakeReasonRxMulticastPacketDetails rxMulticastPkWakeDetails;
+    WifiDebugHostWakeReasonRxIcmpPacketDetails rxIcmpPkWakeDetails;
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiDebugPacketFateFrameInfo.aidl b/wifi/aidl/android/hardware/wifi/WifiDebugPacketFateFrameInfo.aidl
new file mode 100644
index 0000000..7601bf2
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiDebugPacketFateFrameInfo.aidl
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+import android.hardware.wifi.WifiDebugPacketFateFrameType;
+
+/**
+ * Information regarding the frame transmitted/received.
+ */
+@VintfStability
+parcelable WifiDebugPacketFateFrameInfo {
+    /**
+     * The type of MAC-layer frame that this frame_info holds.
+     * - For data frames, use FRAME_TYPE_ETHERNET_II.
+     * - For management frames, use FRAME_TYPE_80211_MGMT.
+     * - If the type of the frame is unknown, use FRAME_TYPE_UNKNOWN.
+     */
+    WifiDebugPacketFateFrameType frameType;
+    /**
+     * The number of bytes included in |frameContent|.
+     * If the frame contents are missing (e.g. RX frame dropped in firmware),
+     * |frameLen| must be set to 0.
+     */
+    long frameLen;
+    /**
+     * Host clock when this frame was received by the driver (either outbound
+     * from the host network stack, or inbound from the firmware).
+     * - The timestamp must be taken from a clock which includes time the host
+     *   spent suspended (e.g. ktime_get_boottime()).
+     * - If no host timestamp is available (e.g. RX frame was dropped in firmware),
+     *   this field must be set to 0.
+     */
+    long driverTimestampUsec;
+    /**
+     * Firmware clock when this frame was received by the firmware
+     * (either outbound from the host, or inbound from a remote  station).
+     * - The timestamp must be taken from a clock which includes time firmware
+     *   spent suspended (if applicable).
+     * - If no firmware timestamp is available (e.g. TX frame was dropped by the
+     *   driver), then this field must be set to 0.
+     * - Consumers of |frameInfo| must not assume any synchronization between
+     *   the driver and firmware clocks.
+     */
+    long firmwareTimestampUsec;
+    /**
+     * Actual frame content. This is the raw bytes of the corresponding packet.
+     * - Should be provided for TX frames originated by the host.
+     * - Should be provided for RX frames received by the driver.
+     * - Optionally provided for TX frames originated by firmware.
+     *   (At discretion of HAL implementation.)
+     * - Optionally provided for RX frames dropped in firmware.
+     *   (At discretion of HAL implementation.)
+     * - If frame content is not provided, |frameLen| must be set to 0.
+     */
+    byte[] frameContent;
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiDebugPacketFateFrameType.aidl b/wifi/aidl/android/hardware/wifi/WifiDebugPacketFateFrameType.aidl
new file mode 100644
index 0000000..5c0d171
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiDebugPacketFateFrameType.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+/**
+ * Type of frame transmitted/received.
+ */
+@VintfStability
+@Backing(type="int")
+enum WifiDebugPacketFateFrameType {
+    UNKNOWN,
+    ETHERNET_II,
+    MGMT_80211,
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiDebugRingBufferFlags.aidl b/wifi/aidl/android/hardware/wifi/WifiDebugRingBufferFlags.aidl
new file mode 100644
index 0000000..0d1806e
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiDebugRingBufferFlags.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+/**
+ * Flags describing each debug ring buffer.
+ */
+@VintfStability
+@Backing(type="int")
+enum WifiDebugRingBufferFlags {
+    HAS_BINARY_ENTRIES = 1 << 0,
+    HAS_ASCII_ENTRIES = 1 << 1,
+    HAS_PER_PACKET_ENTRIES = 1 << 2,
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiDebugRingBufferStatus.aidl b/wifi/aidl/android/hardware/wifi/WifiDebugRingBufferStatus.aidl
new file mode 100644
index 0000000..2b0faa2
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiDebugRingBufferStatus.aidl
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+/**
+ * Struct describing each debug ring buffer supported by
+ * the device.
+ */
+@VintfStability
+parcelable WifiDebugRingBufferStatus {
+    /**
+     * Name of this debug ring buffer.
+     */
+    String ringName;
+    /**
+     * Combination of |WifiDebugRingBufferFlags| values.
+     */
+    int flags;
+    /**
+     * Unique integer representing the ring.
+     */
+    int ringId;
+    /**
+     * Total memory size allocated for the buffer.
+     */
+    int sizeInBytes;
+    /**
+     * Amount of free space in the buffer.
+     */
+    int freeSizeInBytes;
+    /**
+     * Verbose level for ring buffer.
+     */
+    int verboseLevel;
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiDebugRingBufferVerboseLevel.aidl b/wifi/aidl/android/hardware/wifi/WifiDebugRingBufferVerboseLevel.aidl
new file mode 100644
index 0000000..30778eb
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiDebugRingBufferVerboseLevel.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+/**
+ * Verbose logging level to set for each debug ring buffer supported
+ * by the device.
+ */
+@VintfStability
+@Backing(type="int")
+enum WifiDebugRingBufferVerboseLevel {
+    /**
+     * Level 0 corresponds to no collection, and it makes log handler
+     * stop by no more events from driver.
+     */
+    NONE = 0,
+    /**
+     * Level 1 corresponds to normal log level, with minimal user impact.
+     * This is the default value.
+     */
+    DEFAULT = 1,
+    /**
+     * Level 2 is enabled when user is lazily trying to reproduce a problem.
+     * Wifi performance and power can be impacted, but device should not
+     * otherwise be significantly impacted.
+     */
+    VERBOSE = 2,
+    /**
+     * Level 3 is used when trying to actively debug a problem.
+     * This will cause severe performance degradation.
+     */
+    EXCESSIVE = 3,
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiDebugRxPacketFate.aidl b/wifi/aidl/android/hardware/wifi/WifiDebugRxPacketFate.aidl
new file mode 100644
index 0000000..2983f81
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiDebugRxPacketFate.aidl
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+/**
+ * Enum describing the fate of the RX packets.
+ */
+@VintfStability
+@Backing(type="int")
+enum WifiDebugRxPacketFate {
+    /**
+     * Valid and delivered to network stack (e.g., netif_rx()).
+     */
+    SUCCESS,
+    /**
+     * Queued within firmware, but not yet sent to driver.
+     */
+    FW_QUEUED,
+    /**
+     * Dropped by firmware due to host-programmable filters.
+     */
+    FW_DROP_FILTER,
+    /**
+     * Dropped by firmware as invalid (e.g. bad checksum, decrypt failed,
+     * or invalid for current state).
+     */
+    FW_DROP_INVALID,
+    /**
+     * Dropped by firmware due to lack of buffer space.
+     */
+    FW_DROP_NOBUFS,
+    /**
+     * Dropped by firmware for any other reason.
+     */
+    FW_DROP_OTHER,
+    /**
+     * Queued within driver, not yet delivered to network stack.
+     */
+    DRV_QUEUED,
+    /**
+     * Dropped by driver due to filter rules.
+     */
+    DRV_DROP_FILTER,
+    /**
+     * Dropped by driver as invalid (e.g. not permitted in current state).
+     */
+    DRV_DROP_INVALID,
+    /**
+     * Dropped by driver due to lack of buffer space.
+     */
+    DRV_DROP_NOBUFS,
+    /**
+     * Dropped by driver for any other reason.
+     */
+    DRV_DROP_OTHER,
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiDebugRxPacketFateReport.aidl b/wifi/aidl/android/hardware/wifi/WifiDebugRxPacketFateReport.aidl
new file mode 100644
index 0000000..f4d709c
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiDebugRxPacketFateReport.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+import android.hardware.wifi.WifiDebugPacketFateFrameInfo;
+import android.hardware.wifi.WifiDebugRxPacketFate;
+
+/**
+ * Struct describing packet fate report for each Rx frame.
+ */
+@VintfStability
+parcelable WifiDebugRxPacketFateReport {
+    WifiDebugRxPacketFate fate;
+    WifiDebugPacketFateFrameInfo frameInfo;
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiDebugTxPacketFate.aidl b/wifi/aidl/android/hardware/wifi/WifiDebugTxPacketFate.aidl
new file mode 100644
index 0000000..717d62a
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiDebugTxPacketFate.aidl
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+/**
+ * Enum describing the fate of the TX packets.
+ */
+@VintfStability
+@Backing(type="int")
+enum WifiDebugTxPacketFate {
+    /**
+     * Sent over air and ACKed.
+     */
+    ACKED,
+    /**
+     * Sent over air but not ACKed (normal for broadcast/multicast).
+     */
+    SENT,
+    /**
+     * Queued within firmware, but not yet sent over air.
+     */
+    FW_QUEUED,
+    /**
+     * Dropped by firmware as invalid (e.g. bad source address, bad checksum,
+     * or invalid for current state).
+     */
+    FW_DROP_INVALID,
+    /**
+     * Dropped by firmware due to lack of buffer space.
+     */
+    FW_DROP_NOBUFS,
+    /**
+     * Dropped by firmware for any other reason. Includes frames that were sent
+     * by driver to the firmware, but unaccounted for by firmware.
+     */
+    FW_DROP_OTHER,
+    /**
+     * Queued within driver, not yet sent to firmware.
+     */
+    DRV_QUEUED,
+    /**
+     * Dropped by driver as invalid (e.g. bad source address, or invalid for
+     * current state).
+     */
+    DRV_DROP_INVALID,
+    /**
+     * Dropped by driver due to lack of buffer space.
+     */
+    DRV_DROP_NOBUFS,
+    /**
+     * Dropped by driver for any other reason.
+     */
+    DRV_DROP_OTHER,
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiDebugTxPacketFateReport.aidl b/wifi/aidl/android/hardware/wifi/WifiDebugTxPacketFateReport.aidl
new file mode 100644
index 0000000..b59b0a5
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiDebugTxPacketFateReport.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+import android.hardware.wifi.WifiDebugPacketFateFrameInfo;
+import android.hardware.wifi.WifiDebugTxPacketFate;
+
+/**
+ * Struct describing packet fate report for each Tx frame.
+ */
+@VintfStability
+parcelable WifiDebugTxPacketFateReport {
+    WifiDebugTxPacketFate fate;
+    WifiDebugPacketFateFrameInfo frameInfo;
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiIfaceMode.aidl b/wifi/aidl/android/hardware/wifi/WifiIfaceMode.aidl
new file mode 100644
index 0000000..f70c744
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiIfaceMode.aidl
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+/**
+ * Interface operating modes.
+ */
+@VintfStability
+@Backing(type="int")
+enum WifiIfaceMode {
+    /**
+     * Interface operation mode is client.
+     */
+    IFACE_MODE_STA = 1 << 0,
+    /**
+     * Interface operation mode is Hotspot.
+     */
+    IFACE_MODE_SOFTAP = 1 << 1,
+    /**
+     * Interface operation mode is Ad-Hoc network.
+     */
+    IFACE_MODE_IBSS = 1 << 2,
+    /**
+     * Interface operation mode is Wifi Direct Client.
+     */
+    IFACE_MODE_P2P_CLIENT = 1 << 3,
+    /**
+     * Interface operation mode is Wifi Direct Group Owner.
+     */
+    IFACE_MODE_P2P_GO = 1 << 4,
+    /**
+     * Interface operation mode is Aware.
+     */
+    IFACE_MODE_NAN = 1 << 5,
+    /**
+     * Interface operation mode is Mesh network.
+     */
+    IFACE_MODE_MESH = 1 << 6,
+    /**
+     * Interface operation mode is Tunneled Direct Link Setup.
+     */
+    IFACE_MODE_TDLS = 1 << 7,
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiInformationElement.aidl b/wifi/aidl/android/hardware/wifi/WifiInformationElement.aidl
new file mode 100644
index 0000000..f5f6de9
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiInformationElement.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+/**
+ * Information elements contained within the |ScanResult| structure.
+ * These elements correspond to the IEEE_802.11 standard.
+ */
+@VintfStability
+parcelable WifiInformationElement {
+    byte id;
+    byte[] data;
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiRadioCombination.aidl b/wifi/aidl/android/hardware/wifi/WifiRadioCombination.aidl
new file mode 100644
index 0000000..28b15ed
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiRadioCombination.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+import android.hardware.wifi.WifiRadioConfiguration;
+
+/**
+ * Wifi radio combination.
+ */
+@VintfStability
+parcelable WifiRadioCombination {
+    /**
+     * List of radio configurations in this combination.
+     */
+    WifiRadioConfiguration[] radioConfigurations;
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiRadioCombinationMatrix.aidl b/wifi/aidl/android/hardware/wifi/WifiRadioCombinationMatrix.aidl
new file mode 100644
index 0000000..b79a818
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiRadioCombinationMatrix.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+import android.hardware.wifi.WifiRadioCombination;
+
+/**
+ * Wifi radio combinations matrix retrieved via
+ * |IWifiChip.getSupportedRadioCombinationsMatrix|.
+ */
+@VintfStability
+parcelable WifiRadioCombinationMatrix {
+    /**
+     * List of all the possible radio combinations that the chip can operate.
+     */
+    WifiRadioCombination[] radioCombinations;
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiRadioConfiguration.aidl b/wifi/aidl/android/hardware/wifi/WifiRadioConfiguration.aidl
new file mode 100644
index 0000000..ae8eff3
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiRadioConfiguration.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+import android.hardware.wifi.WifiAntennaMode;
+import android.hardware.wifi.WifiBand;
+
+/**
+ * Wifi radio configuration.
+ */
+@VintfStability
+parcelable WifiRadioConfiguration {
+    /**
+     * Band on which this radio chain is operating.
+     * Valid values of bandInfo are: BAND_24GHZ, BAND_5GHZ, BAND_6GHZ and
+     * BAND_60GHZ.
+     *
+     */
+    WifiBand bandInfo;
+    /**
+     * Wifi Antenna configuration.
+     */
+    WifiAntennaMode antennaMode;
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiRateInfo.aidl b/wifi/aidl/android/hardware/wifi/WifiRateInfo.aidl
new file mode 100644
index 0000000..c4e285e
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiRateInfo.aidl
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+import android.hardware.wifi.WifiChannelWidthInMhz;
+import android.hardware.wifi.WifiRateNss;
+import android.hardware.wifi.WifiRatePreamble;
+
+/**
+ * Wifi rate info.
+ */
+@VintfStability
+parcelable WifiRateInfo {
+    /**
+     * Preamble used for RTT measurements.
+     */
+    WifiRatePreamble preamble;
+    /**
+     * Number of spatial streams.
+     */
+    WifiRateNss nss;
+    /**
+     * Bandwidth of channel.
+     */
+    WifiChannelWidthInMhz bw;
+    /**
+     * OFDM/CCK rate code as per IEEE std in units of 0.5mbps.
+     * HT/VHT/HE/EHT would be mcs index.
+     */
+    byte rateMcsIdx;
+    /**
+     * Bitrate in units of 100 Kbps.
+     */
+    int bitRateInKbps;
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiRateNss.aidl b/wifi/aidl/android/hardware/wifi/WifiRateNss.aidl
new file mode 100644
index 0000000..0c263a5
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiRateNss.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+/**
+ * Number of spatial streams in VHT/HT.
+ */
+@VintfStability
+@Backing(type="int")
+enum WifiRateNss {
+    NSS_1x1 = 0,
+    NSS_2x2 = 1,
+    NSS_3x3 = 2,
+    NSS_4x4 = 3,
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiRatePreamble.aidl b/wifi/aidl/android/hardware/wifi/WifiRatePreamble.aidl
new file mode 100644
index 0000000..116e46a
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiRatePreamble.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+/**
+ * Wifi Rate Preamble.
+ */
+@VintfStability
+@Backing(type="int")
+enum WifiRatePreamble {
+    OFDM = 0,
+    CCK = 1,
+    HT = 2,
+    VHT = 3,
+    RESERVED = 4,
+    /**
+     * Preamble type for 11ax.
+     */
+    HE = 5,
+    /**
+     * Preamble type for 11be.
+     */
+    EHT = 6,
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiStatusCode.aidl b/wifi/aidl/android/hardware/wifi/WifiStatusCode.aidl
new file mode 100644
index 0000000..30817f3
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiStatusCode.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+/**
+ * Enum values indicating the status of the WiFi operation.
+ */
+@VintfStability
+@Backing(type="int")
+enum WifiStatusCode {
+    /**
+     * No errors.
+     */
+    SUCCESS,
+    /**
+     * Method invoked on an invalid |IWifiChip| object.
+     */
+    ERROR_WIFI_CHIP_INVALID,
+    /**
+     * Method invoked on an invalid |IWifiIface| object.
+     */
+    ERROR_WIFI_IFACE_INVALID,
+    /**
+     * Method invoked on an invalid |IWifiRttController| object.
+     */
+    ERROR_WIFI_RTT_CONTROLLER_INVALID,
+    ERROR_NOT_SUPPORTED,
+    ERROR_NOT_AVAILABLE,
+    ERROR_NOT_STARTED,
+    ERROR_INVALID_ARGS,
+    ERROR_BUSY,
+    ERROR_UNKNOWN,
+}
diff --git a/wifi/aidl/android/hardware/wifi/WifiUsableChannel.aidl b/wifi/aidl/android/hardware/wifi/WifiUsableChannel.aidl
new file mode 100644
index 0000000..d92e4cc
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/WifiUsableChannel.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 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.wifi;
+
+import android.hardware.wifi.WifiChannelWidthInMhz;
+import android.hardware.wifi.WifiIfaceMode;
+
+/**
+ * Wifi usable channel information.
+ */
+@VintfStability
+parcelable WifiUsableChannel {
+    /**
+     * Wifi channel freqeuncy in MHz.
+     */
+    int channel;
+    /**
+     * Wifi channel bandwidth in MHz.
+     */
+    WifiChannelWidthInMhz channelBandwidth;
+    /**
+     * Iface modes feasible on this channel.
+     */
+    WifiIfaceMode ifaceModeMask;
+}
diff --git a/wifi/hostapd/1.2/vts/functional/Android.bp b/wifi/hostapd/1.2/vts/functional/Android.bp
index 9609da5..26edab5 100644
--- a/wifi/hostapd/1.2/vts/functional/Android.bp
+++ b/wifi/hostapd/1.2/vts/functional/Android.bp
@@ -31,12 +31,17 @@
     ],
     static_libs: [
         "VtsHalWifiV1_0TargetTestUtil",
+        "VtsHalWifiV1_4TargetTestUtil",
         "VtsHalWifiHostapdV1_0TargetTestUtil",
         "android.hardware.wifi.hostapd@1.0",
         "android.hardware.wifi.hostapd@1.1",
         "android.hardware.wifi.hostapd@1.2",
         "android.hardware.wifi.hostapd@1.3",
         "android.hardware.wifi@1.0",
+        "android.hardware.wifi@1.1",
+        "android.hardware.wifi@1.2",
+        "android.hardware.wifi@1.3",
+        "android.hardware.wifi@1.4",
         "libgmock",
         "libwifi-system",
         "libwifi-system-iface",
diff --git a/wifi/hostapd/1.2/vts/functional/hostapd_hidl_test.cpp b/wifi/hostapd/1.2/vts/functional/hostapd_hidl_test.cpp
index c40c582..5c59819 100644
--- a/wifi/hostapd/1.2/vts/functional/hostapd_hidl_test.cpp
+++ b/wifi/hostapd/1.2/vts/functional/hostapd_hidl_test.cpp
@@ -29,6 +29,7 @@
 
 #include "hostapd_hidl_call_util.h"
 #include "hostapd_hidl_test_utils.h"
+#include "wifi_hidl_test_utils_1_4.h"
 
 using ::android::sp;
 using ::android::hardware::hidl_string;
@@ -39,6 +40,9 @@
 using ::android::hardware::wifi::hostapd::V1_2::Ieee80211ReasonCode;
 using ::android::hardware::wifi::hostapd::V1_2::IHostapd;
 using ::android::hardware::wifi::V1_0::IWifi;
+using ::android::hardware::wifi::V1_0::WifiStatusCode;
+using ::android::hardware::wifi::V1_4::IWifiApIface;
+using ::android::hardware::wifi::V1_4::IWifiChip;
 
 namespace {
 constexpr unsigned char kNwSsid[] = {'t', 'e', 's', 't', '1',
@@ -81,23 +85,25 @@
    protected:
     bool isWpa3SaeSupport_ = false;
     bool isAcsSupport_ = false;
-    std::string getPrimaryWlanIfaceName() {
-        std::array<char, PROPERTY_VALUE_MAX> buffer;
-        auto res = property_get("ro.vendor.wifi.sap.interface", buffer.data(),
-                                nullptr);
-        if (res > 0) return buffer.data();
-        property_get("wifi.interface", buffer.data(), "wlan0");
-        return buffer.data();
+
+    std::string setupApIfaceIfNeededAndGetName() {
+        sp<IWifiApIface> wifi_ap_iface;
+        wifi_ap_iface = getWifiApIface_1_4(wifi_instance_name_);
+        EXPECT_NE(nullptr, wifi_ap_iface.get());
+
+        const auto& status_and_name = HIDL_INVOKE(wifi_ap_iface, getName);
+        EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_name.first.code);
+        return status_and_name.second;
     }
 
-    IHostapd::IfaceParams getIfaceParamsWithoutAcs() {
+    IHostapd::IfaceParams getIfaceParamsWithoutAcs(std::string iface_name) {
         ::android::hardware::wifi::hostapd::V1_0::IHostapd::IfaceParams
             iface_params;
         ::android::hardware::wifi::hostapd::V1_1::IHostapd::IfaceParams
             iface_params_1_1;
         IHostapd::IfaceParams iface_params_1_2;
 
-        iface_params.ifaceName = getPrimaryWlanIfaceName();
+        iface_params.ifaceName = iface_name;
         iface_params.hwModeParams.enable80211N = true;
         iface_params.hwModeParams.enable80211AC = false;
         iface_params.channelParams.enableAcs = false;
@@ -114,9 +120,10 @@
         return iface_params_1_2;
     }
 
-    IHostapd::IfaceParams getIfaceParamsWithAcs() {
+    IHostapd::IfaceParams getIfaceParamsWithAcs(std::string iface_name) {
         // First get the settings for WithoutAcs and then make changes
-        IHostapd::IfaceParams iface_params_1_2 = getIfaceParamsWithoutAcs();
+        IHostapd::IfaceParams iface_params_1_2 =
+            getIfaceParamsWithoutAcs(iface_name);
         iface_params_1_2.V1_1.V1_0.channelParams.enableAcs = true;
         iface_params_1_2.V1_1.V1_0.channelParams.acsShouldExcludeDfs = true;
         iface_params_1_2.V1_1.V1_0.channelParams.channel = 0;
@@ -126,8 +133,10 @@
         return iface_params_1_2;
     }
 
-    IHostapd::IfaceParams getIfaceParamsWithAcsAndFreqRange() {
-        IHostapd::IfaceParams iface_params_1_2 = getIfaceParamsWithAcs();
+    IHostapd::IfaceParams getIfaceParamsWithAcsAndFreqRange(
+        std::string iface_name) {
+        IHostapd::IfaceParams iface_params_1_2 =
+            getIfaceParamsWithAcs(iface_name);
         ::android::hardware::wifi::hostapd::V1_2::IHostapd::AcsFrequencyRange
             acsFrequencyRange;
         acsFrequencyRange.start = 2412;
@@ -141,9 +150,10 @@
         return iface_params_1_2;
     }
 
-    IHostapd::IfaceParams getIfaceParamsWithAcsAndInvalidFreqRange() {
+    IHostapd::IfaceParams getIfaceParamsWithAcsAndInvalidFreqRange(
+        std::string iface_name) {
         IHostapd::IfaceParams iface_params_1_2 =
-            getIfaceParamsWithAcsAndFreqRange();
+            getIfaceParamsWithAcsAndFreqRange(iface_name);
         iface_params_1_2.channelParams.acsChannelFreqRangesMhz[0].start = 222;
         iface_params_1_2.channelParams.acsChannelFreqRangesMhz[0].end = 999;
         return iface_params_1_2;
@@ -205,8 +215,10 @@
         return nw_params_1_2;
     }
 
-    IHostapd::IfaceParams getIfaceParamsWithInvalidChannel() {
-        IHostapd::IfaceParams iface_params_1_2 = getIfaceParamsWithoutAcs();
+    IHostapd::IfaceParams getIfaceParamsWithInvalidChannel(
+        std::string iface_name) {
+        IHostapd::IfaceParams iface_params_1_2 =
+            getIfaceParamsWithoutAcs(iface_name);
         iface_params_1_2.V1_1.V1_0.channelParams.channel = kIfaceInvalidChannel;
         return iface_params_1_2;
     }
@@ -231,8 +243,9 @@
     if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support";
     if (is_1_3(hostapd_))
         GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
+    std::string ifname = setupApIfaceIfNeededAndGetName();
     auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
-                              getIfaceParamsWithAcs(), getPskNwParams());
+                              getIfaceParamsWithAcs(ifname), getPskNwParams());
     EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
 }
 
@@ -244,9 +257,10 @@
     if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support";
     if (is_1_3(hostapd_))
         GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
-    auto status =
-        HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
-                    getIfaceParamsWithAcsAndFreqRange(), getPskNwParams());
+    std::string ifname = setupApIfaceIfNeededAndGetName();
+    auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
+                              getIfaceParamsWithAcsAndFreqRange(ifname),
+                              getPskNwParams());
     EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
 }
 
@@ -258,8 +272,9 @@
     if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support";
     if (is_1_3(hostapd_))
         GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
+    std::string ifname = setupApIfaceIfNeededAndGetName();
     auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
-                              getIfaceParamsWithAcsAndInvalidFreqRange(),
+                              getIfaceParamsWithAcsAndInvalidFreqRange(ifname),
                               getPskNwParams());
     EXPECT_NE(HostapdStatusCode::SUCCESS, status.code);
 }
@@ -272,8 +287,9 @@
     if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support";
     if (is_1_3(hostapd_))
         GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
+    std::string ifname = setupApIfaceIfNeededAndGetName();
     auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
-                              getIfaceParamsWithAcs(), getOpenNwParams());
+                              getIfaceParamsWithAcs(ifname), getOpenNwParams());
     EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
 }
 
@@ -284,8 +300,10 @@
 TEST_P(HostapdHidlTest, AddPskAccessPointWithoutAcs) {
     if (is_1_3(hostapd_))
         GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
-    auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
-                              getIfaceParamsWithoutAcs(), getPskNwParams());
+    std::string ifname = setupApIfaceIfNeededAndGetName();
+    auto status =
+        HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
+                    getIfaceParamsWithoutAcs(ifname), getPskNwParams());
     EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
 }
 
@@ -296,8 +314,10 @@
 TEST_P(HostapdHidlTest, AddOpenAccessPointWithoutAcs) {
     if (is_1_3(hostapd_))
         GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
-    auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
-                              getIfaceParamsWithoutAcs(), getOpenNwParams());
+    std::string ifname = setupApIfaceIfNeededAndGetName();
+    auto status =
+        HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
+                    getIfaceParamsWithoutAcs(ifname), getOpenNwParams());
     EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
 }
 
@@ -309,9 +329,10 @@
     if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support";
     if (is_1_3(hostapd_))
         GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
-    auto status =
-        HIDL_INVOKE(hostapd_, addAccessPoint_1_2, getIfaceParamsWithoutAcs(),
-                    getSaeTransitionNwParams());
+    std::string ifname = setupApIfaceIfNeededAndGetName();
+    auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
+                              getIfaceParamsWithoutAcs(ifname),
+                              getSaeTransitionNwParams());
     EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
 }
 
@@ -323,8 +344,10 @@
     if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support";
     if (is_1_3(hostapd_))
         GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
-    auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
-                              getIfaceParamsWithoutAcs(), getSaeNwParams());
+    std::string ifname = setupApIfaceIfNeededAndGetName();
+    auto status =
+        HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
+                    getIfaceParamsWithoutAcs(ifname), getSaeNwParams());
     EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
 }
 
@@ -336,11 +359,12 @@
     if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support";
     if (is_1_3(hostapd_))
         GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
-    auto status_1_2 = HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
-                                  getIfaceParamsWithAcs(), getPskNwParams());
+    std::string ifname = setupApIfaceIfNeededAndGetName();
+    auto status_1_2 =
+        HIDL_INVOKE(hostapd_, addAccessPoint_1_2, getIfaceParamsWithAcs(ifname),
+                    getPskNwParams());
     EXPECT_EQ(HostapdStatusCode::SUCCESS, status_1_2.code);
-    auto status =
-        HIDL_INVOKE(hostapd_, removeAccessPoint, getPrimaryWlanIfaceName());
+    auto status = HIDL_INVOKE(hostapd_, removeAccessPoint, ifname);
     EXPECT_EQ(
         android::hardware::wifi::hostapd::V1_0::HostapdStatusCode::SUCCESS,
         status.code);
@@ -353,11 +377,12 @@
 TEST_P(HostapdHidlTest, RemoveAccessPointWithoutAcs) {
     if (is_1_3(hostapd_))
         GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
-    auto status_1_2 = HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
-                                  getIfaceParamsWithoutAcs(), getPskNwParams());
+    std::string ifname = setupApIfaceIfNeededAndGetName();
+    auto status_1_2 =
+        HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
+                    getIfaceParamsWithoutAcs(ifname), getPskNwParams());
     EXPECT_EQ(HostapdStatusCode::SUCCESS, status_1_2.code);
-    auto status =
-        HIDL_INVOKE(hostapd_, removeAccessPoint, getPrimaryWlanIfaceName());
+    auto status = HIDL_INVOKE(hostapd_, removeAccessPoint, ifname);
     EXPECT_EQ(
         android::hardware::wifi::hostapd::V1_0::HostapdStatusCode::SUCCESS,
         status.code);
@@ -370,9 +395,10 @@
 TEST_P(HostapdHidlTest, AddPskAccessPointWithInvalidChannel) {
     if (is_1_3(hostapd_))
         GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
+    std::string ifname = setupApIfaceIfNeededAndGetName();
     auto status =
         HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
-                    getIfaceParamsWithInvalidChannel(), getPskNwParams());
+                    getIfaceParamsWithInvalidChannel(ifname), getPskNwParams());
     EXPECT_NE(HostapdStatusCode::SUCCESS, status.code);
 }
 
@@ -383,9 +409,10 @@
 TEST_P(HostapdHidlTest, AddInvalidPskAccessPointWithoutAcs) {
     if (is_1_3(hostapd_))
         GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
+    std::string ifname = setupApIfaceIfNeededAndGetName();
     auto status =
-        HIDL_INVOKE(hostapd_, addAccessPoint_1_2, getIfaceParamsWithoutAcs(),
-                    getInvalidPskNwParams());
+        HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
+                    getIfaceParamsWithoutAcs(ifname), getInvalidPskNwParams());
     EXPECT_NE(HostapdStatusCode::SUCCESS, status.code);
 }
 
@@ -397,9 +424,10 @@
     if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support";
     if (is_1_3(hostapd_))
         GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
-    auto status =
-        HIDL_INVOKE(hostapd_, addAccessPoint_1_2, getIfaceParamsWithoutAcs(),
-                    getInvalidSaeTransitionNwParams());
+    std::string ifname = setupApIfaceIfNeededAndGetName();
+    auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
+                              getIfaceParamsWithoutAcs(ifname),
+                              getInvalidSaeTransitionNwParams());
     EXPECT_NE(HostapdStatusCode::SUCCESS, status.code);
 }
 
@@ -411,9 +439,10 @@
     if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support";
     if (is_1_3(hostapd_))
         GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
+    std::string ifname = setupApIfaceIfNeededAndGetName();
     auto status =
-        HIDL_INVOKE(hostapd_, addAccessPoint_1_2, getIfaceParamsWithoutAcs(),
-                    getInvalidSaeNwParams());
+        HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
+                    getIfaceParamsWithoutAcs(ifname), getInvalidSaeNwParams());
     EXPECT_NE(HostapdStatusCode::SUCCESS, status.code);
 }
 
@@ -422,9 +451,9 @@
  * when hotspot interface doesn't init..
  */
 TEST_P(HostapdHidlTest, DisconnectClientWhenIfaceNotAvailable) {
-    auto status =
-        HIDL_INVOKE(hostapd_, forceClientDisconnect, getPrimaryWlanIfaceName(),
-                    kTestZeroMacAddr, kTestDisconnectReasonCode);
+    std::string ifname = setupApIfaceIfNeededAndGetName();
+    auto status = HIDL_INVOKE(hostapd_, forceClientDisconnect, ifname,
+                              kTestZeroMacAddr, kTestDisconnectReasonCode);
     EXPECT_EQ(HostapdStatusCode::FAILURE_IFACE_UNKNOWN, status.code);
 }
 
@@ -435,14 +464,14 @@
 TEST_P(HostapdHidlTest, DisconnectClientWhenIfacAvailable) {
     if (is_1_3(hostapd_))
         GTEST_SKIP() << "Ignore addAccessPoint_1_2 on hostapd 1_3";
+    std::string ifname = setupApIfaceIfNeededAndGetName();
     auto status_1_2 =
-        HIDL_INVOKE(hostapd_, addAccessPoint_1_2, getIfaceParamsWithoutAcs(),
-                    getOpenNwParams());
+        HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
+                    getIfaceParamsWithoutAcs(ifname), getOpenNwParams());
     EXPECT_EQ(HostapdStatusCode::SUCCESS, status_1_2.code);
 
-    status_1_2 =
-        HIDL_INVOKE(hostapd_, forceClientDisconnect, getPrimaryWlanIfaceName(),
-                    kTestZeroMacAddr, kTestDisconnectReasonCode);
+    status_1_2 = HIDL_INVOKE(hostapd_, forceClientDisconnect, ifname,
+                             kTestZeroMacAddr, kTestDisconnectReasonCode);
     EXPECT_EQ(HostapdStatusCode::FAILURE_CLIENT_UNKNOWN, status_1_2.code);
 }
 
diff --git a/wifi/hostapd/aidl/Android.bp b/wifi/hostapd/aidl/Android.bp
index fcd06ff..250a555 100644
--- a/wifi/hostapd/aidl/Android.bp
+++ b/wifi/hostapd/aidl/Android.bp
@@ -38,9 +38,7 @@
             min_sdk_version: "30",
         },
         ndk: {
-            vndk: {
-                enabled: true,
-            },
+            gen_trace: true,
         },
     },
 }
diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test.cpp b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test.cpp
index eabbf1b..da3ff3a 100644
--- a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test.cpp
+++ b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test.cpp
@@ -38,11 +38,12 @@
     : public ::testing::TestWithParam<std::tuple<std::string, std::string>> {
    public:
     virtual void SetUp() override {
-        // Stop Wi-Fi
-        ASSERT_TRUE(stopWifiFramework());  // stop & wait for wifi to shutdown.
-
         wifi_instance_name_ = std::get<0>(GetParam());
         supplicant_instance_name_ = std::get<1>(GetParam());
+
+        // Stop & wait for wifi to shutdown.
+        ASSERT_TRUE(stopWifiFramework(wifi_instance_name_));
+
         std::system("/system/bin/start");
         ASSERT_TRUE(waitForFrameworkReady());
         isP2pOn_ =
diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp
index 086166a..6760663 100644
--- a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp
+++ b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.cpp
@@ -28,26 +28,42 @@
 
 using ::android::sp;
 using ::android::hardware::configureRpcThreadpool;
-using ::android::hardware::joinRpcThreadpool;
 using ::android::hardware::hidl_string;
 using ::android::hardware::hidl_vec;
+using ::android::hardware::joinRpcThreadpool;
 using ::android::hardware::Return;
 using ::android::hardware::Void;
-using ::android::hardware::wifi::V1_0::ChipModeId;
-using ::android::hardware::wifi::V1_0::IWifiChip;
+using ::android::hardware::wifi::supplicant::V1_0::IfaceType;
 using ::android::hardware::wifi::supplicant::V1_0::ISupplicant;
 using ::android::hardware::wifi::supplicant::V1_0::ISupplicantIface;
 using ::android::hardware::wifi::supplicant::V1_0::ISupplicantNetwork;
+using ::android::hardware::wifi::supplicant::V1_0::ISupplicantP2pIface;
 using ::android::hardware::wifi::supplicant::V1_0::ISupplicantStaIface;
 using ::android::hardware::wifi::supplicant::V1_0::ISupplicantStaNetwork;
-using ::android::hardware::wifi::supplicant::V1_0::ISupplicantP2pIface;
-using ::android::hardware::wifi::supplicant::V1_0::IfaceType;
 using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatus;
 using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatusCode;
+using ::android::hardware::wifi::V1_0::ChipModeId;
+using ::android::hardware::wifi::V1_0::IWifi;
+using ::android::hardware::wifi::V1_0::IWifiChip;
 using ::android::wifi_system::InterfaceTool;
 using ::android::wifi_system::SupplicantManager;
 
 namespace {
+
+bool waitForWifiHalStop(const std::string& wifi_instance_name) {
+    sp<IWifi> wifi = getWifi(wifi_instance_name);
+    int count = 50; /* wait at most 5 seconds for completion */
+    while (count-- > 0) {
+        if (wifi != nullptr && !wifi->isStarted()) {
+            return true;
+        }
+        usleep(100000);
+        wifi = getWifi(wifi_instance_name);
+    }
+    LOG(ERROR) << "Wifi HAL was not stopped";
+    return false;
+}
+
 bool waitForSupplicantState(bool is_running) {
     SupplicantManager supplicant_manager;
     int count = 50; /* wait at most 5 seconds for completion */
@@ -113,10 +129,10 @@
     return waitForSupplicantStart();  // wait for wifi to start.
 }
 
-bool stopWifiFramework() {
+bool stopWifiFramework(const std::string& wifi_instance_name) {
     std::system("svc wifi disable");
     std::system("cmd wifi set-scan-always-available disabled");
-    return waitForSupplicantStop();  // wait for wifi to shutdown.
+    return waitForSupplicantStop() && waitForWifiHalStop(wifi_instance_name);
 }
 
 void stopSupplicant() { stopSupplicant(""); }
diff --git a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.h b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.h
index 7228623..2198d7c 100644
--- a/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.h
+++ b/wifi/supplicant/1.0/vts/functional/supplicant_hidl_test_utils.h
@@ -33,7 +33,7 @@
 bool startWifiFramework();
 
 // Used to stop the android wifi framework before every test.
-bool stopWifiFramework();
+bool stopWifiFramework(const std::string& wifi_instance_name);
 
 void stopSupplicant(const std::string& wifi_instance_name);
 // Used to configure the chip, driver and start wpa_supplicant before every
@@ -77,12 +77,13 @@
     : public ::testing::TestWithParam<std::tuple<std::string, std::string>> {
    public:
     virtual void SetUp() override {
-        // Stop Wi-Fi
-        ASSERT_TRUE(stopWifiFramework());  // stop & wait for wifi to shutdown.
-
-        // should always be v1.0 wifi
-        wifi_v1_0_instance_name_ = std::get<0>(GetParam());
+        wifi_v1_0_instance_name_ =
+            std::get<0>(GetParam());  // should always be v1.0 wifi
         supplicant_instance_name_ = std::get<1>(GetParam());
+
+        // Stop & wait for wifi to shutdown.
+        ASSERT_TRUE(stopWifiFramework(wifi_v1_0_instance_name_));
+
         std::system("/system/bin/start");
         ASSERT_TRUE(waitForFrameworkReady());
         isP2pOn_ =
diff --git a/wifi/supplicant/aidl/Android.bp b/wifi/supplicant/aidl/Android.bp
index d00dd21..4b2c8dd 100644
--- a/wifi/supplicant/aidl/Android.bp
+++ b/wifi/supplicant/aidl/Android.bp
@@ -38,9 +38,7 @@
             min_sdk_version: "30",
         },
         ndk: {
-            vndk: {
-                enabled: true,
-            },
+            gen_trace: true,
         },
     },
 }
diff --git a/wifi/supplicant/aidl/vts/functional/supplicant_test_utils.h b/wifi/supplicant/aidl/vts/functional/supplicant_test_utils.h
index 17e0394..31042a2 100644
--- a/wifi/supplicant/aidl/vts/functional/supplicant_test_utils.h
+++ b/wifi/supplicant/aidl/vts/functional/supplicant_test_utils.h
@@ -78,7 +78,7 @@
 void stopSupplicantService() { stopSupplicant(getWifiInstanceName()); }
 
 void initializeService() {
-    ASSERT_TRUE(stopWifiFramework());
+    ASSERT_TRUE(stopWifiFramework(getWifiInstanceName()));
     std::system("/system/bin/start");
     ASSERT_TRUE(waitForFrameworkReady());
     stopSupplicantService();