Merge "Add TrafficDescriptor to DataProfileInfo"
diff --git a/authsecret/aidl/default/service.cpp b/authsecret/aidl/default/service.cpp
index efecf10..a7d8678 100644
--- a/authsecret/aidl/default/service.cpp
+++ b/authsecret/aidl/default/service.cpp
@@ -28,7 +28,7 @@
 
     const std::string instance = std::string() + AuthSecret::descriptor + "/default";
     binder_status_t status = AServiceManager_addService(authsecret->asBinder().get(), instance.c_str());
-    CHECK(status == STATUS_OK);
+    CHECK_EQ(status, STATUS_OK);
 
     ABinderProcess_joinThreadPool();
     return -1; // Should never be reached
diff --git a/automotive/audiocontrol/aidl/default/main.cpp b/automotive/audiocontrol/aidl/default/main.cpp
index 9b259fc..cc15ccb 100644
--- a/automotive/audiocontrol/aidl/default/main.cpp
+++ b/automotive/audiocontrol/aidl/default/main.cpp
@@ -31,7 +31,7 @@
     const std::string instance = std::string() + AudioControl::descriptor + "/default";
     binder_status_t status =
             AServiceManager_addService(audioControl->asBinder().get(), instance.c_str());
-    CHECK(status == STATUS_OK);
+    CHECK_EQ(status, STATUS_OK);
 
     std::shared_ptr<PowerPolicyClient> powerPolicyClient =
             ::ndk::SharedRefBase::make<PowerPolicyClient>(audioControl);
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h b/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h
index 46a526c..cab184b 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h
@@ -39,14 +39,6 @@
 
 class FakeVehicleHardware final : public IVehicleHardware {
   public:
-    using SetValuesCallback = std::function<void(
-            const std::vector<::aidl::android::hardware::automotive::vehicle::SetValueResult>&)>;
-    using GetValuesCallback = std::function<void(
-            const std::vector<::aidl::android::hardware::automotive::vehicle::GetValueResult>&)>;
-    using OnPropertyChangeCallback = std::function<void(
-            const std::vector<::aidl::android::hardware::automotive::vehicle::VehiclePropValue>&)>;
-    using OnPropertySetErrorCallback = std::function<void(const std::vector<SetValueErrorEvent>&)>;
-
     FakeVehicleHardware();
 
     explicit FakeVehicleHardware(std::unique_ptr<VehiclePropValuePool> valuePool);
@@ -59,7 +51,7 @@
     // are sent to vehicle bus or before property set confirmation is received. The callback is
     // safe to be called after the function returns and is safe to be called in a different thread.
     ::aidl::android::hardware::automotive::vehicle::StatusCode setValues(
-            SetValuesCallback&& callback,
+            std::shared_ptr<const SetValuesCallback> callback,
             const std::vector<::aidl::android::hardware::automotive::vehicle::SetValueRequest>&
                     requests) override;
 
@@ -67,7 +59,7 @@
     // The callback is safe to be called after the function returns and is safe to be called in a
     // different thread.
     ::aidl::android::hardware::automotive::vehicle::StatusCode getValues(
-            GetValuesCallback&& callback,
+            std::shared_ptr<const GetValuesCallback> callback,
             const std::vector<::aidl::android::hardware::automotive::vehicle::GetValueRequest>&
                     requests) const override;
 
@@ -78,11 +70,13 @@
     ::aidl::android::hardware::automotive::vehicle::StatusCode checkHealth() override;
 
     // Register a callback that would be called when there is a property change event from vehicle.
-    void registerOnPropertyChangeEvent(OnPropertyChangeCallback&& callback) override;
+    void registerOnPropertyChangeEvent(
+            std::unique_ptr<const PropertyChangeCallback> callback) override;
 
     // Register a callback that would be called when there is a property set error event from
     // vehicle.
-    void registerOnPropertySetErrorEvent(OnPropertySetErrorCallback&& callback) override;
+    void registerOnPropertySetErrorEvent(
+            std::unique_ptr<const PropertySetErrorCallback> callback) override;
 
   private:
     // Expose private methods to unit test.
@@ -94,8 +88,10 @@
     const std::unique_ptr<obd2frame::FakeObd2Frame> mFakeObd2Frame;
     const std::unique_ptr<FakeUserHal> mFakeUserHal;
     std::mutex mCallbackLock;
-    OnPropertyChangeCallback mOnPropertyChangeCallback GUARDED_BY(mCallbackLock);
-    OnPropertySetErrorCallback mOnPropertySetErrorCallback GUARDED_BY(mCallbackLock);
+    std::unique_ptr<const PropertyChangeCallback> mOnPropertyChangeCallback
+            GUARDED_BY(mCallbackLock);
+    std::unique_ptr<const PropertySetErrorCallback> mOnPropertySetErrorCallback
+            GUARDED_BY(mCallbackLock);
 
     void init();
     // Stores the initial value to property store.
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp b/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
index 5b2003e..e75f0e7 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
@@ -379,7 +379,7 @@
     return {};
 }
 
-StatusCode FakeVehicleHardware::setValues(FakeVehicleHardware::SetValuesCallback&& callback,
+StatusCode FakeVehicleHardware::setValues(std::shared_ptr<const SetValuesCallback> callback,
                                           const std::vector<SetValueRequest>& requests) {
     std::vector<VehiclePropValue> updatedValues;
     std::vector<SetValueResult> results;
@@ -424,12 +424,12 @@
 
     // In the real vhal, the values will be sent to Car ECU. We just pretend it is done here and
     // send back the updated property values to client.
-    callback(std::move(results));
+    (*callback)(std::move(results));
 
     return StatusCode::OK;
 }
 
-StatusCode FakeVehicleHardware::getValues(FakeVehicleHardware::GetValuesCallback&& callback,
+StatusCode FakeVehicleHardware::getValues(std::shared_ptr<const GetValuesCallback> callback,
                                           const std::vector<GetValueRequest>& requests) const {
     std::vector<GetValueResult> results;
     for (auto& request : requests) {
@@ -471,7 +471,7 @@
         results.push_back(std::move(getValueResult));
     }
 
-    callback(std::move(results));
+    (*callback)(std::move(results));
 
     return StatusCode::OK;
 }
@@ -487,23 +487,28 @@
     return StatusCode::OK;
 }
 
-void FakeVehicleHardware::registerOnPropertyChangeEvent(OnPropertyChangeCallback&& callback) {
+void FakeVehicleHardware::registerOnPropertyChangeEvent(
+        std::unique_ptr<const PropertyChangeCallback> callback) {
     std::scoped_lock<std::mutex> lockGuard(mCallbackLock);
     mOnPropertyChangeCallback = std::move(callback);
 }
 
-void FakeVehicleHardware::registerOnPropertySetErrorEvent(OnPropertySetErrorCallback&& callback) {
+void FakeVehicleHardware::registerOnPropertySetErrorEvent(
+        std::unique_ptr<const PropertySetErrorCallback> callback) {
     std::scoped_lock<std::mutex> lockGuard(mCallbackLock);
     mOnPropertySetErrorCallback = std::move(callback);
 }
 
 void FakeVehicleHardware::onValueChangeCallback(const VehiclePropValue& value) {
     std::scoped_lock<std::mutex> lockGuard(mCallbackLock);
-    if (mOnPropertyChangeCallback != nullptr) {
-        std::vector<VehiclePropValue> updatedValues;
-        updatedValues.push_back(value);
-        mOnPropertyChangeCallback(std::move(updatedValues));
+
+    if (mOnPropertyChangeCallback == nullptr) {
+        return;
     }
+
+    std::vector<VehiclePropValue> updatedValues;
+    updatedValues.push_back(value);
+    (*mOnPropertyChangeCallback)(std::move(updatedValues));
 }
 
 void FakeVehicleHardware::maybeOverrideProperties(const char* overrideDir) {
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
index 88834f3..f8df6e6 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
@@ -76,24 +76,25 @@
 class FakeVehicleHardwareTest : public ::testing::Test {
   protected:
     void SetUp() override {
-        getHardware()->registerOnPropertyChangeEvent(
+        auto callback = std::make_unique<IVehicleHardware::PropertyChangeCallback>(
                 [this](const std::vector<VehiclePropValue>& values) {
-                    return onPropertyChangeEvent(values);
+                    onPropertyChangeEvent(values);
                 });
+        getHardware()->registerOnPropertyChangeEvent(std::move(callback));
+        mSetValuesCallback = std::make_shared<IVehicleHardware::SetValuesCallback>(
+                [this](std::vector<SetValueResult> results) { onSetValues(results); });
+        mGetValuesCallback = std::make_shared<IVehicleHardware::GetValuesCallback>(
+                [this](std::vector<GetValueResult> results) { onGetValues(results); });
     }
 
     FakeVehicleHardware* getHardware() { return &mHardware; }
 
     StatusCode setValues(const std::vector<SetValueRequest>& requests) {
-        return getHardware()->setValues(
-                [this](const std::vector<SetValueResult> results) { return onSetValues(results); },
-                requests);
+        return getHardware()->setValues(mSetValuesCallback, requests);
     }
 
     StatusCode getValues(const std::vector<GetValueRequest>& requests) {
-        return getHardware()->getValues(
-                [this](const std::vector<GetValueResult> results) { return onGetValues(results); },
-                requests);
+        return getHardware()->getValues(mGetValuesCallback, requests);
     }
 
     StatusCode setValue(const VehiclePropValue& value) {
@@ -245,6 +246,8 @@
     std::vector<SetValueResult> mSetValueResults;
     std::vector<GetValueResult> mGetValueResults;
     std::vector<VehiclePropValue> mChangedProperties;
+    std::shared_ptr<IVehicleHardware::SetValuesCallback> mSetValuesCallback;
+    std::shared_ptr<IVehicleHardware::GetValuesCallback> mGetValuesCallback;
 };
 
 TEST_F(FakeVehicleHardwareTest, testGetAllPropertyConfigs) {
@@ -367,9 +370,9 @@
 
 TEST_F(FakeVehicleHardwareTest, testRegisterOnPropertyChangeEvent) {
     // We have already registered this callback in Setup, here we are registering again.
-    getHardware()->registerOnPropertyChangeEvent(std::bind(
-            &FakeVehicleHardwareTest_testRegisterOnPropertyChangeEvent_Test::onPropertyChangeEvent,
-            this, std::placeholders::_1));
+    auto callback = std::make_unique<IVehicleHardware::PropertyChangeCallback>(
+            [this](const std::vector<VehiclePropValue>& values) { onPropertyChangeEvent(values); });
+    getHardware()->registerOnPropertyChangeEvent(std::move(callback));
 
     auto testValues = getTestPropValues();
     std::vector<SetValueRequest> requests;
diff --git a/automotive/vehicle/aidl/impl/hardware/include/IVehicleHardware.h b/automotive/vehicle/aidl/impl/hardware/include/IVehicleHardware.h
index 2e12327..4b9de2d 100644
--- a/automotive/vehicle/aidl/impl/hardware/include/IVehicleHardware.h
+++ b/automotive/vehicle/aidl/impl/hardware/include/IVehicleHardware.h
@@ -19,6 +19,7 @@
 
 #include <VehicleHalTypes.h>
 
+#include <memory>
 #include <vector>
 
 namespace android {
@@ -49,6 +50,14 @@
 // with a VehicleHardware through this interface.
 class IVehicleHardware {
   public:
+    using SetValuesCallback = std::function<void(
+            std::vector<::aidl::android::hardware::automotive::vehicle::SetValueResult>)>;
+    using GetValuesCallback = std::function<void(
+            std::vector<::aidl::android::hardware::automotive::vehicle::GetValueResult>)>;
+    using PropertyChangeCallback = std::function<void(
+            std::vector<::aidl::android::hardware::automotive::vehicle::VehiclePropValue>)>;
+    using PropertySetErrorCallback = std::function<void(std::vector<SetValueErrorEvent>)>;
+
     virtual ~IVehicleHardware() = default;
 
     // Get all the property configs.
@@ -59,9 +68,7 @@
     // are sent to vehicle bus or before property set confirmation is received. The callback is
     // safe to be called after the function returns and is safe to be called in a different thread.
     virtual ::aidl::android::hardware::automotive::vehicle::StatusCode setValues(
-            std::function<void(const std::vector<
-                               ::aidl::android::hardware::automotive::vehicle::SetValueResult>&)>&&
-                    callback,
+            std::shared_ptr<const SetValuesCallback> callback,
             const std::vector<::aidl::android::hardware::automotive::vehicle::SetValueRequest>&
                     requests) = 0;
 
@@ -69,9 +76,7 @@
     // The callback is safe to be called after the function returns and is safe to be called in a
     // different thread.
     virtual ::aidl::android::hardware::automotive::vehicle::StatusCode getValues(
-            std::function<void(const std::vector<
-                               ::aidl::android::hardware::automotive::vehicle::GetValueResult>&)>&&
-                    callback,
+            std::shared_ptr<const GetValuesCallback> callback,
             const std::vector<::aidl::android::hardware::automotive::vehicle::GetValueRequest>&
                     requests) const = 0;
 
@@ -83,13 +88,12 @@
 
     // Register a callback that would be called when there is a property change event from vehicle.
     virtual void registerOnPropertyChangeEvent(
-            std::function<void(const std::vector<::aidl::android::hardware::automotive::vehicle::
-                                                         VehiclePropValue>&)>&& callback) = 0;
+            std::unique_ptr<const PropertyChangeCallback> callback) = 0;
 
     // Register a callback that would be called when there is a property set error event from
     // vehicle.
     virtual void registerOnPropertySetErrorEvent(
-            std::function<void(const std::vector<SetValueErrorEvent>&)>&& callback) = 0;
+            std::unique_ptr<const PropertySetErrorCallback> callback) = 0;
 };
 
 }  // namespace vehicle
diff --git a/automotive/vehicle/aidl/impl/vhal/Android.bp b/automotive/vehicle/aidl/impl/vhal/Android.bp
index 79d3ebd..454fea5 100644
--- a/automotive/vehicle/aidl/impl/vhal/Android.bp
+++ b/automotive/vehicle/aidl/impl/vhal/Android.bp
@@ -19,7 +19,7 @@
 }
 
 cc_binary {
-    name: "android.hardware.automotive.vehicle-aidl-default-service",
+    name: "android.hardware.automotive.vehicle@V1-default-service",
     vendor: true,
     defaults: [
         "FakeVehicleHardwareDefaults",
diff --git a/automotive/vehicle/aidl/impl/vhal/src/VehicleService.cpp b/automotive/vehicle/aidl/impl/vhal/src/VehicleService.cpp
index 14224a5..c8b5c65 100644
--- a/automotive/vehicle/aidl/impl/vhal/src/VehicleService.cpp
+++ b/automotive/vehicle/aidl/impl/vhal/src/VehicleService.cpp
@@ -32,8 +32,8 @@
             ::ndk::SharedRefBase::make<DefaultVehicleHal>(std::move(hardware));
 
     ALOGI("Registering as service...");
-    binder_exception_t err = AServiceManager_addService(vhal->asBinder().get(),
-                                                        "android.hardware.automotive.vehicle");
+    binder_exception_t err = AServiceManager_addService(
+            vhal->asBinder().get(), "android.hardware.automotive.vehicle.IVehicle/default");
     if (err != EX_NONE) {
         ALOGE("failed to register android.hardware.automotive.vehicle service, exception: %d", err);
         return 1;
diff --git a/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp b/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp
index 62a7098..2b5ca70 100644
--- a/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp
+++ b/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp
@@ -19,6 +19,7 @@
 #include <IVehicleHardware.h>
 #include <LargeParcelableBase.h>
 #include <aidl/android/hardware/automotive/vehicle/IVehicle.h>
+#include <android-base/thread_annotations.h>
 
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
@@ -53,16 +54,17 @@
 class MockVehicleHardware final : public IVehicleHardware {
   public:
     std::vector<VehiclePropConfig> getAllPropertyConfigs() const override {
+        std::scoped_lock<std::mutex> lockGuard(mLock);
         return mPropertyConfigs;
     }
 
-    StatusCode setValues(std::function<void(const std::vector<SetValueResult>&)>&&,
+    StatusCode setValues(std::shared_ptr<const SetValuesCallback>,
                          const std::vector<SetValueRequest>&) override {
         // TODO(b/200737967): mock this.
         return StatusCode::OK;
     }
 
-    StatusCode getValues(std::function<void(const std::vector<GetValueResult>&)>&&,
+    StatusCode getValues(std::shared_ptr<const GetValuesCallback>,
                          const std::vector<GetValueRequest>&) const override {
         // TODO(b/200737967): mock this.
         return StatusCode::OK;
@@ -78,23 +80,23 @@
         return StatusCode::OK;
     }
 
-    void registerOnPropertyChangeEvent(
-            std::function<void(const std::vector<VehiclePropValue>&)>&&) override {
+    void registerOnPropertyChangeEvent(std::unique_ptr<const PropertyChangeCallback>) override {
         // TODO(b/200737967): mock this.
     }
 
-    void registerOnPropertySetErrorEvent(
-            std::function<void(const std::vector<SetValueErrorEvent>&)>&&) override {
+    void registerOnPropertySetErrorEvent(std::unique_ptr<const PropertySetErrorCallback>) override {
         // TODO(b/200737967): mock this.
     }
 
     // Test functions.
     void setPropertyConfigs(const std::vector<VehiclePropConfig>& configs) {
+        std::scoped_lock<std::mutex> lockGuard(mLock);
         mPropertyConfigs = configs;
     }
 
   private:
-    std::vector<VehiclePropConfig> mPropertyConfigs;
+    mutable std::mutex mLock;
+    std::vector<VehiclePropConfig> mPropertyConfigs GUARDED_BY(mLock);
 };
 
 struct PropConfigCmp {
diff --git a/automotive/vehicle/aidl/impl/vhal/vhal-default-service.rc b/automotive/vehicle/aidl/impl/vhal/vhal-default-service.rc
index 4c8865a..19267cd 100644
--- a/automotive/vehicle/aidl/impl/vhal/vhal-default-service.rc
+++ b/automotive/vehicle/aidl/impl/vhal/vhal-default-service.rc
@@ -1,4 +1,4 @@
-service vendor.vehicle-hal-default /vendor/bin/hw/android.hardware.automotive.vehicle-aidl-default-service
+service vendor.vehicle-hal-default /vendor/bin/hw/android.hardware.automotive.vehicle@V1-default-service
     class early_hal
     user vehicle_network
     group system inet
diff --git a/biometrics/face/aidl/default/main.cpp b/biometrics/face/aidl/default/main.cpp
index 80b153e..b7274e3 100644
--- a/biometrics/face/aidl/default/main.cpp
+++ b/biometrics/face/aidl/default/main.cpp
@@ -29,7 +29,7 @@
 
     const std::string instance = std::string(Face::descriptor) + "/default";
     binder_status_t status = AServiceManager_addService(hal->asBinder().get(), instance.c_str());
-    CHECK(status == STATUS_OK);
+    CHECK_EQ(status, STATUS_OK);
 
     ABinderProcess_joinThreadPool();
     return EXIT_FAILURE;  // should not reach
diff --git a/biometrics/fingerprint/aidl/default/main.cpp b/biometrics/fingerprint/aidl/default/main.cpp
index 4690d73..c985201 100644
--- a/biometrics/fingerprint/aidl/default/main.cpp
+++ b/biometrics/fingerprint/aidl/default/main.cpp
@@ -29,7 +29,7 @@
 
     const std::string instance = std::string(Fingerprint::descriptor) + "/default";
     binder_status_t status = AServiceManager_addService(hal->asBinder().get(), instance.c_str());
-    CHECK(status == STATUS_OK);
+    CHECK_EQ(status, STATUS_OK);
 
     ABinderProcess_joinThreadPool();
     return EXIT_FAILURE;  // should not reach
diff --git a/bluetooth/audio/2.2/Android.bp b/bluetooth/audio/2.2/Android.bp
index 6449c08..8d52ce9 100644
--- a/bluetooth/audio/2.2/Android.bp
+++ b/bluetooth/audio/2.2/Android.bp
@@ -14,6 +14,7 @@
     root: "android.hardware",
     srcs: [
         "types.hal",
+        "IBluetoothAudioPort.hal",
         "IBluetoothAudioProvider.hal",
         "IBluetoothAudioProvidersFactory.hal",
     ],
diff --git a/bluetooth/audio/2.2/IBluetoothAudioPort.hal b/bluetooth/audio/2.2/IBluetoothAudioPort.hal
new file mode 100644
index 0000000..344899c
--- /dev/null
+++ b/bluetooth/audio/2.2/IBluetoothAudioPort.hal
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio@2.2;
+
+import @2.0::IBluetoothAudioPort;
+import android.hardware.audio.common@5.0::SinkMetadata;
+
+interface IBluetoothAudioPort extends @2.0::IBluetoothAudioPort  {
+    /**
+     * Called when the metadata of the stream's sink has been changed.
+     *
+     * @param sinkMetadata Description of the audio that is recorded by the
+     *    clients.
+     */
+    updateSinkMetadata(SinkMetadata sinkMetadata);
+};
diff --git a/bluetooth/audio/2.2/IBluetoothAudioProvider.hal b/bluetooth/audio/2.2/IBluetoothAudioProvider.hal
index ad8c839..bc16b01 100644
--- a/bluetooth/audio/2.2/IBluetoothAudioProvider.hal
+++ b/bluetooth/audio/2.2/IBluetoothAudioProvider.hal
@@ -17,7 +17,7 @@
 package android.hardware.bluetooth.audio@2.2;
 
 import @2.1::IBluetoothAudioProvider;
-import @2.0::IBluetoothAudioPort;
+import @2.2::IBluetoothAudioPort;
 import @2.0::Status;
 
 /**
diff --git a/bluetooth/audio/2.2/default/A2dpOffloadAudioProvider.cpp b/bluetooth/audio/2.2/default/A2dpOffloadAudioProvider.cpp
index 126bc9e..2a6d93a 100644
--- a/bluetooth/audio/2.2/default/A2dpOffloadAudioProvider.cpp
+++ b/bluetooth/audio/2.2/default/A2dpOffloadAudioProvider.cpp
@@ -54,7 +54,7 @@
 }
 
 Return<void> A2dpOffloadAudioProvider::startSession(
-    const sp<IBluetoothAudioPort>& hostIf,
+    const sp<V2_0::IBluetoothAudioPort>& hostIf,
     const AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
   /**
    * Initialize the audio platform if audioConfiguration is supported.
diff --git a/bluetooth/audio/2.2/default/A2dpSoftwareAudioProvider.cpp b/bluetooth/audio/2.2/default/A2dpSoftwareAudioProvider.cpp
index 0d918e1..ba31d39 100644
--- a/bluetooth/audio/2.2/default/A2dpSoftwareAudioProvider.cpp
+++ b/bluetooth/audio/2.2/default/A2dpSoftwareAudioProvider.cpp
@@ -70,7 +70,7 @@
 }
 
 Return<void> A2dpSoftwareAudioProvider::startSession(
-    const sp<IBluetoothAudioPort>& hostIf,
+    const sp<V2_0::IBluetoothAudioPort>& hostIf,
     const AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
   /**
    * Initialize the audio platform if audioConfiguration is supported.
diff --git a/bluetooth/audio/2.2/default/A2dpSoftwareAudioProvider.h b/bluetooth/audio/2.2/default/A2dpSoftwareAudioProvider.h
index 3d4f0cc..ac3aece 100644
--- a/bluetooth/audio/2.2/default/A2dpSoftwareAudioProvider.h
+++ b/bluetooth/audio/2.2/default/A2dpSoftwareAudioProvider.h
@@ -40,7 +40,7 @@
   bool isValid(const V2_1::SessionType& sessionType) override;
   bool isValid(const V2_0::SessionType& sessionType) override;
 
-  Return<void> startSession(const sp<IBluetoothAudioPort>& hostIf,
+  Return<void> startSession(const sp<V2_0::IBluetoothAudioPort>& hostIf,
                             const V2_0::AudioConfiguration& audioConfig,
                             startSession_cb _hidl_cb) override;
 
diff --git a/bluetooth/audio/2.2/default/AudioPort_2_0_to_2_2_Wrapper.h b/bluetooth/audio/2.2/default/AudioPort_2_0_to_2_2_Wrapper.h
new file mode 100644
index 0000000..c5613fb
--- /dev/null
+++ b/bluetooth/audio/2.2/default/AudioPort_2_0_to_2_2_Wrapper.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/hardware/bluetooth/audio/2.2/types.h>
+
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+namespace V2_2 {
+namespace implementation {
+
+using ::android::sp;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::audio::common::V5_0::SinkMetadata;
+using ::android::hardware::audio::common::V5_0::SourceMetadata;
+using ::android::hardware::bluetooth::audio::V2_2::IBluetoothAudioPort;
+
+class AudioPort_2_0_to_2_2_Wrapper : public V2_2::IBluetoothAudioPort {
+ public:
+  AudioPort_2_0_to_2_2_Wrapper(const sp<V2_0::IBluetoothAudioPort>& port) {
+    this->port = port;
+  }
+
+  Return<void> startStream() override { return port->startStream(); }
+  Return<void> suspendStream() override { return port->suspendStream(); }
+  Return<void> stopStream() override { return port->stopStream(); }
+  Return<void> getPresentationPosition(
+      getPresentationPosition_cb _hidl_cb) override {
+    return port->getPresentationPosition(_hidl_cb);
+  }
+  Return<void> updateMetadata(const SourceMetadata& sourceMetadata) override {
+    return port->updateMetadata(sourceMetadata);
+  }
+  Return<void> updateSinkMetadata(const SinkMetadata&) override {
+    // DO NOTHING, 2.0 AudioPort doesn't support sink metadata updates
+    return Void();
+  }
+
+  sp<V2_0::IBluetoothAudioPort> port;
+};
+
+}  // namespace implementation
+}  // namespace V2_2
+}  // namespace audio
+}  // namespace bluetooth
+}  // namespace hardware
+}  // namespace android
\ No newline at end of file
diff --git a/bluetooth/audio/2.2/default/BluetoothAudioProvider.cpp b/bluetooth/audio/2.2/default/BluetoothAudioProvider.cpp
index 3655bc0..3c0ff42 100644
--- a/bluetooth/audio/2.2/default/BluetoothAudioProvider.cpp
+++ b/bluetooth/audio/2.2/default/BluetoothAudioProvider.cpp
@@ -20,6 +20,7 @@
 
 #include <android-base/logging.h>
 
+#include "AudioPort_2_0_to_2_2_Wrapper.h"
 #include "BluetoothAudioSessionReport_2_2.h"
 #include "BluetoothAudioSupportedCodecsDB_2_1.h"
 
@@ -51,7 +52,7 @@
       audio_config_({}) {}
 
 Return<void> BluetoothAudioProvider::startSession(
-    const sp<IBluetoothAudioPort>& hostIf,
+    const sp<V2_0::IBluetoothAudioPort>& hostIf,
     const V2_0::AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
   AudioConfiguration audioConfig_2_2;
 
@@ -67,11 +68,13 @@
     audioConfig_2_2.codecConfig(audioConfig.codecConfig());
   }
 
-  return startSession_2_2(hostIf, audioConfig_2_2, _hidl_cb);
+  sp<V2_2::IBluetoothAudioPort> hostIf_2_2 =
+      new AudioPort_2_0_to_2_2_Wrapper(hostIf);
+  return startSession_2_2(hostIf_2_2, audioConfig_2_2, _hidl_cb);
 }
 
 Return<void> BluetoothAudioProvider::startSession_2_1(
-    const sp<IBluetoothAudioPort>& hostIf,
+    const sp<V2_0::IBluetoothAudioPort>& hostIf,
     const V2_1::AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
   AudioConfiguration audioConfig_2_2;
   if (audioConfig.getDiscriminator() ==
@@ -92,11 +95,13 @@
     audioConfig_2_2.codecConfig(audioConfig.codecConfig());
   }
 
-  return startSession_2_2(hostIf, audioConfig_2_2, _hidl_cb);
+  sp<V2_2::IBluetoothAudioPort> hostIf_2_2 =
+      new AudioPort_2_0_to_2_2_Wrapper(hostIf);
+  return startSession_2_2(hostIf_2_2, audioConfig_2_2, _hidl_cb);
 }
 
 Return<void> BluetoothAudioProvider::startSession_2_2(
-    const sp<IBluetoothAudioPort>& hostIf,
+    const sp<V2_2::IBluetoothAudioPort>& hostIf,
     const AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
   if (hostIf == nullptr) {
     _hidl_cb(BluetoothAudioStatus::FAILURE, DataMQ::Descriptor());
diff --git a/bluetooth/audio/2.2/default/BluetoothAudioProvider.h b/bluetooth/audio/2.2/default/BluetoothAudioProvider.h
index b7581ba..0f1f3c6 100644
--- a/bluetooth/audio/2.2/default/BluetoothAudioProvider.h
+++ b/bluetooth/audio/2.2/default/BluetoothAudioProvider.h
@@ -26,7 +26,7 @@
 namespace implementation {
 
 using ::android::sp;
-using ::android::hardware::bluetooth::audio::V2_0::IBluetoothAudioPort;
+using ::android::hardware::bluetooth::audio::V2_2::IBluetoothAudioPort;
 
 using BluetoothAudioStatus =
     ::android::hardware::bluetooth::audio::V2_0::Status;
@@ -41,13 +41,13 @@
   virtual bool isValid(const V2_1::SessionType& sessionType) = 0;
   virtual bool isValid(const V2_0::SessionType& sessionType) = 0;
 
-  Return<void> startSession(const sp<IBluetoothAudioPort>& hostIf,
+  Return<void> startSession(const sp<V2_0::IBluetoothAudioPort>& hostIf,
                             const V2_0::AudioConfiguration& audioConfig,
                             startSession_cb _hidl_cb) override;
-  Return<void> startSession_2_1(const sp<IBluetoothAudioPort>& hostIf,
+  Return<void> startSession_2_1(const sp<V2_0::IBluetoothAudioPort>& hostIf,
                                 const V2_1::AudioConfiguration& audioConfig,
                                 startSession_cb _hidl_cb) override;
-  Return<void> startSession_2_2(const sp<IBluetoothAudioPort>& hostIf,
+  Return<void> startSession_2_2(const sp<V2_2::IBluetoothAudioPort>& hostIf,
                                 const AudioConfiguration& audioConfig,
                                 startSession_cb _hidl_cb) override;
   Return<void> streamStarted(BluetoothAudioStatus status) override;
@@ -59,7 +59,7 @@
 
   V2_1::SessionType session_type_;
   AudioConfiguration audio_config_;
-  sp<V2_0::IBluetoothAudioPort> stack_iface_;
+  sp<V2_2::IBluetoothAudioPort> stack_iface_;
 
   virtual Return<void> onSessionReady(startSession_cb _hidl_cb) = 0;
 };
diff --git a/bluetooth/audio/2.2/default/HearingAidAudioProvider.cpp b/bluetooth/audio/2.2/default/HearingAidAudioProvider.cpp
index c79b910..9b3294f 100644
--- a/bluetooth/audio/2.2/default/HearingAidAudioProvider.cpp
+++ b/bluetooth/audio/2.2/default/HearingAidAudioProvider.cpp
@@ -66,7 +66,7 @@
 }
 
 Return<void> HearingAidAudioProvider::startSession(
-    const sp<IBluetoothAudioPort>& hostIf,
+    const sp<V2_0::IBluetoothAudioPort>& hostIf,
     const AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
   /**
    * Initialize the audio platform if audioConfiguration is supported.
diff --git a/bluetooth/audio/2.2/default/HearingAidAudioProvider.h b/bluetooth/audio/2.2/default/HearingAidAudioProvider.h
index 426c443..63290b5 100644
--- a/bluetooth/audio/2.2/default/HearingAidAudioProvider.h
+++ b/bluetooth/audio/2.2/default/HearingAidAudioProvider.h
@@ -40,7 +40,7 @@
   bool isValid(const V2_1::SessionType& sessionType) override;
   bool isValid(const V2_0::SessionType& sessionType) override;
 
-  Return<void> startSession(const sp<IBluetoothAudioPort>& hostIf,
+  Return<void> startSession(const sp<V2_0::IBluetoothAudioPort>& hostIf,
                             const V2_0::AudioConfiguration& audioConfig,
                             startSession_cb _hidl_cb) override;
 
diff --git a/bluetooth/audio/2.2/default/LeAudioAudioProvider.cpp b/bluetooth/audio/2.2/default/LeAudioAudioProvider.cpp
index af6ec99..9ec1776 100644
--- a/bluetooth/audio/2.2/default/LeAudioAudioProvider.cpp
+++ b/bluetooth/audio/2.2/default/LeAudioAudioProvider.cpp
@@ -20,6 +20,7 @@
 
 #include <android-base/logging.h>
 
+#include "AudioPort_2_0_to_2_2_Wrapper.h"
 #include "BluetoothAudioSessionReport_2_2.h"
 #include "BluetoothAudioSupportedCodecsDB_2_1.h"
 
@@ -83,11 +84,13 @@
        .bitsPerSample = audioConfig.pcmConfig().bitsPerSample,
        .dataIntervalUs = 0});
 
-  return startSession_2_2(hostIf, audioConfig_2_2, _hidl_cb);
+  sp<V2_2::IBluetoothAudioPort> hostIf_2_2 =
+      new AudioPort_2_0_to_2_2_Wrapper(hostIf);
+  return startSession_2_2(hostIf_2_2, audioConfig_2_2, _hidl_cb);
 }
 
 Return<void> LeAudioAudioProvider::startSession_2_2(
-    const sp<V2_0::IBluetoothAudioPort>& hostIf,
+    const sp<V2_2::IBluetoothAudioPort>& hostIf,
     const AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
   /**
    * Initialize the audio platform if audioConfiguration is supported.
diff --git a/bluetooth/audio/2.2/default/LeAudioAudioProvider.h b/bluetooth/audio/2.2/default/LeAudioAudioProvider.h
index 40c26e0..3de1724 100644
--- a/bluetooth/audio/2.2/default/LeAudioAudioProvider.h
+++ b/bluetooth/audio/2.2/default/LeAudioAudioProvider.h
@@ -45,7 +45,7 @@
                                 const V2_1::AudioConfiguration& audioConfig,
                                 startSession_cb _hidl_cb) override;
 
-  Return<void> startSession_2_2(const sp<V2_0::IBluetoothAudioPort>& hostIf,
+  Return<void> startSession_2_2(const sp<V2_2::IBluetoothAudioPort>& hostIf,
                                 const AudioConfiguration& audioConfig,
                                 startSession_cb _hidl_cb) override;
 
diff --git a/bluetooth/audio/2.2/default/LeAudioOffloadAudioProvider.cpp b/bluetooth/audio/2.2/default/LeAudioOffloadAudioProvider.cpp
index 7b70654..e3da267 100644
--- a/bluetooth/audio/2.2/default/LeAudioOffloadAudioProvider.cpp
+++ b/bluetooth/audio/2.2/default/LeAudioOffloadAudioProvider.cpp
@@ -20,6 +20,7 @@
 
 #include <android-base/logging.h>
 
+#include "AudioPort_2_0_to_2_2_Wrapper.h"
 #include "BluetoothAudioSessionReport_2_2.h"
 #include "BluetoothAudioSupportedCodecsDB_2_1.h"
 #include "BluetoothAudioSupportedCodecsDB_2_2.h"
@@ -91,11 +92,13 @@
       .peerDelay = 0,
       .lc3Config = audioConfig.leAudioCodecConfig().lc3Config};
 
-  return startSession_2_2(hostIf, audioConfig_2_2, _hidl_cb);
+  sp<V2_2::IBluetoothAudioPort> hostIf_2_2 =
+      new AudioPort_2_0_to_2_2_Wrapper(hostIf);
+  return startSession_2_2(hostIf_2_2, audioConfig_2_2, _hidl_cb);
 }
 
 Return<void> LeAudioOffloadAudioProvider::startSession_2_2(
-    const sp<V2_0::IBluetoothAudioPort>& hostIf,
+    const sp<V2_2::IBluetoothAudioPort>& hostIf,
     const AudioConfiguration& audioConfig, startSession_cb _hidl_cb) {
   /**
    * Initialize the audio platform if audioConfiguration is supported.
diff --git a/bluetooth/audio/2.2/default/LeAudioOffloadAudioProvider.h b/bluetooth/audio/2.2/default/LeAudioOffloadAudioProvider.h
index 5620295..fe58de5 100644
--- a/bluetooth/audio/2.2/default/LeAudioOffloadAudioProvider.h
+++ b/bluetooth/audio/2.2/default/LeAudioOffloadAudioProvider.h
@@ -38,7 +38,7 @@
                                 const V2_1::AudioConfiguration& audioConfig,
                                 startSession_cb _hidl_cb) override;
 
-  Return<void> startSession_2_2(const sp<V2_0::IBluetoothAudioPort>& hostIf,
+  Return<void> startSession_2_2(const sp<V2_2::IBluetoothAudioPort>& hostIf,
                                 const AudioConfiguration& audioConfig,
                                 startSession_cb _hidl_cb) override;
 
diff --git a/bluetooth/audio/aidl/Android.bp b/bluetooth/audio/aidl/Android.bp
index 60da877..12eed55 100644
--- a/bluetooth/audio/aidl/Android.bp
+++ b/bluetooth/audio/aidl/Android.bp
@@ -12,6 +12,15 @@
 // 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.bluetooth.audio",
     vendor_available: true,
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
index e389ef3..9a1557a 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
@@ -38,5 +38,6 @@
   void startStream();
   void stopStream();
   void suspendStream();
-  void updateMetadata(in android.hardware.audio.common.SourceMetadata sourceMetadata);
+  void updateSourceMetadata(in android.hardware.audio.common.SourceMetadata sourceMetadata);
+  void updateSinkMetadata(in android.hardware.audio.common.SinkMetadata sinkMetadata);
 }
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
index 50e3197..827f57d 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
@@ -16,6 +16,7 @@
 
 package android.hardware.bluetooth.audio;
 
+import android.hardware.audio.common.SinkMetadata;
 import android.hardware.audio.common.SourceMetadata;
 import android.hardware.bluetooth.audio.PresentationPosition;
 
@@ -69,5 +70,12 @@
      * @param sourceMetadata Description of the audio that is played by the
      *    clients.
      */
-    void updateMetadata(in SourceMetadata sourceMetadata);
+    void updateSourceMetadata(in SourceMetadata sourceMetadata);
+
+    /**
+     * Called when the metadata of the stream's sink has been changed.
+     *
+     * @param sinkMetadata as passed from Audio Framework
+     */
+    void updateSinkMetadata(in SinkMetadata sinkMetadata);
 }
diff --git a/bluetooth/audio/utils/Android.bp b/bluetooth/audio/utils/Android.bp
index 19d2d92..4f712bf 100644
--- a/bluetooth/audio/utils/Android.bp
+++ b/bluetooth/audio/utils/Android.bp
@@ -22,6 +22,7 @@
     export_include_dirs: ["session/"],
     header_libs: ["libhardware_headers"],
     shared_libs: [
+        "android.hardware.audio.common@5.0",
         "android.hardware.bluetooth.audio@2.0",
         "android.hardware.bluetooth.audio@2.1",
         "android.hardware.bluetooth.audio@2.2",
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_1.h b/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_1.h
index 95f7408..4d7be21 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_1.h
+++ b/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_1.h
@@ -35,7 +35,7 @@
     std::shared_ptr<BluetoothAudioSession_2_1> session_ptr =
         BluetoothAudioSessionInstance_2_1::GetSessionInstance(session_type);
     if (session_ptr != nullptr) {
-      return session_ptr->IsSessionReady();
+      return session_ptr->GetAudioSession()->IsSessionReady();
     }
     return false;
   }
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_2.h b/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_2.h
index e20914e..b4ba8cf 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_2.h
+++ b/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_2.h
@@ -132,6 +132,15 @@
     }
   }
 
+  static void UpdateSinkMetadata(const SessionType_2_1& session_type,
+                                 const struct sink_metadata* sink_metadata) {
+    std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
+        BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
+    if (session_ptr != nullptr) {
+      session_ptr->UpdateSinkMetadata(sink_metadata);
+    }
+  }
+
   // The control API writes stream to FMQ
   static size_t OutWritePcmData(const SessionType_2_1& session_type,
                                 const void* buffer, size_t bytes) {
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.cpp b/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.cpp
index c250ef1..646e225 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.cpp
+++ b/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.cpp
@@ -60,16 +60,6 @@
   }
 }
 
-bool BluetoothAudioSession_2_1::IsSessionReady() {
-  if (session_type_2_1_ !=
-      SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
-    return audio_session->IsSessionReady();
-  }
-
-  std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_);
-  return audio_session->stack_iface_ != nullptr;
-}
-
 std::shared_ptr<BluetoothAudioSession>
 BluetoothAudioSession_2_1::GetAudioSession() {
   return audio_session;
@@ -80,7 +70,7 @@
 const ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration
 BluetoothAudioSession_2_1::GetAudioConfig() {
   std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_);
-  if (IsSessionReady()) {
+  if (audio_session->IsSessionReady()) {
     // If session is unknown it means it should be 2.0 type
     if (session_type_2_1_ != SessionType_2_1::UNKNOWN)
       return audio_config_2_1_;
@@ -122,9 +112,6 @@
            SessionType_2_1::LE_AUDIO_SOFTWARE_DECODED_DATAPATH);
   bool is_offload_a2dp_session =
       (session_type_2_1_ == SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH);
-  bool is_offload_le_audio_session =
-      (session_type_2_1_ == SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
-       session_type_2_1_ == SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH);
   auto audio_config_discriminator = audio_config.getDiscriminator();
   bool is_software_audio_config =
       (is_software_session &&
@@ -136,13 +123,7 @@
        audio_config_discriminator ==
            ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration::
                hidl_discriminator::codecConfig);
-  bool is_le_audio_offload_audio_config =
-      (is_offload_le_audio_session &&
-       audio_config_discriminator ==
-           ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration::
-               hidl_discriminator::leAudioCodecConfig);
-  if (!is_software_audio_config && !is_a2dp_offload_audio_config &&
-      !is_le_audio_offload_audio_config) {
+  if (!is_software_audio_config && !is_a2dp_offload_audio_config) {
     return false;
   }
   audio_config_2_1_ = audio_config;
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.h b/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.h
index db82c73..5a35153 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.h
+++ b/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.h
@@ -50,10 +50,6 @@
       const ::android::hardware::bluetooth::audio::V2_1::SessionType&
           session_type);
 
-  // The function helps to check if this session is ready or not
-  // @return: true if the Bluetooth stack has started the specified session
-  bool IsSessionReady();
-
   std::shared_ptr<BluetoothAudioSession> GetAudioSession();
 
   // The report function is used to report that the Bluetooth stack has started
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.cpp b/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.cpp
index 5a6b2e7..80df5d9 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.cpp
+++ b/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.cpp
@@ -20,10 +20,16 @@
 
 #include <android-base/logging.h>
 #include <android-base/stringprintf.h>
+#include <android/hardware/bluetooth/audio/2.2/IBluetoothAudioPort.h>
 
 namespace android {
 namespace bluetooth {
 namespace audio {
+
+using ::android::hardware::audio::common::V5_0::AudioSource;
+using ::android::hardware::audio::common::V5_0::RecordTrackMetadata;
+using ::android::hardware::audio::common::V5_0::SinkMetadata;
+
 using SessionType_2_1 =
     ::android::hardware::bluetooth::audio::V2_1::SessionType;
 using SessionType_2_0 =
@@ -37,6 +43,9 @@
 ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration
     BluetoothAudioSession_2_2::invalidOffloadAudioConfiguration = {};
 
+using IBluetoothAudioPort_2_2 =
+    ::android::hardware::bluetooth::audio::V2_2::IBluetoothAudioPort;
+
 namespace {
 bool is_2_0_session_type(
     const ::android::hardware::bluetooth::audio::V2_1::SessionType&
@@ -84,6 +93,54 @@
   return audio_session_2_1;
 }
 
+void BluetoothAudioSession_2_2::UpdateSinkMetadata(
+    const struct sink_metadata* sink_metadata) {
+  std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_);
+  if (!IsSessionReady()) {
+    LOG(DEBUG) << __func__ << " - SessionType=" << toString(session_type_2_1_)
+               << " has NO session";
+    return;
+  }
+
+  ssize_t track_count = sink_metadata->track_count;
+  LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_2_1_)
+            << ", " << track_count << " track(s)";
+  if (session_type_2_1_ == SessionType_2_1::A2DP_SOFTWARE_ENCODING_DATAPATH ||
+      session_type_2_1_ == SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH) {
+    return;
+  }
+
+  struct record_track_metadata* track = sink_metadata->tracks;
+  SinkMetadata sinkMetadata;
+  RecordTrackMetadata* halMetadata;
+
+  sinkMetadata.tracks.resize(track_count);
+  halMetadata = sinkMetadata.tracks.data();
+  while (track_count && track) {
+    halMetadata->source = static_cast<AudioSource>(track->source);
+    halMetadata->gain = track->gain;
+    // halMetadata->destination leave unspecified
+    LOG(INFO) << __func__
+              << " - SessionType=" << toString(GetAudioSession()->session_type_)
+              << ", source=" << track->source
+              << ", dest_device=" << track->dest_device
+              << ", gain=" << track->gain
+              << ", dest_device_address=" << track->dest_device_address;
+    --track_count;
+    ++track;
+    ++halMetadata;
+  }
+
+  /* This is called just for 2.2 sessions, so it's safe to do this casting*/
+  IBluetoothAudioPort_2_2* stack_iface_2_2_ =
+      static_cast<IBluetoothAudioPort_2_2*>(audio_session->stack_iface_.get());
+  auto hal_retval = stack_iface_2_2_->updateSinkMetadata(sinkMetadata);
+  if (!hal_retval.isOk()) {
+    LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
+                 << toString(session_type_2_1_) << " failed";
+  }
+}
+
 // The control function is for the bluetooth_audio module to get the current
 // AudioConfiguration
 const ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.h b/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.h
index 7213ede..d6ae3d7 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.h
+++ b/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.h
@@ -74,6 +74,8 @@
   const ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration
   GetAudioConfig();
 
+  void UpdateSinkMetadata(const struct sink_metadata* sink_metadata);
+
   static constexpr ::android::hardware::bluetooth::audio::V2_2::
       AudioConfiguration& kInvalidSoftwareAudioConfiguration =
           invalidSoftwareAudioConfiguration;
diff --git a/camera/device/3.8/ICameraDevice.hal b/camera/device/3.8/ICameraDevice.hal
index 448f176..1101819 100644
--- a/camera/device/3.8/ICameraDevice.hal
+++ b/camera/device/3.8/ICameraDevice.hal
@@ -16,6 +16,7 @@
 
 package android.hardware.camera.device@3.8;
 
+import android.hardware.camera.common@1.0::Status;
 import @3.7::ICameraDevice;
 
 /**
@@ -29,4 +30,81 @@
  * @3.7::ICameraDeviceSession.
  */
 interface ICameraDevice extends @3.7::ICameraDevice {
+    /**
+     * turnOnTorchWithStrengthLevel:
+     *
+     * Change the brightness level of the flash unit associated with this camera device
+     * and set it to value in torchStrength. This function also turns ON the torch
+     * with specified torchStrength if the torch is OFF.
+     *
+     * The torchStrength value must be within the valid range i.e. >=1 and
+     * <= FLASH_INFO_STRENGTH_MAXIMUM_LEVEL. Whenever the torch is turned OFF,
+     * the brightness level will reset to FLASH_INFO_STRENGTH_DEFAULT_LEVEL.
+     * When the client calls setTorchMode(ON) after turnOnTorchWithStrengthLevel(N),
+     * the flash unit will have brightness level equal to N. This level does not
+     * represent the real brightness units. It is linear in nature i.e. flashlight
+     * at level 10 is twice as bright as at level 5.
+     *
+     * @param torchStrength Brightness level to be set for the flashlight.
+     *
+     * @return status Status code for the operation, one of:
+     *     OK:
+     *         On a successful change to the torch strength level.
+     *     INTERNAL_ERROR:
+     *         The flash unit cannot be operated due to an unexpected internal
+     *         error.
+     *     CAMERA_IN_USE:
+     *         This status code is returned when:
+     *           - This camera device has been opened, so the torch cannot be
+     *             controlled until it is closed.
+     *           - Due to other camera devices being open, or due to other
+     *             resource constraints, the torch cannot be controlled currently.
+     *     ILLEGAL_ARGUMENT:
+     *         If the torchStrength value is not within the range i.e. < 1 or
+     *         > FLASH_INFO_STRENGTH_MAXIMUM_LEVEL.
+     *     METHOD_NOT_SUPPORTED:
+     *         This status code is returned when:
+     *           - This camera device does not support direct operation of flashlight
+     *             torch mode. The framework must open the camera device and turn
+     *             the torch on through the device interface.
+     *           - This camera device does not have a flash unit.
+     *           - This camera device has flash unit but does not support torch
+     *             strength control.
+     *     CAMERA_DISCONNECTED:
+     *         An external camera device has been disconnected, and is no longer
+     *         available. This camera device interface is now stale, and a new
+     *         instance must be acquired if the device is reconnected. All
+     *         subsequent calls on this interface must return
+     *         CAMERA_DISCONNECTED.
+     *
+     */
+    turnOnTorchWithStrengthLevel(int32_t torchStrength) generates (Status status);
+
+    /**
+     * getTorchStrengthLevel:
+     *
+     * Get current torch strength level.
+     * If the device supports torch strength control, when the torch is OFF the
+     * strength level will reset to default level, so the return
+     * value in this case will be equal to FLASH_INFO_STRENGTH_DEFAULT_LEVEL.
+     *
+     * @return status Status code for the operation, one of:
+     *      OK:
+     *           On success.
+     *      INTERNAL_ERROR:
+     *           An unexpected error occurred and the information is not
+     *           available.
+     *      METHOD_NOT_SUPPORTED:
+     *          This status code is returned when:
+     *            - This camera device does not support direct operation of flashlight
+     *              torch mode. The framework must open the camera device and turn
+     *              the torch on through the device interface.
+     *            - This camera device does not have a flash unit.
+     *            - This camera device has flash unit but does not support torch
+     *              strength control.
+     *
+     * @return torchStrength Current torch strength level.
+     *
+     */
+    getTorchStrengthLevel() generates (Status status, int32_t torchStrength);
 };
diff --git a/camera/device/3.8/types.hal b/camera/device/3.8/types.hal
index 6daa0e1..843d050 100644
--- a/camera/device/3.8/types.hal
+++ b/camera/device/3.8/types.hal
@@ -35,8 +35,9 @@
 
     /**
      * Timestamp for the capture readout. This must be in the same time domain
-     * as v3_2.timestamp, and the value must be v3_2.timestamp + exposureTime
-     * for a rolling shutter sensor.
+     * as v3_2.timestamp, and for a rolling shutter sensor, the value must be
+     * v3_2.timestamp + exposureTime + t_crop_top where t_crop_top is the exposure time
+     * skew of the cropped lines on the top.
      */
     uint64_t readoutTimestamp;
 };
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index ff8cd49..01ec9cb 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -41,6 +41,7 @@
 #include <android/hardware/camera/device/3.6/ICameraDevice.h>
 #include <android/hardware/camera/device/3.6/ICameraDeviceSession.h>
 #include <android/hardware/camera/device/3.7/ICameraDevice.h>
+#include <android/hardware/camera/device/3.8/ICameraDevice.h>
 #include <android/hardware/camera/device/3.7/ICameraDeviceSession.h>
 #include <android/hardware/camera/device/3.7/ICameraInjectionSession.h>
 #include <android/hardware/camera/device/3.8/ICameraDeviceCallback.h>
@@ -911,6 +912,7 @@
             uint32_t* outBufSize);
     static Status isConstrainedModeAvailable(camera_metadata_t *staticMeta);
     static Status isLogicalMultiCamera(const camera_metadata_t *staticMeta);
+    static bool isTorchStrengthControlSupported(const camera_metadata_t *staticMeta);
     static Status isOfflineSessionSupported(const camera_metadata_t *staticMeta);
     static Status getPhysicalCameraIds(const camera_metadata_t *staticMeta,
             std::unordered_set<std::string> *physicalIds/*out*/);
@@ -2933,6 +2935,137 @@
     }
 }
 
+// Verify that the torch strength level can be set and retrieved successfully.
+TEST_P(CameraHidlTest, turnOnTorchWithStrengthLevel) {
+    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
+    bool torchControlSupported = false;
+    bool torchStrengthControlSupported = false;
+    Return<void> ret;
+
+    ret = mProvider->isSetTorchModeSupported([&](auto status, bool support) {
+        ALOGI("isSetTorchModeSupported returns status:%d supported:%d", (int)status, support);
+        ASSERT_EQ(Status::OK, status);
+        torchControlSupported = support;
+    });
+
+    sp<TorchProviderCb> cb = new TorchProviderCb(this);
+    Return<Status> returnStatus = mProvider->setCallback(cb);
+    ASSERT_TRUE(returnStatus.isOk());
+    ASSERT_EQ(Status::OK, returnStatus);
+
+    for (const auto& name : cameraDeviceNames) {
+        int deviceVersion = getCameraDeviceVersion(name, mProviderType);
+        int32_t defaultLevel;
+        switch (deviceVersion) {
+            case CAMERA_DEVICE_API_VERSION_3_8: {
+                ::android::sp<::android::hardware::camera::device::V3_8::ICameraDevice> device3_8;
+                ALOGI("%s: Testing camera device %s", __FUNCTION__, name.c_str());
+                ret = mProvider->getCameraDeviceInterface_V3_x(
+                        name, [&](auto status, const auto& device) {
+                            ASSERT_EQ(Status::OK, status);
+                            ASSERT_NE(device, nullptr);
+                            auto castResult = device::V3_8::ICameraDevice::castFrom(device);
+                            ASSERT_TRUE(castResult.isOk());
+                            device3_8 = castResult;
+                        });
+                ASSERT_TRUE(ret.isOk());
+
+                ret = device3_8->getCameraCharacteristics([&] (auto s, const auto& chars) {
+                    ASSERT_EQ(Status::OK, s);
+                    const camera_metadata_t* staticMeta =
+                            reinterpret_cast<const camera_metadata_t*>(chars.data());
+                    ASSERT_NE(nullptr, staticMeta);
+                    torchStrengthControlSupported = isTorchStrengthControlSupported(staticMeta);
+                    camera_metadata_ro_entry entry;
+                    int rc = find_camera_metadata_ro_entry(staticMeta,
+                            ANDROID_FLASH_INFO_STRENGTH_DEFAULT_LEVEL, &entry);
+                    if (torchStrengthControlSupported) {
+                        ASSERT_EQ(rc, 0);
+                        ASSERT_GT(entry.count, 0);
+                        defaultLevel = *entry.data.i32;
+                        ALOGI("Default level is:%d", defaultLevel);
+                    }
+                });
+                ASSERT_TRUE(ret.isOk());
+                // If torchStrengthControl is supported, torchControlSupported should be true.
+                if (torchStrengthControlSupported) {
+                    ASSERT_TRUE(torchControlSupported);
+                }
+                mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
+                returnStatus = device3_8->turnOnTorchWithStrengthLevel(2);
+                ASSERT_TRUE(returnStatus.isOk());
+                // Method_not_supported check
+                if (!torchStrengthControlSupported) {
+                    ALOGI("Torch strength control not supported.");
+                    ASSERT_EQ(Status::METHOD_NOT_SUPPORTED, returnStatus);
+                } else {
+                    ASSERT_EQ(Status::OK, returnStatus);
+                    if (returnStatus == Status::OK) {
+                        {
+                            std::unique_lock<std::mutex> l(mTorchLock);
+                            while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
+                                auto timeout = std::chrono::system_clock::now() +
+                                        std::chrono::seconds(kTorchTimeoutSec);
+                                ASSERT_NE(std::cv_status::timeout, mTorchCond.wait_until(l,
+                                        timeout));
+                            }
+                            ASSERT_EQ(TorchModeStatus::AVAILABLE_ON, mTorchStatus);
+                            mTorchStatus = TorchModeStatus::NOT_AVAILABLE;
+                        }
+                        ALOGI("getTorchStrengthLevel: Testing");
+                        ret = device3_8->getTorchStrengthLevel([&]
+                                (auto status, const auto& strengthLevel) {
+                                    ASSERT_TRUE(ret.isOk());
+                                    ASSERT_EQ(Status::OK, status);
+                                    ALOGI("Torch strength level is : %d", strengthLevel);
+                                    ASSERT_EQ(strengthLevel, 2);
+                                });
+                        // Turn OFF the torch and verify torch strength level is reset to default level.
+                        ALOGI("Testing torch strength level reset after turning the torch OFF.");
+                        returnStatus = device3_8->setTorchMode(TorchMode::OFF);
+                        ASSERT_TRUE(returnStatus.isOk());
+                        ASSERT_EQ(Status::OK, returnStatus);
+                        {
+                            std::unique_lock<std::mutex> l(mTorchLock);
+                            while (TorchModeStatus::NOT_AVAILABLE == mTorchStatus) {
+                                auto timeout = std::chrono::system_clock::now() +
+                                        std::chrono::seconds(kTorchTimeoutSec);
+                                ASSERT_NE(std::cv_status::timeout, mTorchCond.wait_until(l,
+                                        timeout));
+                            }
+                            ASSERT_EQ(TorchModeStatus::AVAILABLE_OFF, mTorchStatus);
+                        }
+                        ret = device3_8->getTorchStrengthLevel([&]
+                                (auto status, const auto& strengthLevel) {
+                                    ASSERT_TRUE(ret.isOk());
+                                    ASSERT_EQ(Status::OK, status);
+                                    ALOGI("Torch strength level after turning OFF torch is : %d",
+                                            strengthLevel);
+                                    ASSERT_EQ(strengthLevel, defaultLevel);
+                                });
+                    }
+                }
+            }
+            break;
+            case CAMERA_DEVICE_API_VERSION_3_7:
+            case CAMERA_DEVICE_API_VERSION_3_6:
+            case CAMERA_DEVICE_API_VERSION_3_5:
+            case CAMERA_DEVICE_API_VERSION_3_4:
+            case CAMERA_DEVICE_API_VERSION_3_3:
+            case CAMERA_DEVICE_API_VERSION_3_2:
+            case CAMERA_DEVICE_API_VERSION_1_0: {
+                ALOGI("Torch strength control feature not supported.");
+            }
+            break;
+            default: {
+                ALOGI("Invalid device version.");
+                ADD_FAILURE();
+            }
+            break;
+        }
+    }
+}
+
 //In case it is supported verify that torch can be enabled.
 //Check for corresponding toch callbacks as well.
 TEST_P(CameraHidlTest, setTorchMode) {
@@ -4796,15 +4929,24 @@
             ASSERT_EQ(testStream.id, inflightReq.resultOutputBuffers[0].streamId);
 
             // For camera device 3.8 or newer, shutterReadoutTimestamp must be
-            // available, and it must be shutterTimestamp + exposureTime.
+            // available, and it must be >= shutterTimestamp + exposureTime, and
+            // < shutterTimestamp + exposureTime + rollingShutterSkew / 2.
             if (deviceVersion >= CAMERA_DEVICE_API_VERSION_3_8) {
                 ASSERT_TRUE(inflightReq.shutterReadoutTimestampValid);
                 ASSERT_FALSE(inflightReq.collectedResult.isEmpty());
                 if (inflightReq.collectedResult.exists(ANDROID_SENSOR_EXPOSURE_TIME)) {
                     camera_metadata_entry_t exposureTimeResult = inflightReq.collectedResult.find(
                             ANDROID_SENSOR_EXPOSURE_TIME);
-                    ASSERT_EQ(inflightReq.shutterReadoutTimestamp - inflightReq.shutterTimestamp,
-                            exposureTimeResult.data.i64[0]);
+                    nsecs_t exposureToReadout =
+                            inflightReq.shutterReadoutTimestamp - inflightReq.shutterTimestamp;
+                    ASSERT_GE(exposureToReadout, exposureTimeResult.data.i64[0]);
+                    if (inflightReq.collectedResult.exists(ANDROID_SENSOR_ROLLING_SHUTTER_SKEW)) {
+                        camera_metadata_entry_t rollingShutterSkew =
+                                inflightReq.collectedResult.find(
+                                        ANDROID_SENSOR_ROLLING_SHUTTER_SKEW);
+                        ASSERT_LT(exposureToReadout, exposureTimeResult.data.i64[0] +
+                                                             rollingShutterSkew.data.i64[0] / 2);
+                    }
                 }
             }
 
@@ -6591,6 +6733,22 @@
     return ret;
 }
 
+bool CameraHidlTest::isTorchStrengthControlSupported(const camera_metadata_t *staticMetadata) {
+    int32_t maxLevel = 0;
+    camera_metadata_ro_entry maxEntry;
+    int rc = find_camera_metadata_ro_entry(staticMetadata,
+            ANDROID_FLASH_INFO_STRENGTH_MAXIMUM_LEVEL, &maxEntry);
+    if (rc != 0) {
+        return false;
+    }
+    maxLevel = *maxEntry.data.i32;
+    if (maxLevel > 1) {
+        ALOGI("Torch strength control supported.");
+        return true;
+    }
+    return false;
+}
+
 // Check if the camera device has logical multi-camera capability.
 Status CameraHidlTest::isOfflineSessionSupported(const camera_metadata_t *staticMeta) {
     Status ret = Status::METHOD_NOT_SUPPORTED;
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index a781b35..416b55b 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -298,16 +298,7 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="false">
-        <name>android.hardware.health</name>
-        <version>2.1</version>
-        <interface>
-            <name>IHealth</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <!-- TODO(b/177269435): require health AIDL HAL and deprecate HIDL HAL -->
-    <hal format="aidl" optional="true">
+    <hal format="aidl" optional="false">
         <name>android.hardware.health</name>
         <version>1</version>
         <interface>
@@ -332,6 +323,13 @@
         </interface>
     </hal>
     <hal format="aidl" optional="true">
+        <name>android.hardware.net.nlinterceptor</name>
+        <interface>
+            <name>IInterceptor</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
         <name>android.hardware.oemlock</name>
         <version>1</version>
         <interface>
@@ -374,7 +372,7 @@
     </hal>
     <hal format="aidl" optional="true">
         <name>android.hardware.security.keymint</name>
-        <version>1</version>
+        <version>1-2</version>
         <interface>
             <name>IKeyMintDevice</name>
             <instance>default</instance>
@@ -383,6 +381,7 @@
     </hal>
     <hal format="aidl" optional="true">
         <name>android.hardware.security.keymint</name>
+        <version>1-2</version>
         <interface>
             <name>IRemotelyProvisionedComponent</name>
             <instance>default</instance>
@@ -459,7 +458,7 @@
     </hal>
     <hal format="aidl" optional="false">
         <name>android.hardware.power</name>
-        <version>1-2</version>
+        <version>1-3</version>
         <interface>
             <name>IPower</name>
             <instance>default</instance>
@@ -788,4 +787,11 @@
             <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/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/NanoappInfo.aidl b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/NanoappInfo.aidl
index ea7825a..7175d7f 100644
--- a/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/NanoappInfo.aidl
+++ b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/NanoappInfo.aidl
@@ -38,4 +38,5 @@
   int nanoappVersion;
   boolean enabled;
   String[] permissions;
+  android.hardware.contexthub.NanoappRpcService[] rpcServices;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/NanoappRpcService.aidl
similarity index 86%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
copy to contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/NanoappRpcService.aidl
index cfafc50..a6a1644 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/NanoappRpcService.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,8 +31,9 @@
 // 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.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum LayerRequest {
-  CLEAR_CLIENT_TARGET = 1,
+package android.hardware.contexthub;
+@VintfStability
+parcelable NanoappRpcService {
+  long id;
+  int version;
 }
diff --git a/contexthub/aidl/android/hardware/contexthub/NanoappInfo.aidl b/contexthub/aidl/android/hardware/contexthub/NanoappInfo.aidl
index 9991dc8..77ac026 100644
--- a/contexthub/aidl/android/hardware/contexthub/NanoappInfo.aidl
+++ b/contexthub/aidl/android/hardware/contexthub/NanoappInfo.aidl
@@ -16,6 +16,8 @@
 
 package android.hardware.contexthub;
 
+import android.hardware.contexthub.NanoappRpcService;
+
 @VintfStability
 parcelable NanoappInfo {
     /** The unique identifier of the nanoapp. */
@@ -39,4 +41,9 @@
      * this list.
      */
     String[] permissions;
+
+    /**
+     * The list of RPC services supported by this nanoapp.
+     */
+    NanoappRpcService[] rpcServices;
 }
diff --git a/contexthub/aidl/android/hardware/contexthub/NanoappRpcService.aidl b/contexthub/aidl/android/hardware/contexthub/NanoappRpcService.aidl
new file mode 100644
index 0000000..6dc5e95
--- /dev/null
+++ b/contexthub/aidl/android/hardware/contexthub/NanoappRpcService.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.
+ */
+
+package android.hardware.contexthub;
+
+/**
+ * An RPC service exposed by a nanoapp.
+ *
+ * The implementation of the RPC interface is not defined by the HAL, and is written
+ * at the messaging endpoint layers (Android app and/or CHRE nanoapp). NanoappRpcService
+ * contains the informational metadata to be consumed by the RPC interface layer.
+ */
+@VintfStability
+parcelable NanoappRpcService {
+    /**
+     * The unique 64-bit ID of an RPC service exposed by a nanoapp. Note that
+     * the uniqueness is only required within the nanoapp's domain (i.e. the
+     * combination of the nanoapp ID and service id must be unique).
+     */
+    long id;
+
+    /**
+     * The software version of this service, which follows the semantic
+     * versioning scheme (see semver.org). It follows the format
+     * major.minor.patch, where major and minor versions take up one byte
+     * each, and the patch version takes up the final 2 bytes.
+     */
+    int version;
+}
diff --git a/contexthub/aidl/vts/VtsAidlHalContextHubTargetTest.cpp b/contexthub/aidl/vts/VtsAidlHalContextHubTargetTest.cpp
index 1b2dc29..392e23c 100644
--- a/contexthub/aidl/vts/VtsAidlHalContextHubTargetTest.cpp
+++ b/contexthub/aidl/vts/VtsAidlHalContextHubTargetTest.cpp
@@ -41,6 +41,7 @@
 using ::android::hardware::contexthub::IContextHubCallbackDefault;
 using ::android::hardware::contexthub::NanoappBinary;
 using ::android::hardware::contexthub::NanoappInfo;
+using ::android::hardware::contexthub::NanoappRpcService;
 using ::android::hardware::contexthub::Setting;
 using ::android::hardware::contexthub::vts_utils::kNonExistentAppId;
 using ::android::hardware::contexthub::vts_utils::waitForCallback;
@@ -151,6 +152,14 @@
     for (const NanoappInfo& appInfo : appInfoList) {
         EXPECT_NE(appInfo.nanoappId, UINT64_C(0));
         EXPECT_NE(appInfo.nanoappId, kNonExistentAppId);
+
+        // Verify services are unique.
+        std::set<uint64_t> existingServiceIds;
+        for (const NanoappRpcService& rpcService : appInfo.rpcServices) {
+            EXPECT_NE(rpcService.id, UINT64_C(0));
+            EXPECT_EQ(existingServiceIds.count(rpcService.id), 0);
+            existingServiceIds.insert(rpcService.id);
+        }
     }
 }
 
diff --git a/dumpstate/aidl/default/main.cpp b/dumpstate/aidl/default/main.cpp
index 2451752..5bc85b4 100644
--- a/dumpstate/aidl/default/main.cpp
+++ b/dumpstate/aidl/default/main.cpp
@@ -29,7 +29,7 @@
     const std::string instance = std::string() + Dumpstate::descriptor + "/default";
     binder_status_t status =
             AServiceManager_registerLazyService(dumpstate->asBinder().get(), instance.c_str());
-    CHECK(status == STATUS_OK);
+    CHECK_EQ(status, STATUS_OK);
 
     ABinderProcess_joinThreadPool();
     return EXIT_FAILURE;  // Unreachable
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IAGnss.aidl
similarity index 71%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
copy to gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IAGnss.aidl
index a522d53..f02e08c 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IAGnss.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,11 +31,19 @@
 // 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.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum BlendMode {
-  INVALID = 0,
-  NONE = 1,
-  PREMULTIPLIED = 2,
-  COVERAGE = 3,
+package android.hardware.gnss;
+@VintfStability
+interface IAGnss {
+  void setCallback(in android.hardware.gnss.IAGnssCallback callback);
+  void dataConnClosed();
+  void dataConnFailed();
+  void setServer(in android.hardware.gnss.IAGnssCallback.AGnssType type, in String hostname, in int port);
+  void dataConnOpen(in long networkHandle, in String apn, in android.hardware.gnss.IAGnss.ApnIpType apnIpType);
+  @Backing(type="int") @VintfStability
+  enum ApnIpType {
+    INVALID = 0,
+    IPV4 = 1,
+    IPV6 = 2,
+    IPV4V6 = 3,
+  }
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IAGnssCallback.aidl
similarity index 70%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
copy to gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IAGnssCallback.aidl
index 41a1afe..2a46f61 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IAGnssCallback.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,10 +31,23 @@
 // 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.graphics.composer3;
+package android.hardware.gnss;
 @VintfStability
-parcelable ExecuteCommandsStatus {
-  boolean queueChanged;
-  int length;
-  android.hardware.common.NativeHandle[] handles;
+interface IAGnssCallback {
+  void agnssStatusCb(in android.hardware.gnss.IAGnssCallback.AGnssType type, in android.hardware.gnss.IAGnssCallback.AGnssStatusValue status);
+  @Backing(type="int") @VintfStability
+  enum AGnssType {
+    SUPL = 1,
+    C2K = 2,
+    SUPL_EIMS = 3,
+    SUPL_IMS = 4,
+  }
+  @Backing(type="int") @VintfStability
+  enum AGnssStatusValue {
+    REQUEST_AGNSS_DATA_CONN = 1,
+    RELEASE_AGNSS_DATA_CONN = 2,
+    AGNSS_DATA_CONNECTED = 3,
+    AGNSS_DATA_CONN_DONE = 4,
+    AGNSS_DATA_CONN_FAILED = 5,
+  }
 }
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl
index 9bd04a0..9df7fe5 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl
@@ -43,6 +43,8 @@
   @nullable android.hardware.gnss.IGnssBatching getExtensionGnssBatching();
   @nullable android.hardware.gnss.IGnssGeofence getExtensionGnssGeofence();
   @nullable android.hardware.gnss.IGnssNavigationMessageInterface getExtensionGnssNavigationMessage();
+  android.hardware.gnss.IAGnss getExtensionAGnss();
+  android.hardware.gnss.IGnssDebug getExtensionGnssDebug();
   const int ERROR_INVALID_ARGUMENT = 1;
   const int ERROR_ALREADY_INIT = 2;
   const int ERROR_GENERIC = 3;
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssDebug.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssDebug.aidl
new file mode 100644
index 0000000..27d9887
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssDebug.aidl
@@ -0,0 +1,94 @@
+/*
+ * 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.gnss;
+@VintfStability
+interface IGnssDebug {
+  android.hardware.gnss.IGnssDebug.DebugData getDebugData();
+  @Backing(type="int") @VintfStability
+  enum SatelliteEphemerisType {
+    EPHEMERIS = 0,
+    ALMANAC_ONLY = 1,
+    NOT_AVAILABLE = 2,
+  }
+  @Backing(type="int") @VintfStability
+  enum SatelliteEphemerisSource {
+    DEMODULATED = 0,
+    SUPL_PROVIDED = 1,
+    OTHER_SERVER_PROVIDED = 2,
+    OTHER = 3,
+  }
+  @Backing(type="int") @VintfStability
+  enum SatelliteEphemerisHealth {
+    GOOD = 0,
+    BAD = 1,
+    UNKNOWN = 2,
+  }
+  @VintfStability
+  parcelable TimeDebug {
+    long timeEstimateMs;
+    float timeUncertaintyNs;
+    float frequencyUncertaintyNsPerSec;
+  }
+  @VintfStability
+  parcelable PositionDebug {
+    boolean valid;
+    double latitudeDegrees;
+    double longitudeDegrees;
+    float altitudeMeters;
+    float speedMetersPerSec;
+    float bearingDegrees;
+    double horizontalAccuracyMeters;
+    double verticalAccuracyMeters;
+    double speedAccuracyMetersPerSecond;
+    double bearingAccuracyDegrees;
+    float ageSeconds;
+  }
+  @VintfStability
+  parcelable SatelliteData {
+    int svid;
+    android.hardware.gnss.GnssConstellationType constellation;
+    android.hardware.gnss.IGnssDebug.SatelliteEphemerisType ephemerisType;
+    android.hardware.gnss.IGnssDebug.SatelliteEphemerisSource ephemerisSource;
+    android.hardware.gnss.IGnssDebug.SatelliteEphemerisHealth ephemerisHealth;
+    float ephemerisAgeSeconds;
+    boolean serverPredictionIsAvailable;
+    float serverPredictionAgeSeconds;
+  }
+  @VintfStability
+  parcelable DebugData {
+    android.hardware.gnss.IGnssDebug.PositionDebug position;
+    android.hardware.gnss.IGnssDebug.TimeDebug time;
+    List<android.hardware.gnss.IGnssDebug.SatelliteData> satelliteDataArray;
+  }
+}
diff --git a/gnss/aidl/android/hardware/gnss/IAGnss.aidl b/gnss/aidl/android/hardware/gnss/IAGnss.aidl
new file mode 100644
index 0000000..3e256e2
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/IAGnss.aidl
@@ -0,0 +1,79 @@
+/*
+ * 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.gnss;
+
+import android.hardware.gnss.IAGnssCallback;
+import android.hardware.gnss.IAGnssCallback.AGnssType;
+
+/** Extended interface for Assisted GNSS support. */
+@VintfStability
+interface IAGnss {
+    /** Access point name IP type */
+    @VintfStability
+    @Backing(type="int")
+    enum ApnIpType {
+        INVALID = 0,
+        IPV4 = 1,
+        IPV6 = 2,
+        IPV4V6 = 3,
+    }
+
+    /**
+     * Opens the AGNSS interface and provides the callback routines to the
+     * implementation of this interface.
+     *
+     * If setCallback is not called, this interface will not respond to any
+     * other method calls.
+     *
+     * @param callback Handle to the AGNSS status callback interface.
+     */
+    void setCallback(in IAGnssCallback callback);
+
+    /**
+     * Notifies that the AGNSS data connection has been closed.
+     */
+    void dataConnClosed();
+
+    /**
+     * Notifies that a data connection is not available for AGNSS.
+     */
+    void dataConnFailed();
+
+    /**
+     * Sets the hostname and port for the AGNSS server.
+     *
+     * @param type Specifies if SUPL or C2K.
+     * @param hostname Hostname of the AGNSS server.
+     * @param port Port number associated with the server.
+     */
+    void setServer(in AGnssType type, in String hostname, in int port);
+
+    /**
+     * Notifies GNSS that a data connection is available and sets the network handle,
+     * name of the APN, and its IP type to be used for SUPL connections.
+     *
+     * The HAL implementation must use the network handle to set the network for the
+     * SUPL connection sockets using the android_setsocknetwork function. This will ensure
+     * that there is a network path to the SUPL server. The network handle can also be used
+     * to get the IP address of SUPL FQDN using the android_getaddrinfofornetwork() function.
+     *
+     * @param networkHandle Handle representing the network for use with the NDK API.
+     * @param apn Access Point Name (follows regular APN naming convention).
+     * @param apnIpType Specifies IP type of APN.
+     */
+    void dataConnOpen(in long networkHandle, in String apn, in ApnIpType apnIpType);
+}
diff --git a/gnss/aidl/android/hardware/gnss/IAGnssCallback.aidl b/gnss/aidl/android/hardware/gnss/IAGnssCallback.aidl
new file mode 100644
index 0000000..7c25937
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/IAGnssCallback.aidl
@@ -0,0 +1,63 @@
+/*
+ * 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.gnss;
+
+/** Callback structure for the AGNSS interface. */
+@VintfStability
+interface IAGnssCallback {
+    /** AGNSS service type */
+    @VintfStability
+    @Backing(type="int")
+    enum AGnssType {
+        SUPL = 1,
+        C2K = 2,
+        SUPL_EIMS = 3,
+        SUPL_IMS = 4,
+    }
+
+    /** AGNSS status value */
+    @VintfStability
+    @Backing(type="int")
+    enum AGnssStatusValue {
+        /** GNSS requests data connection for AGNSS. */
+        REQUEST_AGNSS_DATA_CONN = 1,
+
+        /** GNSS releases the AGNSS data connection. */
+        RELEASE_AGNSS_DATA_CONN = 2,
+
+        /** AGNSS data connection initiated */
+        AGNSS_DATA_CONNECTED = 3,
+
+        /** AGNSS data connection completed */
+        AGNSS_DATA_CONN_DONE = 4,
+
+        /** AGNSS data connection failed */
+        AGNSS_DATA_CONN_FAILED = 5,
+    }
+
+    /**
+     * Callback with AGNSS status information.
+     *
+     * The GNSS HAL implementation must use this method to request the framework to setup
+     * network connection for the specified AGNSS service and to update the connection
+     * status so that the framework can release the resources.
+     *
+     * @param type Type of AGNSS service.
+     * @parama status Status of the data connection.
+     */
+    void agnssStatusCb(in AGnssType type, in AGnssStatusValue status);
+}
diff --git a/gnss/aidl/android/hardware/gnss/IGnss.aidl b/gnss/aidl/android/hardware/gnss/IGnss.aidl
index 42cc496..2751521 100644
--- a/gnss/aidl/android/hardware/gnss/IGnss.aidl
+++ b/gnss/aidl/android/hardware/gnss/IGnss.aidl
@@ -16,9 +16,11 @@
 
 package android.hardware.gnss;
 
+import android.hardware.gnss.IAGnss;
 import android.hardware.gnss.IGnssBatching;
 import android.hardware.gnss.IGnssCallback;
 import android.hardware.gnss.IGnssConfiguration;
+import android.hardware.gnss.IGnssDebug;
 import android.hardware.gnss.IGnssGeofence;
 import android.hardware.gnss.IGnssMeasurementInterface;
 import android.hardware.gnss.IGnssNavigationMessageInterface;
@@ -75,7 +77,7 @@
     /**
      * This method returns the IGnssPsds interface.
      *
-     * @return Handle to the IGnssPsds interface.
+     * @return The IGnssPsds interface.
      */
     @nullable IGnssPsds getExtensionPsds();
 
@@ -84,7 +86,7 @@
      *
      * This method must return non-null.
      *
-     * @return Handle to the IGnssConfiguration interface.
+     * @return The IGnssConfiguration interface.
      */
     IGnssConfiguration getExtensionGnssConfiguration();
 
@@ -93,7 +95,7 @@
      *
      * This method must return non-null.
      *
-     * @return Handle to the IGnssMeasurementInterface interface.
+     * @return The IGnssMeasurementInterface interface.
      */
     IGnssMeasurementInterface getExtensionGnssMeasurement();
 
@@ -102,28 +104,44 @@
      *
      * This method must return non-null.
      *
-     * @return Handle to the IGnssPowerIndication interface.
+     * @return The IGnssPowerIndication interface.
      */
     IGnssPowerIndication getExtensionGnssPowerIndication();
 
     /**
      * This method returns the IGnssBatching interface.
      *
-     * @return Handle to the IGnssBatching interface.
+     * @return The IGnssBatching interface.
      */
     @nullable IGnssBatching getExtensionGnssBatching();
 
     /**
      * This method returns the IGnssGeofence interface.
      *
-     * @return Handle to the IGnssGeofence interface.
+     * @return The IGnssGeofence interface.
      */
     @nullable IGnssGeofence getExtensionGnssGeofence();
 
     /**
      * This method returns the IGnssNavigationMessageInterface.
      *
-     * @return Handle to the IGnssNavigationMessageInterface.
+     * @return The IGnssNavigationMessageInterface.
      */
     @nullable IGnssNavigationMessageInterface getExtensionGnssNavigationMessage();
+
+    /**
+     * This method returns the IAGnss interface.
+     *
+     * @return The IAGnss interface.
+     */
+    IAGnss getExtensionAGnss();
+
+    /**
+     * This method returns the IGnssDebug interface.
+     *
+     * This method must return non-null.
+     *
+     * @return Handle to the IGnssDebug interface.
+     */
+    IGnssDebug getExtensionGnssDebug();
 }
diff --git a/gnss/aidl/android/hardware/gnss/IGnssDebug.aidl b/gnss/aidl/android/hardware/gnss/IGnssDebug.aidl
new file mode 100644
index 0000000..475a4a3
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/IGnssDebug.aidl
@@ -0,0 +1,208 @@
+/*
+ * 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.gnss;
+
+import android.hardware.gnss.GnssConstellationType;
+
+/**
+ * Extended interface for GNSS Debug support
+ *
+ * This information is used for debugging purpose, e.g., shown in a bugreport to
+ * describe the chipset states including time, position, and satellite data.
+ */
+@VintfStability
+interface IGnssDebug {
+    /** Satellite's ephemeris type */
+    @VintfStability
+    @Backing(type="int")
+    enum SatelliteEphemerisType {
+        EPHEMERIS = 0,
+        ALMANAC_ONLY = 1,
+        NOT_AVAILABLE = 2,
+    }
+
+    /** Satellite's ephemeris source */
+    @VintfStability
+    @Backing(type="int")
+    enum SatelliteEphemerisSource {
+        DEMODULATED = 0,
+        SUPL_PROVIDED = 1,
+        OTHER_SERVER_PROVIDED = 2,
+        OTHER = 3,
+    }
+
+    /** Satellite's ephemeris health */
+    @VintfStability
+    @Backing(type="int")
+    enum SatelliteEphemerisHealth {
+        GOOD = 0,
+        BAD = 1,
+        UNKNOWN = 2,
+    }
+
+    /**
+     * Provides the current best known UTC time estimate.
+     * If no fresh information is available, e.g. after a delete all,
+     * then whatever the effective defaults are on the device must be
+     * provided (e.g. Jan. 1, 2017, with an uncertainty of 5 years) expressed
+     * in the specified units.
+     */
+    @VintfStability
+    parcelable TimeDebug {
+        /** UTC time estimate in milliseconds. */
+        long timeEstimateMs;
+
+        /** 68% time error estimate in nanoseconds. */
+        float timeUncertaintyNs;
+
+        /**
+         * 68% error estimate in local clock drift,
+         * in nanoseconds per second (also known as parts per billion - ppb.)
+         */
+        float frequencyUncertaintyNsPerSec;
+    }
+
+    @VintfStability
+    parcelable PositionDebug {
+        /**
+         * Validity of the data in this struct. False only if no
+         * latitude/longitude information is known.
+         */
+        boolean valid;
+
+        /** Latitude expressed in degrees */
+        double latitudeDegrees;
+
+        /** Longitude expressed in degrees */
+        double longitudeDegrees;
+
+        /** Altitude above ellipsoid expressed in meters */
+        float altitudeMeters;
+
+        /** Represents horizontal speed in meters per second. */
+        float speedMetersPerSec;
+
+        /** Represents heading in degrees. */
+        float bearingDegrees;
+
+        /**
+         * Estimated horizontal accuracy of position expressed in meters,
+         * radial, 68% confidence.
+         */
+        double horizontalAccuracyMeters;
+
+        /**
+         * Estimated vertical accuracy of position expressed in meters, with
+         * 68% confidence.
+         */
+        double verticalAccuracyMeters;
+
+        /**
+         * Estimated speed accuracy in meters per second with 68% confidence.
+         */
+        double speedAccuracyMetersPerSecond;
+
+        /**
+         * Estimated bearing accuracy degrees with 68% confidence.
+         */
+        double bearingAccuracyDegrees;
+
+        /**
+         * Time duration before this report that this position information was
+         * valid.  This can, for example, be a previous injected location with
+         * an age potentially thousands of seconds old, or
+         * extrapolated to the current time (with appropriately increased
+         * accuracy estimates), with a (near) zero age.
+         */
+        float ageSeconds;
+    }
+
+    @VintfStability
+    parcelable SatelliteData {
+        /** Satellite vehicle ID number */
+        int svid;
+
+        /** Defines the constellation type of the given SV. */
+        GnssConstellationType constellation;
+
+        /**
+         * Defines the standard broadcast ephemeris or almanac availability for
+         * the satellite.  To report status of predicted orbit and clock
+         * information, see the serverPrediction fields below.
+         */
+        SatelliteEphemerisType ephemerisType;
+
+        /** Defines the ephemeris source of the satellite. */
+        SatelliteEphemerisSource ephemerisSource;
+
+        /**
+         * Defines whether the satellite is known healthy
+         * (safe for use in location calculation.)
+         */
+        SatelliteEphemerisHealth ephemerisHealth;
+
+        /**
+         * Time duration from this report (current time), minus the
+         * effective time of the ephemeris source (e.g. TOE, TOA.)
+         * Set to 0 when ephemerisType is NOT_AVAILABLE.
+         */
+        float ephemerisAgeSeconds;
+
+        /**
+         * True if a server has provided a predicted orbit and clock model for
+         * this satellite.
+         */
+        boolean serverPredictionIsAvailable;
+
+        /**
+         * Time duration from this report (current time) minus the time of the
+         * start of the server predicted information.  For example, a 1 day
+         * old prediction would be reported as 86400 seconds here.
+         */
+        float serverPredictionAgeSeconds;
+    }
+
+    /**
+     * Provides a set of debug information that is filled by the GNSS chipset
+     * when the method getDebugData() is invoked.
+     */
+    @VintfStability
+    parcelable DebugData {
+        /** Current best known position. */
+        PositionDebug position;
+
+        /** Current best know time estimate */
+        TimeDebug time;
+
+        /**
+         * Provides a list of the available satellite data, for all
+         * satellites and constellations the device can track,
+         * including GnssConstellationType UNKNOWN.
+         */
+        List<SatelliteData> satelliteDataArray;
+    }
+
+    /**
+     * This methods requests position, time and satellite ephemeris debug information
+     * from the HAL.
+     *
+     * @return ret debugData information from GNSS Hal that contains the current best
+     * known position, best known time estimate and a complete list of
+     * constellations that the device can track.
+     */
+    DebugData getDebugData();
+}
diff --git a/gnss/aidl/default/AGnss.cpp b/gnss/aidl/default/AGnss.cpp
new file mode 100644
index 0000000..e8d5ef7
--- /dev/null
+++ b/gnss/aidl/default/AGnss.cpp
@@ -0,0 +1,47 @@
+/*
+ * 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 "AGnssAidl"
+
+#include "AGnss.h"
+#include <inttypes.h>
+#include <log/log.h>
+
+namespace aidl::android::hardware::gnss {
+
+std::shared_ptr<IAGnssCallback> AGnss::sCallback = nullptr;
+
+ndk::ScopedAStatus AGnss::setCallback(const std::shared_ptr<IAGnssCallback>& callback) {
+    ALOGD("AGnss::setCallback");
+    std::unique_lock<std::mutex> lock(mMutex);
+    sCallback = callback;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus AGnss::setServer(AGnssType type, const std::string& hostname, int port) {
+    ALOGD("AGnss::setServer: type: %s, hostname: %s, port: %d", toString(type).c_str(),
+          hostname.c_str(), port);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus AGnss::dataConnOpen(int64_t networkHandle, const std::string& apn,
+                                       ApnIpType apnIpType) {
+    ALOGD("AGnss::dataConnOpen: networkHandle:%" PRId64 ", apn: %s, apnIpType %s", networkHandle,
+          apn.c_str(), toString(apnIpType).c_str());
+    return ndk::ScopedAStatus::ok();
+}
+
+}  // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/AGnss.h b/gnss/aidl/default/AGnss.h
new file mode 100644
index 0000000..cd973e1
--- /dev/null
+++ b/gnss/aidl/default/AGnss.h
@@ -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.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/gnss/BnAGnss.h>
+
+namespace aidl::android::hardware::gnss {
+
+using AGnssType = IAGnssCallback::AGnssType;
+
+struct AGnss : public BnAGnss {
+  public:
+    ndk::ScopedAStatus setCallback(const std::shared_ptr<IAGnssCallback>& callback) override;
+    ndk::ScopedAStatus dataConnClosed() override { return ndk::ScopedAStatus::ok(); }
+    ndk::ScopedAStatus dataConnFailed() override { return ndk::ScopedAStatus::ok(); }
+    ndk::ScopedAStatus setServer(AGnssType type, const std::string& hostname, int port) override;
+    ndk::ScopedAStatus dataConnOpen(int64_t networkHandle, const std::string& apn,
+                                    ApnIpType apnIpType) override;
+
+  private:
+    // Synchronization lock for sCallback
+    mutable std::mutex mMutex;
+    // Guarded by mMutex
+    static std::shared_ptr<IAGnssCallback> sCallback;
+};
+
+}  // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/Android.bp b/gnss/aidl/default/Android.bp
index b6df895..24569ae 100644
--- a/gnss/aidl/default/Android.bp
+++ b/gnss/aidl/default/Android.bp
@@ -55,8 +55,10 @@
         "android.hardware.gnss-V2-ndk",
     ],
     srcs: [
+        "AGnss.cpp",
         "Gnss.cpp",
         "GnssBatching.cpp",
+        "GnssDebug.cpp",
         "GnssGeofence.cpp",
         "GnssHidlHal.cpp",
         "GnssNavigationMessageInterface.cpp",
diff --git a/gnss/aidl/default/Gnss.cpp b/gnss/aidl/default/Gnss.cpp
index 8d58a20..45d6b1d 100644
--- a/gnss/aidl/default/Gnss.cpp
+++ b/gnss/aidl/default/Gnss.cpp
@@ -18,8 +18,10 @@
 
 #include "Gnss.h"
 #include <log/log.h>
+#include "AGnss.h"
 #include "GnssBatching.h"
 #include "GnssConfiguration.h"
+#include "GnssDebug.h"
 #include "GnssGeofence.h"
 #include "GnssMeasurementInterface.h"
 #include "GnssNavigationMessageInterface.h"
@@ -56,6 +58,12 @@
     return ndk::ScopedAStatus::ok();
 }
 
+ndk::ScopedAStatus Gnss::getExtensionAGnss(std::shared_ptr<IAGnss>* iAGnss) {
+    ALOGD("Gnss::getExtensionAGnss");
+    *iAGnss = SharedRefBase::make<AGnss>();
+    return ndk::ScopedAStatus::ok();
+}
+
 ndk::ScopedAStatus Gnss::getExtensionPsds(std::shared_ptr<IGnssPsds>* iGnssPsds) {
     ALOGD("Gnss::getExtensionPsds");
     *iGnssPsds = SharedRefBase::make<GnssPsds>();
@@ -113,4 +121,11 @@
     return ndk::ScopedAStatus::ok();
 }
 
+ndk::ScopedAStatus Gnss::getExtensionGnssDebug(std::shared_ptr<IGnssDebug>* iGnssDebug) {
+    ALOGD("Gnss::getExtensionGnssDebug");
+
+    *iGnssDebug = SharedRefBase::make<GnssDebug>();
+    return ndk::ScopedAStatus::ok();
+}
+
 }  // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/Gnss.h b/gnss/aidl/default/Gnss.h
index 128a6c1..f59607f 100644
--- a/gnss/aidl/default/Gnss.h
+++ b/gnss/aidl/default/Gnss.h
@@ -16,9 +16,11 @@
 
 #pragma once
 
+#include <aidl/android/hardware/gnss/BnAGnss.h>
 #include <aidl/android/hardware/gnss/BnGnss.h>
 #include <aidl/android/hardware/gnss/BnGnssBatching.h>
 #include <aidl/android/hardware/gnss/BnGnssConfiguration.h>
+#include <aidl/android/hardware/gnss/BnGnssDebug.h>
 #include <aidl/android/hardware/gnss/BnGnssMeasurementInterface.h>
 #include <aidl/android/hardware/gnss/BnGnssPowerIndication.h>
 #include <aidl/android/hardware/gnss/BnGnssPsds.h>
@@ -44,6 +46,8 @@
             std::shared_ptr<IGnssGeofence>* iGnssGeofence) override;
     ndk::ScopedAStatus getExtensionGnssNavigationMessage(
             std::shared_ptr<IGnssNavigationMessageInterface>* iGnssNavigationMessage) override;
+    ndk::ScopedAStatus getExtensionAGnss(std::shared_ptr<IAGnss>* iAGnss) override;
+    ndk::ScopedAStatus getExtensionGnssDebug(std::shared_ptr<IGnssDebug>* iGnssDebug) override;
 
     std::shared_ptr<GnssConfiguration> mGnssConfiguration;
     std::shared_ptr<GnssPowerIndication> mGnssPowerIndication;
diff --git a/gnss/aidl/default/GnssDebug.cpp b/gnss/aidl/default/GnssDebug.cpp
new file mode 100644
index 0000000..f40c0bc
--- /dev/null
+++ b/gnss/aidl/default/GnssDebug.cpp
@@ -0,0 +1,50 @@
+/*
+ * 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 "GnssDebugAidl"
+
+#include "GnssDebug.h"
+#include <log/log.h>
+#include "MockLocation.h"
+
+namespace aidl::android::hardware::gnss {
+
+ndk::ScopedAStatus GnssDebug::getDebugData(DebugData* debugData) {
+    ALOGD("GnssDebug::getDebugData");
+
+    PositionDebug positionDebug = {.valid = true,
+                                   .latitudeDegrees = 37.4219999,
+                                   .longitudeDegrees = -122.0840575,
+                                   .altitudeMeters = 1.60062531,
+                                   .speedMetersPerSec = 0,
+                                   .bearingDegrees = 0,
+                                   .horizontalAccuracyMeters = 5,
+                                   .verticalAccuracyMeters = 5,
+                                   .speedAccuracyMetersPerSecond = 1,
+                                   .bearingAccuracyDegrees = 90,
+                                   .ageSeconds = 0.99};
+    TimeDebug timeDebug = {.timeEstimateMs = 1519930775453L,
+                           .timeUncertaintyNs = 1000,
+                           .frequencyUncertaintyNsPerSec = 5.0e4};
+    std::vector<SatelliteData> satelliteDataArrayDebug = {};
+    debugData->position = positionDebug;
+    debugData->time = timeDebug;
+    debugData->satelliteDataArray = satelliteDataArrayDebug;
+
+    return ndk::ScopedAStatus::ok();
+}
+
+}  // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/GnssDebug.h b/gnss/aidl/default/GnssDebug.h
new file mode 100644
index 0000000..001d47c
--- /dev/null
+++ b/gnss/aidl/default/GnssDebug.h
@@ -0,0 +1,28 @@
+/*
+ * 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 <aidl/android/hardware/gnss/BnGnssDebug.h>
+
+namespace aidl::android::hardware::gnss {
+
+struct GnssDebug : public BnGnssDebug {
+  public:
+    ndk::ScopedAStatus getDebugData(DebugData* debugData) override;
+};
+
+}  // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/service.cpp b/gnss/aidl/default/service.cpp
index 09f1ad2..bbe34f1 100644
--- a/gnss/aidl/default/service.cpp
+++ b/gnss/aidl/default/service.cpp
@@ -42,7 +42,7 @@
     const std::string instance = std::string() + Gnss::descriptor + "/default";
     binder_status_t status =
             AServiceManager_addService(gnssAidl->asBinder().get(), instance.c_str());
-    CHECK(status == STATUS_OK);
+    CHECK_EQ(status, STATUS_OK);
 
     sp<IGnss> gnss = new GnssHidlHal(gnssAidl);
     configureRpcThreadpool(1, true /* will join */);
diff --git a/gnss/aidl/vts/AGnssCallbackAidl.cpp b/gnss/aidl/vts/AGnssCallbackAidl.cpp
new file mode 100644
index 0000000..3327835
--- /dev/null
+++ b/gnss/aidl/vts/AGnssCallbackAidl.cpp
@@ -0,0 +1,24 @@
+/*
+ * 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 "AGnssCallbackAidl.h"
+#include <log/log.h>
+
+android::binder::Status AGnssCallbackAidl::agnssStatusCb(const AGnssType type,
+                                                         const AGnssStatusValue status) {
+    ALOGI("agnssStatusCb type %d status %d", type, status);
+    return android::binder::Status::ok();
+}
diff --git a/gnss/aidl/vts/AGnssCallbackAidl.h b/gnss/aidl/vts/AGnssCallbackAidl.h
new file mode 100644
index 0000000..6173e85
--- /dev/null
+++ b/gnss/aidl/vts/AGnssCallbackAidl.h
@@ -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.
+ */
+
+#pragma once
+
+#include <android/hardware/gnss/BnAGnssCallback.h>
+
+using AGnssType = android::hardware::gnss::IAGnssCallback::AGnssType;
+using AGnssStatusValue = android::hardware::gnss::IAGnssCallback::AGnssStatusValue;
+
+/** Implementation for IAGnssCallback. */
+class AGnssCallbackAidl : public android::hardware::gnss::BnAGnssCallback {
+  public:
+    AGnssCallbackAidl(){};
+    ~AGnssCallbackAidl(){};
+    android::binder::Status agnssStatusCb(const AGnssType type,
+                                          const AGnssStatusValue status) override;
+};
diff --git a/gnss/aidl/vts/Android.bp b/gnss/aidl/vts/Android.bp
index 4d81519..041d579 100644
--- a/gnss/aidl/vts/Android.bp
+++ b/gnss/aidl/vts/Android.bp
@@ -30,6 +30,7 @@
     srcs: [
         "gnss_hal_test.cpp",
         "gnss_hal_test_cases.cpp",
+        "AGnssCallbackAidl.cpp",
         "GnssBatchingCallback.cpp",
         "GnssCallbackAidl.cpp",
         "GnssGeofenceCallback.cpp",
diff --git a/gnss/aidl/vts/gnss_hal_test_cases.cpp b/gnss/aidl/vts/gnss_hal_test_cases.cpp
index 830922c..36be631 100644
--- a/gnss/aidl/vts/gnss_hal_test_cases.cpp
+++ b/gnss/aidl/vts/gnss_hal_test_cases.cpp
@@ -16,12 +16,16 @@
 
 #define LOG_TAG "GnssHalTestCases"
 
+#include <android/hardware/gnss/IAGnss.h>
 #include <android/hardware/gnss/IGnss.h>
 #include <android/hardware/gnss/IGnssBatching.h>
+#include <android/hardware/gnss/IGnssDebug.h>
 #include <android/hardware/gnss/IGnssMeasurementCallback.h>
 #include <android/hardware/gnss/IGnssMeasurementInterface.h>
 #include <android/hardware/gnss/IGnssPowerIndication.h>
 #include <android/hardware/gnss/IGnssPsds.h>
+#include <cutils/properties.h>
+#include "AGnssCallbackAidl.h"
 #include "GnssBatchingCallback.h"
 #include "GnssGeofenceCallback.h"
 #include "GnssMeasurementCallbackAidl.h"
@@ -36,10 +40,12 @@
 using android::hardware::gnss::GnssData;
 using android::hardware::gnss::GnssMeasurement;
 using android::hardware::gnss::GnssPowerStats;
+using android::hardware::gnss::IAGnss;
 using android::hardware::gnss::IGnss;
 using android::hardware::gnss::IGnssBatching;
 using android::hardware::gnss::IGnssBatchingCallback;
 using android::hardware::gnss::IGnssConfiguration;
+using android::hardware::gnss::IGnssDebug;
 using android::hardware::gnss::IGnssGeofence;
 using android::hardware::gnss::IGnssGeofenceCallback;
 using android::hardware::gnss::IGnssMeasurementCallback;
@@ -52,6 +58,12 @@
 
 using GnssConstellationTypeAidl = android::hardware::gnss::GnssConstellationType;
 
+static bool IsAutomotiveDevice() {
+    char buffer[PROPERTY_VALUE_MAX] = {0};
+    property_get("ro.hardware.type", buffer, "");
+    return strncmp(buffer, "automotive", PROPERTY_VALUE_MAX) == 0;
+}
+
 /*
  * SetupTeardownCreateCleanup:
  * Requests the gnss HAL then calls cleanup
@@ -793,3 +805,74 @@
         ASSERT_TRUE(status.isOk());
     }
 }
+
+/*
+ * TestAGnssExtension:
+ * 1. Gets the IAGnss extension.
+ * 2. Sets AGnssCallback.
+ * 3. Sets SUPL server host/port.
+ */
+TEST_P(GnssHalTest, TestAGnssExtension) {
+    if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+        return;
+    }
+    sp<IAGnss> iAGnss;
+    auto status = aidl_gnss_hal_->getExtensionAGnss(&iAGnss);
+    ASSERT_TRUE(status.isOk());
+    ASSERT_TRUE(iAGnss != nullptr);
+
+    auto agnssCallback = sp<AGnssCallbackAidl>::make();
+    status = iAGnss->setCallback(agnssCallback);
+    ASSERT_TRUE(status.isOk());
+
+    // Set SUPL server host/port
+    status = iAGnss->setServer(AGnssType::SUPL, String16("supl.google.com"), 7275);
+    ASSERT_TRUE(status.isOk());
+}
+
+/*
+ * GnssDebugValuesSanityTest:
+ * Ensures that GnssDebug values make sense.
+ */
+TEST_P(GnssHalTest, GnssDebugValuesSanityTest) {
+    if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+        return;
+    }
+    sp<IGnssDebug> iGnssDebug;
+    auto status = aidl_gnss_hal_->getExtensionGnssDebug(&iGnssDebug);
+    ASSERT_TRUE(status.isOk());
+
+    if (!IsAutomotiveDevice() && gnss_cb_->info_cbq_.calledCount() > 0) {
+        ASSERT_TRUE(iGnssDebug != nullptr);
+
+        IGnssDebug::DebugData data;
+        auto status = iGnssDebug->getDebugData(&data);
+        ASSERT_TRUE(status.isOk());
+
+        if (data.position.valid) {
+            ASSERT_TRUE(data.position.latitudeDegrees >= -90 &&
+                        data.position.latitudeDegrees <= 90);
+            ASSERT_TRUE(data.position.longitudeDegrees >= -180 &&
+                        data.position.longitudeDegrees <= 180);
+            ASSERT_TRUE(data.position.altitudeMeters >= -1000 &&  // Dead Sea: -414m
+                        data.position.altitudeMeters <= 20000);   // Mount Everest: 8850m
+            ASSERT_TRUE(data.position.speedMetersPerSec >= 0 &&
+                        data.position.speedMetersPerSec <= 600);
+            ASSERT_TRUE(data.position.bearingDegrees >= -360 &&
+                        data.position.bearingDegrees <= 360);
+            ASSERT_TRUE(data.position.horizontalAccuracyMeters > 0 &&
+                        data.position.horizontalAccuracyMeters <= 20000000);
+            ASSERT_TRUE(data.position.verticalAccuracyMeters > 0 &&
+                        data.position.verticalAccuracyMeters <= 20000);
+            ASSERT_TRUE(data.position.speedAccuracyMetersPerSecond > 0 &&
+                        data.position.speedAccuracyMetersPerSecond <= 500);
+            ASSERT_TRUE(data.position.bearingAccuracyDegrees > 0 &&
+                        data.position.bearingAccuracyDegrees <= 180);
+            ASSERT_TRUE(data.position.ageSeconds >= 0);
+        }
+        ASSERT_TRUE(data.time.timeEstimateMs >= 1483228800000);  // Jan 01 2017 00:00:00 GMT.
+        ASSERT_TRUE(data.time.timeUncertaintyNs > 0);
+        ASSERT_TRUE(data.time.frequencyUncertaintyNsPerSec > 0 &&
+                    data.time.frequencyUncertaintyNsPerSec <= 2.0e5);  // 200 ppm
+    }
+}
diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/PixelFormat.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/PixelFormat.aidl
index 04a863b..512fecb 100644
--- a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/PixelFormat.aidl
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/PixelFormat.aidl
@@ -63,4 +63,5 @@
   STENCIL_8 = 53,
   YCBCR_P010 = 54,
   HSV_888 = 55,
+  R_8 = 56,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/Point.aidl
similarity index 92%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/Point.aidl
index cfafc50..3722803 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/Point.aidl
@@ -31,8 +31,9 @@
 // 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.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum LayerRequest {
-  CLEAR_CLIENT_TARGET = 1,
+package android.hardware.graphics.common;
+@VintfStability
+parcelable Point {
+  int x;
+  int y;
 }
diff --git a/graphics/common/aidl/android/hardware/graphics/common/PixelFormat.aidl b/graphics/common/aidl/android/hardware/graphics/common/PixelFormat.aidl
index eb87f8d..4e891f6 100644
--- a/graphics/common/aidl/android/hardware/graphics/common/PixelFormat.aidl
+++ b/graphics/common/aidl/android/hardware/graphics/common/PixelFormat.aidl
@@ -498,4 +498,11 @@
      * interpretation is defined by the dataspace.
      */
     HSV_888 = 0x37,
+
+    /**
+     * 8 bit format with a single 8-bit component.
+     *
+     * The component values are unsigned normalized to the range [0, 1].
+     */
+    R_8 = 0x38,
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/common/aidl/android/hardware/graphics/common/Point.aidl
similarity index 64%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/common/aidl/android/hardware/graphics/common/Point.aidl
index 10de558..b3ede44 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/common/aidl/android/hardware/graphics/common/Point.aidl
@@ -14,18 +14,14 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
+package android.hardware.graphics.common;
 
 /**
- * Layer requests returned from getDisplayRequests.
+ * General purpose definition of a point.
  */
+
 @VintfStability
-@Backing(type="int")
-enum LayerRequest {
-    /**
-     * The client must clear its target with transparent pixels where
-     * this layer would be. The client may ignore this request if the
-     * layer must be blended.
-     */
-    CLEAR_CLIENT_TARGET = 1 << 0,
+parcelable Point {
+    int x;
+    int y;
 }
diff --git a/graphics/composer/aidl/Android.bp b/graphics/composer/aidl/Android.bp
index e33c653..5f5b54e 100644
--- a/graphics/composer/aidl/Android.bp
+++ b/graphics/composer/aidl/Android.bp
@@ -31,12 +31,13 @@
         enabled: true,
         support_system_process: true,
     },
-    srcs: ["android/hardware/graphics/composer3/*.aidl"],
+    srcs: [
+        "android/hardware/graphics/composer3/*.aidl",
+    ],
     stability: "vintf",
     imports: [
         "android.hardware.graphics.common-V3",
         "android.hardware.common-V2",
-        "android.hardware.common.fmq-V1",
     ],
     backend: {
         cpp: {
@@ -73,6 +74,7 @@
     vendor_available: true,
     shared_libs: [
         "android.hardware.graphics.composer3-V1-ndk",
+        "android.hardware.common-V2-ndk",
         "libbase",
         "libfmq",
         "libsync",
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Buffer.aidl
similarity index 92%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Buffer.aidl
index a522d53..a33ad23 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Buffer.aidl
@@ -32,10 +32,9 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum BlendMode {
-  INVALID = 0,
-  NONE = 1,
-  PREMULTIPLIED = 2,
-  COVERAGE = 3,
+@VintfStability
+parcelable Buffer {
+  int slot;
+  @nullable android.hardware.common.NativeHandle handle;
+  @nullable ParcelFileDescriptor fence;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ChangedCompositionLayer.aidl
similarity index 93%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ChangedCompositionLayer.aidl
index 41a1afe..7e47ba8 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ChangedCompositionLayer.aidl
@@ -33,8 +33,7 @@
 
 package android.hardware.graphics.composer3;
 @VintfStability
-parcelable ExecuteCommandsStatus {
-  boolean queueChanged;
-  int length;
-  android.hardware.common.NativeHandle[] handles;
+parcelable ChangedCompositionLayer {
+  long layer;
+  android.hardware.graphics.composer3.Composition composition;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ChangedCompositionTypes.aidl
similarity index 93%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ChangedCompositionTypes.aidl
index 41a1afe..9a5ca97 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ChangedCompositionTypes.aidl
@@ -33,8 +33,7 @@
 
 package android.hardware.graphics.composer3;
 @VintfStability
-parcelable ExecuteCommandsStatus {
-  boolean queueChanged;
-  int length;
-  android.hardware.common.NativeHandle[] handles;
+parcelable ChangedCompositionTypes {
+  long display;
+  android.hardware.graphics.composer3.ChangedCompositionLayer[] layers;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ClientTarget.aidl
similarity index 90%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ClientTarget.aidl
index 41a1afe..7632707 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ClientTarget.aidl
@@ -33,8 +33,8 @@
 
 package android.hardware.graphics.composer3;
 @VintfStability
-parcelable ExecuteCommandsStatus {
-  boolean queueChanged;
-  int length;
-  android.hardware.common.NativeHandle[] handles;
+parcelable ClientTarget {
+  android.hardware.graphics.composer3.Buffer buffer;
+  android.hardware.graphics.common.Dataspace dataspace;
+  android.hardware.graphics.common.Rect[] damage;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ClientTargetPropertyWithNits.aidl
similarity index 91%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ClientTargetPropertyWithNits.aidl
index 41a1afe..f0fb22e 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ClientTargetPropertyWithNits.aidl
@@ -33,8 +33,8 @@
 
 package android.hardware.graphics.composer3;
 @VintfStability
-parcelable ExecuteCommandsStatus {
-  boolean queueChanged;
-  int length;
-  android.hardware.common.NativeHandle[] handles;
+parcelable ClientTargetPropertyWithNits {
+  long display;
+  android.hardware.graphics.composer3.ClientTargetProperty clientTargetProperty;
+  float whitePointNits;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl
similarity index 93%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl
index 41a1afe..df07c9c 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl
@@ -33,8 +33,7 @@
 
 package android.hardware.graphics.composer3;
 @VintfStability
-parcelable ExecuteCommandsStatus {
-  boolean queueChanged;
-  int length;
-  android.hardware.common.NativeHandle[] handles;
+parcelable ColorTransformPayload {
+  float[] matrix;
+  android.hardware.graphics.common.ColorTransform hint;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Command.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Command.aidl
deleted file mode 100644
index e19105d..0000000
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Command.aidl
+++ /dev/null
@@ -1,76 +0,0 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-///////////////////////////////////////////////////////////////////////////////
-// 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.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum Command {
-  LENGTH_MASK = 65535,
-  OPCODE_SHIFT = 16,
-  OPCODE_MASK = -65536,
-  SELECT_DISPLAY = 0,
-  SELECT_LAYER = 65536,
-  SET_ERROR = 16777216,
-  SET_CHANGED_COMPOSITION_TYPES = 16842752,
-  SET_DISPLAY_REQUESTS = 16908288,
-  SET_PRESENT_FENCE = 16973824,
-  SET_RELEASE_FENCES = 17039360,
-  SET_COLOR_TRANSFORM = 33554432,
-  SET_CLIENT_TARGET = 33619968,
-  SET_OUTPUT_BUFFER = 33685504,
-  VALIDATE_DISPLAY = 33751040,
-  ACCEPT_DISPLAY_CHANGES = 33816576,
-  PRESENT_DISPLAY = 33882112,
-  PRESENT_OR_VALIDATE_DISPLAY = 33947648,
-  SET_LAYER_CURSOR_POSITION = 50331648,
-  SET_LAYER_BUFFER = 50397184,
-  SET_LAYER_SURFACE_DAMAGE = 50462720,
-  SET_LAYER_BLEND_MODE = 67108864,
-  SET_LAYER_COLOR = 67174400,
-  SET_LAYER_COMPOSITION_TYPE = 67239936,
-  SET_LAYER_DATASPACE = 67305472,
-  SET_LAYER_DISPLAY_FRAME = 67371008,
-  SET_LAYER_PLANE_ALPHA = 67436544,
-  SET_LAYER_SIDEBAND_STREAM = 67502080,
-  SET_LAYER_SOURCE_CROP = 67567616,
-  SET_LAYER_TRANSFORM = 67633152,
-  SET_LAYER_VISIBLE_REGION = 67698688,
-  SET_LAYER_Z_ORDER = 67764224,
-  SET_PRESENT_OR_VALIDATE_DISPLAY_RESULT = 67829760,
-  SET_LAYER_PER_FRAME_METADATA = 50528256,
-  SET_LAYER_FLOAT_COLOR = 67895296,
-  SET_LAYER_COLOR_TRANSFORM = 67960832,
-  SET_LAYER_PER_FRAME_METADATA_BLOBS = 50593792,
-  SET_CLIENT_TARGET_PROPERTY = 17104896,
-  SET_LAYER_GENERIC_METADATA = 68026368,
-  SET_LAYER_WHITE_POINT_NITS = 50659328,
-}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/CommandError.aidl
similarity index 95%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/CommandError.aidl
index cfafc50..103bfdc 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/CommandError.aidl
@@ -32,7 +32,8 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum LayerRequest {
-  CLEAR_CLIENT_TARGET = 1,
+@VintfStability
+parcelable CommandError {
+  int commandIndex;
+  int errorCode;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/CommandResultPayload.aidl
similarity index 76%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/CommandResultPayload.aidl
index 41a1afe..ebbb31e 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/CommandResultPayload.aidl
@@ -33,8 +33,12 @@
 
 package android.hardware.graphics.composer3;
 @VintfStability
-parcelable ExecuteCommandsStatus {
-  boolean queueChanged;
-  int length;
-  android.hardware.common.NativeHandle[] handles;
+union CommandResultPayload {
+  android.hardware.graphics.composer3.CommandError error;
+  android.hardware.graphics.composer3.ChangedCompositionTypes changedCompositionTypes;
+  android.hardware.graphics.composer3.DisplayRequest displayRequest;
+  android.hardware.graphics.composer3.PresentFence presentFence;
+  android.hardware.graphics.composer3.ReleaseFences releaseFences;
+  android.hardware.graphics.composer3.PresentOrValidate presentOrValidateResult;
+  android.hardware.graphics.composer3.ClientTargetPropertyWithNits clientTargetProperty;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Composition.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Composition.aidl
index e327e87..d2d8f04 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Composition.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Composition.aidl
@@ -40,4 +40,5 @@
   SOLID_COLOR = 3,
   CURSOR = 4,
   SIDEBAND = 5,
+  DISPLAY_DECORATION = 6,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayCapability.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayCapability.aidl
index 0bcd870..9f5342e 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayCapability.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayCapability.aidl
@@ -40,4 +40,5 @@
   BRIGHTNESS = 3,
   PROTECTED_CONTENTS = 4,
   AUTO_LOW_LATENCY_MODE = 5,
+  SUSPEND = 6,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayCommand.aidl
similarity index 78%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayCommand.aidl
index a522d53..2f5d00f 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayCommand.aidl
@@ -32,10 +32,15 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum BlendMode {
-  INVALID = 0,
-  NONE = 1,
-  PREMULTIPLIED = 2,
-  COVERAGE = 3,
+@VintfStability
+parcelable DisplayCommand {
+  long display;
+  android.hardware.graphics.composer3.LayerCommand[] layers;
+  @nullable android.hardware.graphics.composer3.ColorTransformPayload colorTransform;
+  @nullable android.hardware.graphics.composer3.ClientTarget clientTarget;
+  @nullable android.hardware.graphics.composer3.Buffer virtualDisplayOutputBuffer;
+  boolean validateDisplay;
+  boolean acceptDisplayChanges;
+  boolean presentDisplay;
+  boolean presentOrValidateDisplay;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl
index 26e7d97..13462ce 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl
@@ -32,8 +32,17 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum DisplayRequest {
-  FLIP_CLIENT_TARGET = 1,
-  WRITE_CLIENT_TARGET_TO_OUTPUT = 2,
+@VintfStability
+parcelable DisplayRequest {
+  long display;
+  int mask;
+  android.hardware.graphics.composer3.DisplayRequest.LayerRequest[] layerRequests;
+  const int FLIP_CLIENT_TARGET = 1;
+  const int WRITE_CLIENT_TARGET_TO_OUTPUT = 2;
+  @VintfStability
+  parcelable LayerRequest {
+    long layer;
+    int mask;
+    const int CLEAR_CLIENT_TARGET = 1;
+  }
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/GenericMetadata.aidl
similarity index 93%
rename from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
rename to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/GenericMetadata.aidl
index 41a1afe..c18529b 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/GenericMetadata.aidl
@@ -33,8 +33,7 @@
 
 package android.hardware.graphics.composer3;
 @VintfStability
-parcelable ExecuteCommandsStatus {
-  boolean queueChanged;
-  int length;
-  android.hardware.common.NativeHandle[] handles;
+parcelable GenericMetadata {
+  android.hardware.graphics.composer3.LayerGenericMetadataKey key;
+  byte[] value;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl
index d7cab2b..2bdbc9f 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl
@@ -38,12 +38,11 @@
   android.hardware.graphics.composer3.VirtualDisplay createVirtualDisplay(int width, int height, android.hardware.graphics.common.PixelFormat formatHint, int outputBufferSlotCount);
   void destroyLayer(long display, long layer);
   void destroyVirtualDisplay(long display);
-  android.hardware.graphics.composer3.ExecuteCommandsStatus executeCommands(int inLength, in android.hardware.common.NativeHandle[] inHandles);
+  android.hardware.graphics.composer3.CommandResultPayload[] executeCommands(in android.hardware.graphics.composer3.DisplayCommand[] commands);
   int getActiveConfig(long display);
   android.hardware.graphics.composer3.ColorMode[] getColorModes(long display);
   float[] getDataspaceSaturationMatrix(android.hardware.graphics.common.Dataspace dataspace);
   int getDisplayAttribute(long display, int config, android.hardware.graphics.composer3.DisplayAttribute attribute);
-  boolean getDisplayBrightnessSupport(long display);
   android.hardware.graphics.composer3.DisplayCapability[] getDisplayCapabilities(long display);
   int[] getDisplayConfigs(long display);
   android.hardware.graphics.composer3.DisplayConnectionType getDisplayConnectionType(long display);
@@ -52,11 +51,9 @@
   int getDisplayVsyncPeriod(long display);
   android.hardware.graphics.composer3.DisplayContentSample getDisplayedContentSample(long display, long maxFrames, long timestamp);
   android.hardware.graphics.composer3.DisplayContentSamplingAttributes getDisplayedContentSamplingAttributes(long display);
-  boolean getDozeSupport(long display);
   android.hardware.graphics.composer3.HdrCapabilities getHdrCapabilities(long display);
   android.hardware.graphics.composer3.LayerGenericMetadataKey[] getLayerGenericMetadataKeys();
   int getMaxVirtualDisplayCount();
-  android.hardware.common.fmq.MQDescriptor<int,android.hardware.common.fmq.SynchronizedReadWrite> getOutputCommandQueue();
   android.hardware.graphics.composer3.PerFrameMetadataKey[] getPerFrameMetadataKeys(long display);
   android.hardware.graphics.composer3.ReadbackBufferAttributes getReadbackBufferAttributes(long display);
   ParcelFileDescriptor getReadbackBufferFence(long display);
@@ -71,7 +68,6 @@
   void setContentType(long display, android.hardware.graphics.composer3.ContentType type);
   void setDisplayBrightness(long display, float brightness);
   void setDisplayedContentSamplingEnabled(long display, boolean enable, android.hardware.graphics.composer3.FormatColorComponent componentMask, long maxFrames);
-  void setInputCommandQueue(in android.hardware.common.fmq.MQDescriptor<int,android.hardware.common.fmq.SynchronizedReadWrite> descriptor);
   void setPowerMode(long display, android.hardware.graphics.composer3.PowerMode mode);
   void setReadbackBuffer(long display, in android.hardware.common.NativeHandle buffer, in ParcelFileDescriptor releaseFence);
   void setVsyncEnabled(long display, boolean enabled);
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerCommand.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerCommand.aidl
new file mode 100644
index 0000000..bad72fc
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerCommand.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.graphics.composer3;
+@VintfStability
+parcelable LayerCommand {
+  long layer;
+  @nullable android.hardware.graphics.common.Point cursorPosition;
+  @nullable android.hardware.graphics.composer3.Buffer buffer;
+  @nullable android.hardware.graphics.common.Rect[] damage;
+  @nullable android.hardware.graphics.composer3.ParcelableBlendMode blendMode;
+  @nullable android.hardware.graphics.composer3.Color color;
+  @nullable android.hardware.graphics.composer3.FloatColor floatColor;
+  @nullable android.hardware.graphics.composer3.ParcelableComposition composition;
+  @nullable android.hardware.graphics.composer3.ParcelableDataspace dataspace;
+  @nullable android.hardware.graphics.common.Rect displayFrame;
+  @nullable android.hardware.graphics.composer3.PlaneAlpha planeAlpha;
+  @nullable android.hardware.common.NativeHandle sidebandStream;
+  @nullable android.hardware.graphics.common.FRect sourceCrop;
+  @nullable android.hardware.graphics.composer3.ParcelableTransform transform;
+  @nullable android.hardware.graphics.common.Rect[] visibleRegion;
+  @nullable android.hardware.graphics.composer3.ZOrder z;
+  @nullable float[] colorTransform;
+  @nullable android.hardware.graphics.composer3.WhitePointNits whitePointNits;
+  @nullable android.hardware.graphics.composer3.GenericMetadata genericMetadata;
+  @nullable android.hardware.graphics.composer3.PerFrameMetadata[] perFrameMetadata;
+  @nullable android.hardware.graphics.composer3.PerFrameMetadataBlob[] perFrameMetadataBlob;
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ParcelableBlendMode.aidl
similarity index 94%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ParcelableBlendMode.aidl
index cfafc50..f1fee5f 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ParcelableBlendMode.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum LayerRequest {
-  CLEAR_CLIENT_TARGET = 1,
+@VintfStability
+parcelable ParcelableBlendMode {
+  android.hardware.graphics.common.BlendMode blendMode;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ParcelableComposition.aidl
similarity index 93%
rename from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
rename to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ParcelableComposition.aidl
index a522d53..98fbb66 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ParcelableComposition.aidl
@@ -32,10 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum BlendMode {
-  INVALID = 0,
-  NONE = 1,
-  PREMULTIPLIED = 2,
-  COVERAGE = 3,
+@VintfStability
+parcelable ParcelableComposition {
+  android.hardware.graphics.composer3.Composition composition;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ParcelableDataspace.aidl
similarity index 94%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ParcelableDataspace.aidl
index cfafc50..76ecf85 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ParcelableDataspace.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum LayerRequest {
-  CLEAR_CLIENT_TARGET = 1,
+@VintfStability
+parcelable ParcelableDataspace {
+  android.hardware.graphics.common.Dataspace dataspace;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ParcelableTransform.aidl
similarity index 94%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ParcelableTransform.aidl
index cfafc50..b673656 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ParcelableTransform.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum LayerRequest {
-  CLEAR_CLIENT_TARGET = 1,
+@VintfStability
+parcelable ParcelableTransform {
+  android.hardware.graphics.common.Transform transform;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/PlaneAlpha.aidl
similarity index 95%
rename from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
rename to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/PlaneAlpha.aidl
index cfafc50..c48c2a8 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/PlaneAlpha.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum LayerRequest {
-  CLEAR_CLIENT_TARGET = 1,
+@VintfStability
+parcelable PlaneAlpha {
+  float alpha;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/PresentFence.aidl
similarity index 94%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/PresentFence.aidl
index cfafc50..3bb09cd 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/PresentFence.aidl
@@ -32,7 +32,8 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum LayerRequest {
-  CLEAR_CLIENT_TARGET = 1,
+@VintfStability
+parcelable PresentFence {
+  long display;
+  ParcelFileDescriptor fence;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/PresentOrValidate.aidl
similarity index 89%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/PresentOrValidate.aidl
index a522d53..3514e53 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/PresentOrValidate.aidl
@@ -32,10 +32,13 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum BlendMode {
-  INVALID = 0,
-  NONE = 1,
-  PREMULTIPLIED = 2,
-  COVERAGE = 3,
+@VintfStability
+parcelable PresentOrValidate {
+  long display;
+  android.hardware.graphics.composer3.PresentOrValidate.Result result;
+  @VintfStability
+  enum Result {
+    Presented = 0,
+    Validated = 1,
+  }
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ReleaseFences.aidl
similarity index 89%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ReleaseFences.aidl
index 41a1afe..d623661 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ReleaseFences.aidl
@@ -33,8 +33,12 @@
 
 package android.hardware.graphics.composer3;
 @VintfStability
-parcelable ExecuteCommandsStatus {
-  boolean queueChanged;
-  int length;
-  android.hardware.common.NativeHandle[] handles;
+parcelable ReleaseFences {
+  long display;
+  android.hardware.graphics.composer3.ReleaseFences.Layer[] layers;
+  @VintfStability
+  parcelable Layer {
+    long layer;
+    ParcelFileDescriptor fence;
+  }
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/WhitePointNits.aidl
similarity index 95%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/WhitePointNits.aidl
index cfafc50..c3925d2 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/WhitePointNits.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum LayerRequest {
-  CLEAR_CLIENT_TARGET = 1,
+@VintfStability
+parcelable WhitePointNits {
+  float nits;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ZOrder.aidl
similarity index 95%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ZOrder.aidl
index cfafc50..ea96ea3 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ZOrder.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum LayerRequest {
-  CLEAR_CLIENT_TARGET = 1,
+@VintfStability
+parcelable ZOrder {
+  int z;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/Buffer.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/Buffer.aidl
new file mode 100644
index 0000000..415a9b6
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/Buffer.aidl
@@ -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 android.hardware.graphics.composer3;
+
+import android.hardware.common.NativeHandle;
+
+@VintfStability
+parcelable Buffer {
+    /**
+     * Buffer slot in the range [0, bufferSlotCount) where bufferSlotCount is
+     * the parameter used when the layer was created.
+     * @see IComposer.createLayer.
+     * The slot is used as a buffer caching mechanism. When the Buffer.handle
+     * is null, the implementation uses the previous buffer associated with this
+     * slot.
+     */
+    int slot;
+
+    /**
+     * Buffer Handle. Can be null if this is the same buffer that was sent
+     * previously on this slot.
+     */
+    @nullable NativeHandle handle;
+
+    /**
+     * Buffer fence that represents when it is safe to access the buffer.
+     * A null fence indicates that the buffer can be accessed immediately.
+     */
+    @nullable ParcelFileDescriptor fence;
+}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/ChangedCompositionLayer.aidl
similarity index 69%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/composer/aidl/android/hardware/graphics/composer3/ChangedCompositionLayer.aidl
index 10de558..fb25163 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/ChangedCompositionLayer.aidl
@@ -16,16 +16,18 @@
 
 package android.hardware.graphics.composer3;
 
-/**
- * Layer requests returned from getDisplayRequests.
- */
+import android.hardware.graphics.composer3.Composition;
+
 @VintfStability
-@Backing(type="int")
-enum LayerRequest {
+parcelable ChangedCompositionLayer {
     /**
-     * The client must clear its target with transparent pixels where
-     * this layer would be. The client may ignore this request if the
-     * layer must be blended.
+     * The layer which this commands refers to.
+     * @see IComposer.createLayer
      */
-    CLEAR_CLIENT_TARGET = 1 << 0,
+    long layer;
+
+    /**
+     * The new composition type.
+     */
+    Composition composition;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/BlendMode.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/ChangedCompositionTypes.aidl
similarity index 66%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/BlendMode.aidl
copy to graphics/composer/aidl/android/hardware/graphics/composer3/ChangedCompositionTypes.aidl
index c6fd063..ddd45b7 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/ChangedCompositionTypes.aidl
@@ -16,23 +16,19 @@
 
 package android.hardware.graphics.composer3;
 
-/**
- * Blend modes, settable per layer.
- */
+import android.hardware.graphics.composer3.ChangedCompositionLayer;
+import android.hardware.graphics.composer3.Composition;
+
 @VintfStability
-@Backing(type="int")
-enum BlendMode {
-    INVALID = 0,
+parcelable ChangedCompositionTypes {
     /**
-     * colorOut = colorSrc
+     * The display which this commands refers to.
+     * @see IComposer.createDisplay
      */
-    NONE = 1,
+    long display;
+
     /**
-     * colorOut = colorSrc + colorDst * (1 - alphaSrc)
+     * Indicates which layers has composition changes
      */
-    PREMULTIPLIED = 2,
-    /**
-     * colorOut = colorSrc * alphaSrc + colorDst * (1 - alphaSrc)
-     */
-    COVERAGE = 3,
+    ChangedCompositionLayer[] layers;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/BlendMode.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/ClientTarget.aidl
similarity index 65%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/BlendMode.aidl
copy to graphics/composer/aidl/android/hardware/graphics/composer3/ClientTarget.aidl
index c6fd063..56488d5 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/ClientTarget.aidl
@@ -16,23 +16,24 @@
 
 package android.hardware.graphics.composer3;
 
-/**
- * Blend modes, settable per layer.
- */
+import android.hardware.graphics.common.Dataspace;
+import android.hardware.graphics.common.Rect;
+import android.hardware.graphics.composer3.Buffer;
+
 @VintfStability
-@Backing(type="int")
-enum BlendMode {
-    INVALID = 0,
+parcelable ClientTarget {
     /**
-     * colorOut = colorSrc
+     * Client target Buffer
      */
-    NONE = 1,
+    Buffer buffer;
+
     /**
-     * colorOut = colorSrc + colorDst * (1 - alphaSrc)
+     * The dataspace of the buffer, as described in LayerCommand.dataspace.
      */
-    PREMULTIPLIED = 2,
+    Dataspace dataspace;
+
     /**
-     * colorOut = colorSrc * alphaSrc + colorDst * (1 - alphaSrc)
+     * The surface damage regions.
      */
-    COVERAGE = 3,
+    Rect[] damage;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/ClientTargetPropertyWithNits.aidl
similarity index 64%
rename from graphics/composer/aidl/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
rename to graphics/composer/aidl/android/hardware/graphics/composer3/ClientTargetPropertyWithNits.aidl
index f67c3ce..5037651 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/ClientTargetPropertyWithNits.aidl
@@ -16,21 +16,23 @@
 
 package android.hardware.graphics.composer3;
 
-/**
- * Output parameters for IComposerClient.executeCommands
- */
+import android.hardware.graphics.composer3.ClientTargetProperty;
+
 @VintfStability
-parcelable ExecuteCommandsStatus {
+parcelable ClientTargetPropertyWithNits {
     /**
-     * Indicates whether the output command message queue has changed.
+     * The display which this commands refers to.
+     * @see IComposer.createDisplay
      */
-    boolean queueChanged;
+    long display;
+
     /**
-     * Indicates whether the output command message queue has changed.
+     * The Client target property.
      */
-    int length;
+    ClientTargetProperty clientTargetProperty;
+
     /**
-     * An array of handles referenced by the output commands.
+     * The white points nits as described in CommandResultPayload.clientTargetProperty
      */
-    android.hardware.common.NativeHandle[] handles;
+    float whitePointNits;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/BlendMode.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/ColorTransformPayload.aidl
similarity index 68%
rename from graphics/composer/aidl/android/hardware/graphics/composer3/BlendMode.aidl
rename to graphics/composer/aidl/android/hardware/graphics/composer3/ColorTransformPayload.aidl
index c6fd063..fc37dac 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/ColorTransformPayload.aidl
@@ -16,23 +16,18 @@
 
 package android.hardware.graphics.composer3;
 
-/**
- * Blend modes, settable per layer.
- */
+import android.hardware.graphics.common.ColorTransform;
+
 @VintfStability
-@Backing(type="int")
-enum BlendMode {
-    INVALID = 0,
+parcelable ColorTransformPayload {
     /**
-     * colorOut = colorSrc
+     * 4x4 transform matrix (16 floats) as described in DisplayCommand.colorTransform.
      */
-    NONE = 1,
+    float[] matrix;
+
     /**
-     * colorOut = colorSrc + colorDst * (1 - alphaSrc)
+     * Hint value which may be used instead of the given matrix unless it
+     * is ColorTransform.ARBITRARY.
      */
-    PREMULTIPLIED = 2,
-    /**
-     * colorOut = colorSrc * alphaSrc + colorDst * (1 - alphaSrc)
-     */
-    COVERAGE = 3,
+    ColorTransform hint;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/Command.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/Command.aidl
deleted file mode 100644
index 95c07ac..0000000
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/Command.aidl
+++ /dev/null
@@ -1,763 +0,0 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.graphics.composer3;
-
-import android.hardware.graphics.composer3.Command;
-
-/**
- * The command interface allows composer3 to reduce binder overhead by sending
- * atomic command stream in a command message queue. These commands are usually
- * sent on a per frame basic and contains the information that describes how the
- * display is composited. @see IComposerClient.executeCommands.
- */
-@VintfStability
-@Backing(type="int")
-enum Command {
-    LENGTH_MASK = 0xffff,
-    OPCODE_SHIFT = 16,
-    OPCODE_MASK = 0xffff << OPCODE_SHIFT,
-
-    // special commands
-
-    /**
-     * SELECT_DISPLAY has this pseudo prototype
-     *
-     *   selectDisplay(long display);
-     *
-     * Selects the current display implied by all other commands.
-     *
-     * @param display is the newly selected display.
-     */
-    SELECT_DISPLAY = 0x000 << OPCODE_SHIFT,
-
-    /**
-     * SELECT_LAYER has this pseudo prototype
-     *
-     *   selectLayer(long layer);
-     *
-     * Selects the current layer implied by all implicit layer commands.
-     *
-     * @param layer is the newly selected layer.
-     */
-    SELECT_LAYER = 0x001 << OPCODE_SHIFT,
-
-    // value commands (for return values)
-
-    /**
-     * SET_ERROR has this pseudo prototype
-     *
-     *   setError(uint32_t location, int error);
-     *
-     * Indicates an error generated by a command.
-     *
-     * @param location is the offset of the command in the input command
-     *        message queue.
-     * @param error is the error generated by the command.
-     */
-    SET_ERROR = 0x100 << OPCODE_SHIFT,
-
-    /**
-     * SET_CHANGED_COMPOSITION_TYPES has this pseudo prototype
-     *
-     *   setChangedCompositionTypes(long[] layers,
-     *                              Composition[] types);
-     *
-     * Sets the layers for which the device requires a different composition
-     * type than had been set prior to the last call to VALIDATE_DISPLAY. The
-     * client must either update its state with these types and call
-     * ACCEPT_DISPLAY_CHANGES, or must set new types and attempt to validate
-     * the display again.
-     *
-     * @param layers is an array of layer handles.
-     * @param types is an array of composition types, each corresponding to
-     *         an element of layers.
-     */
-    SET_CHANGED_COMPOSITION_TYPES = 0x101 << OPCODE_SHIFT,
-
-    /**
-     * SET_DISPLAY_REQUESTS has this pseudo prototype
-     *
-     *   setDisplayRequests(int displayRequestMask,
-     *                      long[] layers,
-     *                      int[] layerRequestMasks);
-     *
-     * Sets the display requests and the layer requests required for the last
-     * validated configuration.
-     *
-     * Display requests provide information about how the client must handle
-     * the client target. Layer requests provide information about how the
-     * client must handle an individual layer.
-     *
-     * @param displayRequestMask is the display requests for the current
-     *        validated state.
-     * @param layers is an array of layers which all have at least one
-     *        request.
-     * @param layerRequestMasks is the requests corresponding to each element
-     *        of layers.
-     */
-    SET_DISPLAY_REQUESTS = 0x102 << OPCODE_SHIFT,
-
-    /**
-     * SET_PRESENT_FENCE has this pseudo prototype
-     *
-     *   setPresentFence(int presentFenceIndex);
-     *
-     * Sets the present fence as a result of PRESENT_DISPLAY. For physical
-     * displays, this fence must be signaled at the vsync when the result
-     * of composition of this frame starts to appear (for video-mode panels)
-     * or starts to transfer to panel memory (for command-mode panels). For
-     * virtual displays, this fence must be signaled when writes to the output
-     * buffer have completed and it is safe to read from it.
-     *
-     * @param presentFenceIndex is an index into outHandles array.
-     */
-    SET_PRESENT_FENCE = 0x103 << OPCODE_SHIFT,
-
-    /**
-     * SET_RELEASE_FENCES has this pseudo prototype
-     *
-     *   setReleaseFences(long[] layers,
-     *                    int[] releaseFenceIndices);
-     *
-     * Sets the release fences for device layers on this display which will
-     * receive new buffer contents this frame.
-     *
-     * A release fence is a file descriptor referring to a sync fence object
-     * which must be signaled after the device has finished reading from the
-     * buffer presented in the prior frame. This indicates that it is safe to
-     * start writing to the buffer again. If a given layer's fence is not
-     * returned from this function, it must be assumed that the buffer
-     * presented on the previous frame is ready to be written.
-     *
-     * The fences returned by this function must be unique for each layer
-     * (even if they point to the same underlying sync object).
-     *
-     * @param layers is an array of layer handles.
-     * @param releaseFenceIndices are indices into outHandles array, each
-     *        corresponding to an element of layers.
-     */
-    SET_RELEASE_FENCES = 0x104 << OPCODE_SHIFT,
-
-    // display commands
-
-    /**
-     * SET_COLOR_TRANSFORM has this pseudo prototype
-     *
-     *   setColorTransform(float[16] matrix,
-     *                     ColorTransform hint);
-     *
-     * Sets a color transform which will be applied after composition.
-     *
-     * If hint is not ColorTransform::ARBITRARY, then the device may use the
-     * hint to apply the desired color transform instead of using the color
-     * matrix directly.
-     *
-     * If the device is not capable of either using the hint or the matrix to
-     * apply the desired color transform, it must force all layers to client
-     * composition during VALIDATE_DISPLAY.
-     *
-     * If IComposer::Capability::SKIP_CLIENT_COLOR_TRANSFORM is present, then
-     * the client must never apply the color transform during client
-     * composition, even if all layers are being composed by the client.
-     *
-     * The matrix provided is an affine color transformation of the following
-     * form:
-     *
-     * |r.r r.g r.b 0|
-     * |g.r g.g g.b 0|
-     * |b.r b.g b.b 0|
-     * |Tr  Tg  Tb  1|
-     *
-     * This matrix must be provided in row-major form:
-     *
-     * {r.r, r.g, r.b, 0, g.r, ...}.
-     *
-     * Given a matrix of this form and an input color [R_in, G_in, B_in], the
-     * output color [R_out, G_out, B_out] will be:
-     *
-     * R_out = R_in * r.r + G_in * g.r + B_in * b.r + Tr
-     * G_out = R_in * r.g + G_in * g.g + B_in * b.g + Tg
-     * B_out = R_in * r.b + G_in * g.b + B_in * b.b + Tb
-     *
-     * @param matrix is a 4x4 transform matrix (16 floats) as described above.
-     * @param hint is a hint value which may be used instead of the given
-     *        matrix unless it is ColorTransform::ARBITRARY.
-     */
-    SET_COLOR_TRANSFORM = 0x200 << OPCODE_SHIFT,
-
-    /**
-     * SET_CLIENT_TARGET has this pseudo prototype
-     *
-     *   setClientTarget(int targetSlot,
-     *                   int targetIndex,
-     *                   int acquireFenceIndex,
-     *                   android.hardware.graphics.common.Dataspace dataspace,
-     *                   Rect[] damage);
-     *
-     * Sets the buffer handle which will receive the output of client
-     * composition.  Layers marked as Composition::CLIENT must be composited
-     * into this buffer prior to the call to PRESENT_DISPLAY, and layers not
-     * marked as Composition::CLIENT must be composited with this buffer by
-     * the device.
-     *
-     * The buffer handle provided may be empty if no layers are being
-     * composited by the client. This must not result in an error (unless an
-     * invalid display handle is also provided).
-     *
-     * Also provides a file descriptor referring to an acquire sync fence
-     * object, which must be signaled when it is safe to read from the client
-     * target buffer.  If it is already safe to read from this buffer, an
-     * empty handle may be passed instead.
-     *
-     * For more about dataspaces, see SET_LAYER_DATASPACE.
-     *
-     * The damage parameter describes a surface damage region as defined in
-     * the description of SET_LAYER_SURFACE_DAMAGE.
-     *
-     * Will be called before PRESENT_DISPLAY if any of the layers are marked
-     * as Composition::CLIENT. If no layers are so marked, then it is not
-     * necessary to call this function. It is not necessary to call
-     * validateDisplay after changing the target through this function.
-     *
-     * @param targetSlot is the client target buffer slot to use.
-     * @param targetIndex is an index into inHandles for the new target
-     *        buffer.
-     * @param acquireFenceIndex is an index into inHandles for a sync fence
-     *        file descriptor as described above.
-     * @param dataspace is the dataspace of the buffer, as described in
-     *        setLayerDataspace.
-     * @param damage is the surface damage region.
-     *
-     */
-    SET_CLIENT_TARGET = 0x201 << OPCODE_SHIFT,
-
-    /**
-     * SET_OUTPUT_BUFFER has this pseudo prototype
-     *
-     *   setOutputBuffer(int bufferSlot,
-     *                   int bufferIndex,
-     *                   int releaseFenceIndex);
-     *
-     * Sets the output buffer for a virtual display. That is, the buffer to
-     * which the composition result will be written.
-     *
-     * Also provides a file descriptor referring to a release sync fence
-     * object, which must be signaled when it is safe to write to the output
-     * buffer. If it is already safe to write to the output buffer, an empty
-     * handle may be passed instead.
-     *
-     * Must be called at least once before PRESENT_DISPLAY, but does not have
-     * any interaction with layer state or display validation.
-     *
-     * @param bufferSlot is the new output buffer.
-     * @param bufferIndex is the new output buffer.
-     * @param releaseFenceIndex is a sync fence file descriptor as described
-     *        above.
-     */
-    SET_OUTPUT_BUFFER = 0x202 << OPCODE_SHIFT,
-
-    /**
-     * VALIDATE_DISPLAY has this pseudo prototype
-     *
-     *   validateDisplay();
-     *
-     * Instructs the device to inspect all of the layer state and determine if
-     * there are any composition type changes necessary before presenting the
-     * display. Permitted changes are described in the definition of
-     * Composition above.
-     */
-    VALIDATE_DISPLAY = 0x203 << OPCODE_SHIFT,
-
-    /**
-     * ACCEPT_DISPLAY_CHANGES has this pseudo prototype
-     *
-     *   acceptDisplayChanges();
-     *
-     * Accepts the changes required by the device from the previous
-     * validateDisplay call (which may be queried using
-     * getChangedCompositionTypes) and revalidates the display. This function
-     * is equivalent to requesting the changed types from
-     * getChangedCompositionTypes, setting those types on the corresponding
-     * layers, and then calling validateDisplay again.
-     *
-     * After this call it must be valid to present this display. Calling this
-     * after validateDisplay returns 0 changes must succeed with NONE, but
-     * must have no other effect.
-     */
-    ACCEPT_DISPLAY_CHANGES = 0x204 << OPCODE_SHIFT,
-
-    /**
-     * PRESENT_DISPLAY has this pseudo prototype
-     *
-     *   presentDisplay();
-     *
-     * Presents the current display contents on the screen (or in the case of
-     * virtual displays, into the output buffer).
-     *
-     * Prior to calling this function, the display must be successfully
-     * validated with validateDisplay. Note that setLayerBuffer and
-     * setLayerSurfaceDamage specifically do not count as layer state, so if
-     * there are no other changes to the layer state (or to the buffer's
-     * properties as described in setLayerBuffer), then it is safe to call
-     * this function without first validating the display.
-     */
-    PRESENT_DISPLAY = 0x205 << OPCODE_SHIFT,
-
-    /**
-     * PRESENT_OR_VALIDATE_DISPLAY has this pseudo prototype
-     *
-     *   presentOrValidateDisplay();
-     *
-     * Presents the current display contents on the screen (or in the case of
-     * virtual displays, into the output buffer) if validate can be skipped,
-     * or perform a VALIDATE_DISPLAY action instead.
-     */
-    PRESENT_OR_VALIDATE_DISPLAY = 0x206 << OPCODE_SHIFT,
-
-    // layer commands (VALIDATE_DISPLAY not required)
-
-    /**
-     * SET_LAYER_CURSOR_POSITION has this pseudo prototype
-     *
-     *   setLayerCursorPosition(int x, int y);
-     *
-     * Asynchronously sets the position of a cursor layer.
-     *
-     * Prior to validateDisplay, a layer may be marked as Composition::CURSOR.
-     * If validation succeeds (i.e., the device does not request a composition
-     * change for that layer), then once a buffer has been set for the layer
-     * and it has been presented, its position may be set by this function at
-     * any time between presentDisplay and any subsequent validateDisplay
-     * calls for this display.
-     *
-     * Once validateDisplay is called, this function must not be called again
-     * until the validate/present sequence is completed.
-     *
-     * May be called from any thread so long as it is not interleaved with the
-     * validate/present sequence as described above.
-     *
-     * @param layer is the layer to which the position is set.
-     * @param x is the new x coordinate (in pixels from the left of the
-     *        screen).
-     * @param y is the new y coordinate (in pixels from the top of the
-     *        screen).
-     */
-    SET_LAYER_CURSOR_POSITION = 0x300 << OPCODE_SHIFT,
-
-    /**
-     * SET_LAYER_BUFFER has this pseudo prototype
-     *
-     *   setLayerBuffer(int bufferSlot,
-     *                  int bufferIndex,
-     *                  int acquireFenceIndex);
-     *
-     * Sets the buffer handle to be displayed for this layer. If the buffer
-     * properties set at allocation time (width, height, format, and usage)
-     * have not changed since the previous frame, it is not necessary to call
-     * validateDisplay before calling presentDisplay unless new state needs to
-     * be validated in the interim.
-     *
-     * Also provides a file descriptor referring to an acquire sync fence
-     * object, which must be signaled when it is safe to read from the given
-     * buffer. If it is already safe to read from the buffer, an empty handle
-     * may be passed instead.
-     *
-     * This function must return NONE and have no other effect if called for a
-     * layer with a composition type of Composition::SOLID_COLOR (because it
-     * has no buffer) or Composition::SIDEBAND or Composition::CLIENT (because
-     * synchronization and buffer updates for these layers are handled
-     * elsewhere).
-     *
-     * @param layer is the layer to which the buffer is set.
-     * @param bufferSlot is the buffer slot to use.
-     * @param bufferIndex is the buffer handle to set.
-     * @param acquireFenceIndex is a sync fence file descriptor as described above.
-     */
-    SET_LAYER_BUFFER = 0x301 << OPCODE_SHIFT,
-
-    /*
-     * SET_LAYER_SURFACE_DAMAGE has this pseudo prototype
-     *
-     *   setLayerSurfaceDamage(Rect[] damage);
-     *
-     * Provides the region of the source buffer which has been modified since
-     * the last frame. This region does not need to be validated before
-     * calling presentDisplay.
-     *
-     * Once set through this function, the damage region remains the same
-     * until a subsequent call to this function.
-     *
-     * If damage is non-empty, then it may be assumed that any portion of the
-     * source buffer not covered by one of the rects has not been modified
-     * this frame. If damage is empty, then the whole source buffer must be
-     * treated as if it has been modified.
-     *
-     * If the layer's contents are not modified relative to the prior frame,
-     * damage must contain exactly one empty rect([0, 0, 0, 0]).
-     *
-     * The damage rects are relative to the pre-transformed buffer, and their
-     * origin is the top-left corner. They must not exceed the dimensions of
-     * the latched buffer.
-     *
-     * @param layer is the layer to which the damage region is set.
-     * @param damage is the new surface damage region.
-     */
-    SET_LAYER_SURFACE_DAMAGE = 0x302 << OPCODE_SHIFT,
-
-    // layer state commands (VALIDATE_DISPLAY required)
-
-    /**
-     * SET_LAYER_BLEND_MODE has this pseudo prototype
-     *
-     *   setLayerBlendMode(android.hardware.graphics.common.BlendMode mode)
-     *
-     * Sets the blend mode of the given layer.
-     *
-     * @param mode is the new blend mode.
-     */
-    SET_LAYER_BLEND_MODE = 0x400 << OPCODE_SHIFT,
-
-    /**
-     * SET_LAYER_COLOR has this pseudo prototype
-     *
-     *   setLayerColor(Color color);
-     *
-     * Sets the color of the given layer. If the composition type of the layer
-     * is not Composition::SOLID_COLOR, this call must succeed and have no
-     * other effect.
-     *
-     * @param color is the new color.
-     */
-    SET_LAYER_COLOR = 0x401 << OPCODE_SHIFT,
-
-    /**
-     * SET_LAYER_COMPOSITION_TYPE has this pseudo prototype
-     *
-     *   setLayerCompositionType(Composition type);
-     *
-     * Sets the desired composition type of the given layer. During
-     * validateDisplay, the device may request changes to the composition
-     * types of any of the layers as described in the definition of
-     * Composition above.
-     *
-     * @param type is the new composition type.
-     */
-    SET_LAYER_COMPOSITION_TYPE = 0x402 << OPCODE_SHIFT,
-
-    /**
-     * SET_LAYER_DATASPACE has this pseudo prototype
-     *
-     *   setLayerDataspace(android.hardware.graphics.common.Dataspace dataspace);
-     *
-     * Sets the dataspace of the layer.
-     *
-     * The dataspace provides more information about how to interpret the buffer
-     * or solid color, such as the encoding standard and color transform.
-     *
-     * See the values of Dataspace for more information.
-     *
-     * @param dataspace is the new dataspace.
-     */
-    SET_LAYER_DATASPACE = 0x403 << OPCODE_SHIFT,
-
-    /**
-     * SET_LAYER_DISPLAY_FRAME has this pseudo prototype
-     *
-     *   setLayerDisplayFrame(Rect frame);
-     *
-     * Sets the display frame (the portion of the display covered by a layer)
-     * of the given layer. This frame must not exceed the display dimensions.
-     *
-     * @param frame is the new display frame.
-     */
-    SET_LAYER_DISPLAY_FRAME = 0x404 << OPCODE_SHIFT,
-
-    /**
-     * SET_LAYER_PLANE_ALPHA has this pseudo prototype
-     *
-     *   setLayerPlaneAlpha(float alpha);
-     *
-     * Sets an alpha value (a floating point value in the range [0.0, 1.0])
-     * which will be applied to the whole layer. It can be conceptualized as a
-     * preprocessing step which applies the following function:
-     *   if (blendMode == BlendMode::PREMULTIPLIED)
-     *       out.rgb = in.rgb * planeAlpha
-     *   out.a = in.a * planeAlpha
-     *
-     * If the device does not support this operation on a layer which is
-     * marked Composition::DEVICE, it must request a composition type change
-     * to Composition::CLIENT upon the next validateDisplay call.
-     *
-     * @param alpha is the plane alpha value to apply.
-     */
-    SET_LAYER_PLANE_ALPHA = 0x405 << OPCODE_SHIFT,
-
-    /**
-     * SET_LAYER_SIDEBAND_STREAM has this pseudo prototype
-     *
-     *   setLayerSidebandStream(int streamIndex)
-     *
-     * Sets the sideband stream for this layer. If the composition type of the
-     * given layer is not Composition::SIDEBAND, this call must succeed and
-     * have no other effect.
-     *
-     * @param streamIndex is the new sideband stream.
-     */
-    SET_LAYER_SIDEBAND_STREAM = 0x406 << OPCODE_SHIFT,
-
-    /**
-     * SET_LAYER_SOURCE_CROP has this pseudo prototype
-     *
-     *   setLayerSourceCrop(FRect crop);
-     *
-     * Sets the source crop (the portion of the source buffer which will fill
-     * the display frame) of the given layer. This crop rectangle must not
-     * exceed the dimensions of the latched buffer.
-     *
-     * If the device is not capable of supporting a true float source crop
-     * (i.e., it will truncate or round the floats to integers), it must set
-     * this layer to Composition::CLIENT when crop is non-integral for the
-     * most accurate rendering.
-     *
-     * If the device cannot support float source crops, but still wants to
-     * handle the layer, it must use the following code (or similar) to
-     * convert to an integer crop:
-     *   intCrop.left = (int) ceilf(crop.left);
-     *   intCrop.top = (int) ceilf(crop.top);
-     *   intCrop.right = (int) floorf(crop.right);
-     *   intCrop.bottom = (int) floorf(crop.bottom);
-     *
-     * @param crop is the new source crop.
-     */
-    SET_LAYER_SOURCE_CROP = 0x407 << OPCODE_SHIFT,
-
-    /**
-     * SET_LAYER_TRANSFORM has this pseudo prototype
-     *
-     * Sets the transform (rotation/flip) of the given layer.
-     *
-     *   setLayerTransform(Transform transform);
-     *
-     * @param transform is the new transform.
-     */
-    SET_LAYER_TRANSFORM = 0x408 << OPCODE_SHIFT,
-
-    /**
-     * SET_LAYER_VISIBLE_REGION has this pseudo prototype
-     *
-     *   setLayerVisibleRegion(Rect[] visible);
-     *
-     * Specifies the portion of the layer that is visible, including portions
-     * under translucent areas of other layers. The region is in screen space,
-     * and must not exceed the dimensions of the screen.
-     *
-     * @param visible is the new visible region, in screen space.
-     */
-    SET_LAYER_VISIBLE_REGION = 0x409 << OPCODE_SHIFT,
-
-    /**
-     * SET_LAYER_Z_ORDER has this pseudo prototype
-     *
-     *   setLayerZOrder(int z);
-     *
-     * Sets the desired Z order (height) of the given layer. A layer with a
-     * greater Z value occludes a layer with a lesser Z value.
-     *
-     * @param z is the new Z order.
-     */
-    SET_LAYER_Z_ORDER = 0x40a << OPCODE_SHIFT,
-
-    /**
-     * SET_PRESENT_OR_VALIDATE_DISPLAY_RESULT has this pseudo prototype
-     *
-     * setPresentOrValidateDisplayResult(int state);
-     *
-     * Sets the state of PRESENT_OR_VALIDATE_DISPLAY command.
-     * @param state is the state of present or validate
-     *    1 - Present Succeeded
-     *    0 - Validate succeeded
-     */
-    SET_PRESENT_OR_VALIDATE_DISPLAY_RESULT = 0x40b << OPCODE_SHIFT,
-
-    /**
-     * SET_LAYER_PER_FRAME_METADATA has this pseudo prototype
-     *
-     *   setLayerPerFrameMetadata(long display, long layer,
-     *                            PerFrameMetadata[] data);
-     *
-     * Sets the PerFrameMetadata for the display. This metadata must be used
-     * by the implementation to better tone map content to that display.
-     *
-     * This is a method that may be called every frame. Thus it's
-     * implemented using buffered transport.
-     * SET_LAYER_PER_FRAME_METADATA is the command used by the buffered transport
-     * mechanism.
-     */
-    SET_LAYER_PER_FRAME_METADATA = 0x303 << OPCODE_SHIFT,
-
-    /**
-     * SET_LAYER_FLOAT_COLOR has this pseudo prototype
-     *
-     *   setLayerColor(FloatColor color);
-     *
-     * Sets the color of the given layer. If the composition type of the layer
-     * is not Composition::SOLID_COLOR, this call must succeed and have no
-     * other effect.
-     *
-     * @param color is the new color using float type.
-     */
-    SET_LAYER_FLOAT_COLOR = 0x40c << OPCODE_SHIFT,
-
-    /**
-     * SET_LAYER_COLOR_TRANSFORM has this pseudo prototype
-     *
-     *   setLayerColorTransform(float[16] matrix);
-     *
-     * This command has the following binary layout in bytes:
-     *
-     *     0 - 16 * 4: matrix
-     *
-     * Sets a matrix for color transform which will be applied on this layer
-     * before composition.
-     *
-     * If the device is not capable of apply the matrix on this layer, it must force
-     * this layer to client composition during VALIDATE_DISPLAY.
-     *
-     * The matrix provided is an affine color transformation of the following
-     * form:
-     *
-     * |r.r r.g r.b 0|
-     * |g.r g.g g.b 0|
-     * |b.r b.g b.b 0|
-     * |Tr  Tg  Tb  1|
-     *
-     * This matrix must be provided in row-major form:
-     *
-     * {r.r, r.g, r.b, 0, g.r, ...}.
-     *
-     * Given a matrix of this form and an input color [R_in, G_in, B_in],
-     * the input color must first be converted to linear space
-     * [R_linear, G_linear, B_linear], then the output linear color
-     * [R_out_linear, G_out_linear, B_out_linear] will be:
-     *
-     * R_out_linear = R_linear * r.r + G_linear * g.r + B_linear * b.r + Tr
-     * G_out_linear = R_linear * r.g + G_linear * g.g + B_linear * b.g + Tg
-     * B_out_linear = R_linear * r.b + G_linear * g.b + B_linear * b.b + Tb
-     *
-     * [R_out_linear, G_out_linear, B_out_linear] must then be converted to
-     * gamma space: [R_out, G_out, B_out] before blending.
-     *
-     * @param matrix is a 4x4 transform matrix (16 floats) as described above.
-     */
-
-    SET_LAYER_COLOR_TRANSFORM = 0x40d << OPCODE_SHIFT,
-    /*
-     * SET_LAYER_PER_FRAME_METADATA_BLOBS has this pseudo prototype
-     *
-     *   setLayerPerFrameMetadataBlobs(long display, long layer,
-     *                                   PerFrameMetadataBlob[] metadata);
-     *
-     *   This command sends metadata that may be used for tone-mapping the
-     *   associated layer.  The metadata structure follows a {key, blob}
-     *   format (see the PerFrameMetadataBlob struct).  All keys must be
-     *   returned by a prior call to getPerFrameMetadataKeys and must
-     *   be part of the list of keys associated with blob-type metadata
-     *   (see PerFrameMetadataKey).
-     *
-     *   This method may be called every frame.
-     */
-    SET_LAYER_PER_FRAME_METADATA_BLOBS = 0x304 << OPCODE_SHIFT,
-
-    /**
-     * SET_CLIENT_TARGET_PROPERTY has this pseudo prototype
-     *
-     * This command has the following binary layout in bytes:
-     *
-     *     0 - 3: clientTargetProperty.pixelFormat
-     *     4 - 7: clientTargetProperty.dataspace
-     *     8 - 11: whitePointNits
-     *
-     * The white point parameter describes the intended white point of the client target buffer.
-     * When client composition blends both HDR and SDR content, the client must composite to the
-     * brightness space as specified by the hardware composer. This is so that adjusting the real
-     * display brightness may be applied atomically with compensating the client target output. For
-     * instance, client-compositing a list of SDR layers requires dimming the brightness space of
-     * the SDR buffers when an HDR layer is simultaneously device-composited.
-     *
-     *   setClientTargetProperty(ClientTargetProperty clientTargetProperty, float whitePointNits);
-     */
-    SET_CLIENT_TARGET_PROPERTY = 0x105 << OPCODE_SHIFT,
-
-    /**
-     * SET_LAYER_GENERIC_METADATA has this pseudo prototype
-     *
-     *   setLayerGenericMetadata(string key, bool mandatory, byte[] value);
-     *
-     * Sets a piece of generic metadata for the given layer. If this
-     * function is called twice with the same key but different values, the
-     * newer value must override the older one. Calling this function with a
-     * 0-length value must reset that key's metadata as if it had not been
-     * set.
-     *
-     * A given piece of metadata may either be mandatory or a hint
-     * (non-mandatory) as indicated by the second parameter. Mandatory
-     * metadata may affect the composition result, which is to say that it
-     * may cause a visible change in the final image. By contrast, hints may
-     * only affect the composition strategy, such as which layers are
-     * composited by the client, but must not cause a visible change in the
-     * final image. The value of the mandatory flag shall match the value
-     * returned from getLayerGenericMetadataKeys for the given key.
-     *
-     * Only keys which have been returned from getLayerGenericMetadataKeys()
-     * shall be accepted. Any other keys must result in an UNSUPPORTED error.
-     *
-     * The value passed into this function shall be the binary
-     * representation of a HIDL type corresponding to the given key. For
-     * example, a key of 'com.example.V1_3.Foo' shall be paired with a
-     * value of type com.example@1.3::Foo, which would be defined in a
-     * vendor HAL extension.
-     *
-     * This function will be encoded in the command buffer in this order:
-     *   1) The key length, stored as a uint32_t
-     *   2) The key itself, padded to a uint32_t boundary if necessary
-     *   3) The mandatory flag, stored as a uint32_t
-     *   4) The value length in bytes, stored as a uint32_t
-     *   5) The value itself, padded to a uint32_t boundary if necessary
-     *
-     * @param key indicates which metadata value should be set on this layer
-     * @param mandatory indicates whether this particular key represents
-     *        mandatory metadata or a hint (non-mandatory metadata), as
-     *        described above
-     * @param value is a binary representation of a HIDL struct
-     *        corresponding to the key as described above
-     */
-    SET_LAYER_GENERIC_METADATA = 0x40e << OPCODE_SHIFT,
-
-    /**
-     * SET_LAYER_WHITE_POINT_NITS has this pseudo prototype
-     *
-     *   setLayerWhitePointNits(float sdrWhitePointNits);
-     *
-     * Sets the desired white point for the layer. This is intended to be used when presenting
-     * an SDR layer alongside HDR content. The HDR content will be presented at the display
-     * brightness in nits, and accordingly SDR content shall be dimmed to the desired white point
-     * provided.
-     *
-     * @param whitePointNits is the white point in nits.
-     */
-    SET_LAYER_WHITE_POINT_NITS = 0x305 << OPCODE_SHIFT,
-}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/CommandError.aidl
similarity index 69%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/composer/aidl/android/hardware/graphics/composer3/CommandError.aidl
index 10de558..ea48600 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/CommandError.aidl
@@ -16,16 +16,14 @@
 
 package android.hardware.graphics.composer3;
 
-/**
- * Layer requests returned from getDisplayRequests.
- */
 @VintfStability
-@Backing(type="int")
-enum LayerRequest {
+parcelable CommandError {
     /**
-     * The client must clear its target with transparent pixels where
-     * this layer would be. The client may ignore this request if the
-     * layer must be blended.
+     * The index in the command payload array.
      */
-    CLEAR_CLIENT_TARGET = 1 << 0,
+    int commandIndex;
+    /**
+     * The error generated by the command. Can be one of the IComposerClient.EX_*
+     */
+    int errorCode;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/CommandResultPayload.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/CommandResultPayload.aidl
new file mode 100644
index 0000000..f2de68e
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/CommandResultPayload.aidl
@@ -0,0 +1,94 @@
+/**
+ * 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.graphics.composer3;
+
+import android.hardware.graphics.composer3.ChangedCompositionTypes;
+import android.hardware.graphics.composer3.ClientTargetPropertyWithNits;
+import android.hardware.graphics.composer3.CommandError;
+import android.hardware.graphics.composer3.DisplayRequest;
+import android.hardware.graphics.composer3.PresentFence;
+import android.hardware.graphics.composer3.PresentOrValidate;
+import android.hardware.graphics.composer3.ReleaseFences;
+
+@VintfStability
+union CommandResultPayload {
+    /**
+     * Indicates an error generated by a command.
+     */
+    CommandError error;
+
+    /**
+     * Sets the layers for which the device requires a different composition
+     * type than had been set prior to the last call to VALIDATE_DISPLAY. The
+     * client must either update its state with these types and call
+     * ACCEPT_DISPLAY_CHANGES, or must set new types and attempt to validate
+     * the display again.
+     */
+    ChangedCompositionTypes changedCompositionTypes;
+
+    /**
+     * Sets the display requests and the layer requests required for the last
+     * validated configuration.
+     *
+     * Display requests provide information about how the client must handle
+     * the client target. Layer requests provide information about how the
+     * client must handle an individual layer.
+     */
+    DisplayRequest displayRequest;
+
+    /**
+     * Sets the present fence as a result of PRESENT_DISPLAY. For physical
+     * displays, this fence must be signaled at the vsync when the result
+     * of composition of this frame starts to appear (for video-mode panels)
+     * or starts to transfer to panel memory (for command-mode panels). For
+     * virtual displays, this fence must be signaled when writes to the output
+     * buffer have completed and it is safe to read from it.
+     */
+    PresentFence presentFence;
+
+    /**
+     * Sets the release fences for device layers on this display which will
+     * receive new buffer contents this frame.
+     *
+     * A release fence is a file descriptor referring to a sync fence object
+     * which must be signaled after the device has finished reading from the
+     * buffer presented in the prior frame. This indicates that it is safe to
+     * start writing to the buffer again. If a given layer's fence is not
+     * returned from this function, it must be assumed that the buffer
+     * presented on the previous frame is ready to be written.
+     *
+     * The fences returned by this function must be unique for each layer
+     * (even if they point to the same underlying sync object).
+     *
+     */
+    ReleaseFences releaseFences;
+
+    /**
+     * Sets the state of PRESENT_OR_VALIDATE_DISPLAY command.
+     */
+    PresentOrValidate presentOrValidateResult;
+
+    /**
+     * The white point parameter describes the intended white point of the client target buffer.
+     * When client composition blends both HDR and SDR content, the client must composite to the
+     * brightness space as specified by the hardware composer. This is so that adjusting the real
+     * display brightness may be applied atomically with compensating the client target output. For
+     * instance, client-compositing a list of SDR layers requires dimming the brightness space of
+     * the SDR buffers when an HDR layer is simultaneously device-composited.
+     */
+    ClientTargetPropertyWithNits clientTargetProperty;
+}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/Composition.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/Composition.aidl
index ea22af2..4947463 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/Composition.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/Composition.aidl
@@ -66,11 +66,24 @@
     /**
      * The device must handle the composition of this layer, as well as
      * its buffer updates and content synchronization. Only supported on
-     * devices which provide Capability::SIDEBAND_STREAM.
+     * devices which provide Capability.SIDEBAND_STREAM.
      *
      * Upon validateDisplay, the device may request a change from this
      * type to either DEVICE or CLIENT, but it is unlikely that content
      * will display correctly in these cases.
      */
     SIDEBAND = 5,
+    /**
+     * A display decoration layer contains a buffer which is an 8 bit
+     * alpha mask. Pixels in the mask with an alpha of 0 (transparent) will
+     * show the content underneath, and pixels with an alpha of 255 will be
+     * be rendered in black. An alpha in between will show the content
+     * blended with black. This is useful, for example, to provide
+     * anti-aliasing on the cutout region/rounded corners on the top and
+     * bottom of a display.
+     *
+     * Upon validateDisplay, the device may request a change from this type
+     * to CLIENT.
+     */
+    DISPLAY_DECORATION = 6,
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCapability.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCapability.aidl
index 54f09c1..eacf106 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCapability.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCapability.aidl
@@ -41,14 +41,15 @@
      */
     SKIP_CLIENT_COLOR_TRANSFORM = 1,
     /**
-     * Indicates that the display supports PowerMode::DOZE and
-     * PowerMode::DOZE_SUSPEND. DOZE_SUSPEND may not provide any benefit
+     * Indicates that the display supports PowerMode.DOZE and
+     * potentially PowerMode.DOZE_SUSPEND if DisplayCapability.SUSPEND is also
+     * supported. DOZE_SUSPEND may not provide any benefit
      * over DOZE (see the definition of PowerMode for more information),
      * but if both DOZE and DOZE_SUSPEND are no different from
-     * PowerMode::ON, the device must not claim support.
+     * PowerMode.ON, the device must not claim support.
      * Must be returned by getDisplayCapabilities when getDozeSupport
-     * indicates the display supports PowerMode::DOZE and
-     * PowerMode::DOZE_SUSPEND.
+     * indicates the display supports PowerMode.DOZE and
+     * PowerMode.DOZE_SUSPEND.
      */
     DOZE = 2,
     /**
@@ -66,4 +67,12 @@
      * support a low latency mode, such as HDMI 2.1 Auto Low Latency Mode.
      */
     AUTO_LOW_LATENCY_MODE = 5,
+    /**
+     * Indicates that the display supports PowerMode.ON_SUSPEND.
+     * If PowerMode.ON_SUSPEND is no different from PowerMode.ON, the device must not
+     * claim support.
+     * If the display supports DisplayCapability.DOZE and DisplayCapability.SUSPEND, then
+     * PowerMode.ON_SUSPEND and PowerMode.DOZE_SUSPEND must be supported.
+     */
+    SUSPEND = 6,
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCommand.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCommand.aidl
new file mode 100644
index 0000000..21497c4
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCommand.aidl
@@ -0,0 +1,158 @@
+/**
+ * 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.graphics.composer3;
+
+import android.hardware.graphics.composer3.Buffer;
+import android.hardware.graphics.composer3.ClientTarget;
+import android.hardware.graphics.composer3.ColorTransformPayload;
+import android.hardware.graphics.composer3.LayerCommand;
+
+@VintfStability
+parcelable DisplayCommand {
+    /**
+     * The display which this commands refers to.
+     * @see IComposer.createDisplay
+     */
+    long display;
+
+    /**
+     * Sets layer commands for this display.
+     * @see LayerCommand.
+     */
+    LayerCommand[] layers;
+
+    /**
+     * Sets a color transform which will be applied after composition.
+     *
+     * If hint is not ColorTransform.ARBITRARY, then the device may use the
+     * hint to apply the desired color transform instead of using the color
+     * matrix directly.
+     *
+     * If the device is not capable of either using the hint or the matrix to
+     * apply the desired color transform, it must force all layers to client
+     * composition during VALIDATE_DISPLAY.
+     *
+     * If Capability.SKIP_CLIENT_COLOR_TRANSFORM is present, then
+     * the client must never apply the color transform during client
+     * composition, even if all layers are being composed by the client.
+     *
+     * The matrix provided is an affine color transformation of the following
+     * form:
+     *
+     * |r.r r.g r.b 0|
+     * |g.r g.g g.b 0|
+     * |b.r b.g b.b 0|
+     * |Tr  Tg  Tb  1|
+     *
+     * This matrix must be provided in row-major form:
+     *
+     * {r.r, r.g, r.b, 0, g.r, ...}.
+     *
+     * Given a matrix of this form and an input color [R_in, G_in, B_in], the
+     * output color [R_out, G_out, B_out] will be:
+     *
+     * R_out = R_in * r.r + G_in * g.r + B_in * b.r + Tr
+     * G_out = R_in * r.g + G_in * g.g + B_in * b.g + Tg
+     * B_out = R_in * r.b + G_in * g.b + B_in * b.b + Tb
+     *
+     */
+    @nullable ColorTransformPayload colorTransform;
+
+    /**
+     * Sets the buffer handle which will receive the output of client
+     * composition.  Layers marked as Composition.CLIENT must be composited
+     * into this buffer prior to the call to PRESENT_DISPLAY, and layers not
+     * marked as Composition.CLIENT must be composited with this buffer by
+     * the device.
+     *
+     * The buffer handle provided may be empty if no layers are being
+     * composited by the client. This must not result in an error (unless an
+     * invalid display handle is also provided).
+     *
+     * Also provides a file descriptor referring to an acquire sync fence
+     * object, which must be signaled when it is safe to read from the client
+     * target buffer.  If it is already safe to read from this buffer, an
+     * empty handle may be passed instead.
+     *
+     * For more about dataspaces, see SET_LAYER_DATASPACE.
+     *
+     * The damage parameter describes a surface damage region as defined in
+     * the description of SET_LAYER_SURFACE_DAMAGE.
+     *
+     * Will be called before PRESENT_DISPLAY if any of the layers are marked
+     * as Composition.CLIENT. If no layers are so marked, then it is not
+     * necessary to call this function. It is not necessary to call
+     * validateDisplay after changing the target through this function.
+     */
+    @nullable ClientTarget clientTarget;
+
+    /**
+     * Sets the output buffer for a virtual display. That is, the buffer to
+     * which the composition result will be written.
+     *
+     * Also provides a file descriptor referring to a release sync fence
+     * object, which must be signaled when it is safe to write to the output
+     * buffer. If it is already safe to write to the output buffer, an empty
+     * handle may be passed instead.
+     *
+     * Must be called at least once before PRESENT_DISPLAY, but does not have
+     * any interaction with layer state or display validation.
+     */
+    @nullable Buffer virtualDisplayOutputBuffer;
+
+    /**
+     * Instructs the device to inspect all of the layer state and determine if
+     * there are any composition type changes necessary before presenting the
+     * display. Permitted changes are described in the definition of
+     * Composition above.
+     */
+    boolean validateDisplay;
+
+    /**
+     * Accepts the changes required by the device from the previous
+     * validateDisplay call (which may be queried using
+     * getChangedCompositionTypes) and revalidates the display. This function
+     * is equivalent to requesting the changed types from
+     * getChangedCompositionTypes, setting those types on the corresponding
+     * layers, and then calling validateDisplay again.
+     *
+     * After this call it must be valid to present this display. Calling this
+     * after validateDisplay returns 0 changes must succeed with NONE, but
+     * must have no other effect.
+     */
+    boolean acceptDisplayChanges;
+
+    /**
+     * Presents the current display contents on the screen (or in the case of
+     * virtual displays, into the output buffer).
+     *
+     * Prior to calling this function, the display must be successfully
+     * validated with validateDisplay. Note that setLayerBuffer and
+     * setLayerSurfaceDamage specifically do not count as layer state, so if
+     * there are no other changes to the layer state (or to the buffer's
+     * properties as described in setLayerBuffer), then it is safe to call
+     * this function without first validating the display.
+     */
+    boolean presentDisplay;
+
+    /**
+     * Presents the current display contents on the screen (or in the case of
+     * virtual displays, into the output buffer) if validate can be skipped,
+     * or perform a VALIDATE_DISPLAY action instead.
+     */
+    boolean presentOrValidateDisplay;
+}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayRequest.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayRequest.aidl
index 4b3d31a..27fe1e6 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayRequest.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayRequest.aidl
@@ -16,22 +16,57 @@
 
 package android.hardware.graphics.composer3;
 
-/**
- * Display requests returned by getDisplayRequests.
- */
 @VintfStability
-@Backing(type="int")
-enum DisplayRequest {
+parcelable DisplayRequest {
     /**
      * Instructs the client to provide a new client target buffer, even if
      * no layers are marked for client composition.
      */
-    FLIP_CLIENT_TARGET = 1 << 0,
+    const int FLIP_CLIENT_TARGET = 1 << 0;
+
     /**
      * Instructs the client to write the result of client composition
      * directly into the virtual display output buffer. If any of the
-     * layers are not marked as Composition::CLIENT or the given display
+     * layers are not marked as Composition.CLIENT or the given display
      * is not a virtual display, this request has no effect.
      */
-    WRITE_CLIENT_TARGET_TO_OUTPUT = 1 << 1,
+    const int WRITE_CLIENT_TARGET_TO_OUTPUT = 1 << 1;
+
+    /**
+     * The display which this commands refers to.
+     * @see IComposer.createDisplay
+     */
+    long display;
+
+    /**
+     * The display requests for the current validated state. This must be a
+     * bitwise-or of the constants in `DisplayRequest`.
+     */
+    int mask;
+
+    @VintfStability
+    parcelable LayerRequest {
+        /**
+         * The client must clear its target with transparent pixels where
+         * this layer would be. The client may ignore this request if the
+         * layer must be blended.
+         */
+        const int CLEAR_CLIENT_TARGET = 1 << 0;
+
+        /**
+         * The layer which this commands refers to.
+         * @see IComposer.createLayer
+         */
+        long layer;
+        /**
+         * The layer requests for the current validated state. This must be a
+         * bitwise-or of the constants in `LayerRequest`.
+         */
+        int mask;
+    }
+
+    /**
+     * The layer requests for the current validated state.
+     */
+    LayerRequest[] layerRequests;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/BlendMode.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/GenericMetadata.aidl
similarity index 66%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/BlendMode.aidl
copy to graphics/composer/aidl/android/hardware/graphics/composer3/GenericMetadata.aidl
index c6fd063..d0254dd 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/GenericMetadata.aidl
@@ -16,23 +16,18 @@
 
 package android.hardware.graphics.composer3;
 
-/**
- * Blend modes, settable per layer.
- */
+import android.hardware.graphics.composer3.LayerGenericMetadataKey;
+
 @VintfStability
-@Backing(type="int")
-enum BlendMode {
-    INVALID = 0,
+parcelable GenericMetadata {
     /**
-     * colorOut = colorSrc
+     * Indicates which metadata value should be set.
      */
-    NONE = 1,
+    LayerGenericMetadataKey key;
     /**
-     * colorOut = colorSrc + colorDst * (1 - alphaSrc)
+     * The binary representation of a AIDL struct corresponding to
+     * the key as described above.
+     * TODO(b/209691612): revisit the use of byte[]
      */
-    PREMULTIPLIED = 2,
-    /**
-     * colorOut = colorSrc * alphaSrc + colorDst * (1 - alphaSrc)
-     */
-    COVERAGE = 3,
+    byte[] value;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposer.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposer.aidl
index a6a9f73..b8edd80 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposer.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposer.aidl
@@ -27,7 +27,7 @@
     const int EX_NO_RESOURCES = 6;
 
     /**
-     * Creates a v2.4 client of the composer. Supersedes @2.3::createClient.
+     * Creates a client of the composer.
      *
      * @return is the newly created client.
      *
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerCallback.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerCallback.aidl
index 1709e6d..ac95b41 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerCallback.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerCallback.aidl
@@ -26,7 +26,7 @@
      * must trigger at least one hotplug notification, even if it only occurs
      * immediately after callback registration.
      *
-     * Displays which have been connected are assumed to be in PowerMode::OFF,
+     * Displays which have been connected are assumed to be in PowerMode.OFF,
      * and the onVsync callback should not be called for a display until vsync
      * has been enabled with setVsyncEnabled.
      *
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl
index 230980d..28bdb2c 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl
@@ -16,19 +16,17 @@
 
 package android.hardware.graphics.composer3;
 
-import android.hardware.common.fmq.MQDescriptor;
-import android.hardware.common.fmq.SynchronizedReadWrite;
 import android.hardware.graphics.composer3.ClientTargetProperty;
 import android.hardware.graphics.composer3.ColorMode;
-import android.hardware.graphics.composer3.Command;
+import android.hardware.graphics.composer3.CommandResultPayload;
 import android.hardware.graphics.composer3.ContentType;
 import android.hardware.graphics.composer3.DisplayAttribute;
 import android.hardware.graphics.composer3.DisplayCapability;
+import android.hardware.graphics.composer3.DisplayCommand;
 import android.hardware.graphics.composer3.DisplayConnectionType;
 import android.hardware.graphics.composer3.DisplayContentSample;
 import android.hardware.graphics.composer3.DisplayContentSamplingAttributes;
 import android.hardware.graphics.composer3.DisplayIdentification;
-import android.hardware.graphics.composer3.ExecuteCommandsStatus;
 import android.hardware.graphics.composer3.FormatColorComponent;
 import android.hardware.graphics.composer3.HdrCapabilities;
 import android.hardware.graphics.composer3.IComposerCallback;
@@ -159,23 +157,13 @@
     void destroyVirtualDisplay(long display);
 
     /**
-     * Executes commands from the input command message queue. Return values
-     * generated by the input commands are written to the output command
-     * message queue in the form of value commands.
+     * Executes commands.
      *
-     * @param inLength is the length of input commands.
-     * @param inHandles is an array of handles referenced by the input
-     *        commands.
+     * @param commands are the commands to be processed.
      *
-     * @return is the status of the command.
-
-     * @exception EX_BAD_PARAMETER when inLength is not equal to the length of
-     *                       commands in the input command message queue.
-     * @exception NO_RESOURCES when the output command message queue was not
-     *                      properly drained.
+     * @return are the command statuses.
      */
-    ExecuteCommandsStatus executeCommands(
-            int inLength, in android.hardware.common.NativeHandle[] inHandles);
+    CommandResultPayload[] executeCommands(in DisplayCommand[] commands);
 
     /**
      * Retrieves which display configuration is currently active.
@@ -197,7 +185,7 @@
     /**
      * Returns the color modes supported on this display.
      *
-     * All devices must support at least ColorMode::NATIVE.
+     * All devices must support at least ColorMode.NATIVE.
      *
      * @param display is the display to query.
      *
@@ -213,7 +201,7 @@
      *
      * When the layer dataspace is a legacy dataspace (see
      * common@1.1::Dataspace) and the display render intent is
-     * RenderIntent::ENHANCE, the pixel values can go through an
+     * RenderIntent.ENHANCE, the pixel values can go through an
      * implementation-defined saturation transform before being mapped to the
      * current color mode colorimetrically.
      *
@@ -259,22 +247,6 @@
     int getDisplayAttribute(long display, int config, DisplayAttribute attribute);
 
     /**
-     * Use getDisplayCapabilities instead. If brightness is supported, must return
-     * DisplayCapability::BRIGHTNESS as one of the display capabilities via getDisplayCapabilities.
-     * Only use getDisplayCapabilities as the source of truth to query brightness support.
-     *
-     * Gets whether brightness operations are supported on a display.
-     *
-     * @param display The display.
-     *
-     * @return Whether brightness operations are supported on the display.
-     *
-     * @exception EX_BAD_DISPLAY   when the display is invalid, or
-     * @exception EX_BAD_PARAMETER when the output parameter is invalid.
-     */
-    boolean getDisplayBrightnessSupport(long display);
-
-    /**
      * Provides a list of supported capabilities (as described in the
      * definition of DisplayCapability above). This list must not change after
      * initialization.
@@ -383,21 +355,6 @@
     DisplayContentSamplingAttributes getDisplayedContentSamplingAttributes(long display);
 
     /**
-     * Returns whether the given display supports PowerMode::DOZE and
-     * PowerMode::DOZE_SUSPEND. DOZE_SUSPEND may not provide any benefit over
-     * DOZE (see the definition of PowerMode for more information), but if
-     * both DOZE and DOZE_SUSPEND are no different from PowerMode::ON, the
-     * device must not claim support.
-     *
-     * @param display is the display to query.
-     *
-     * @return is true only when the display supports doze modes.
-     *
-     * @exception EX_BAD_DISPLAY when an invalid display handle was passed in.
-     */
-    boolean getDozeSupport(long display);
-
-    /**
      * Returns the high dynamic range (HDR) capabilities of the given display,
      * which are invariant with regard to the active configuration.
      *
@@ -436,17 +393,6 @@
     int getMaxVirtualDisplayCount();
 
     /**
-     * Gets the output command message queue.
-     *
-     * This function must only be called inside executeCommands closure.
-     *
-     * @return is the descriptor of the output command queue.
-     *
-     * @exception EX_NO_RESOURCES when failed to get the queue temporarily.
-     */
-    MQDescriptor<int, SynchronizedReadWrite> getOutputCommandQueue();
-
-    /**
      * Returns the PerFrameMetadataKeys that are supported by this device.
      *
      * @param display is the display on which to create the layer.
@@ -463,8 +409,8 @@
      *
      * The width and height of this buffer must be those of the currently-active
      * display configuration, and the usage flags must consist of the following:
-     *   BufferUsage::CPU_READ | BufferUsage::GPU_TEXTURE |
-     *   BufferUsage::COMPOSER_OUTPUT
+     *   BufferUsage.CPU_READ | BufferUsage.GPU_TEXTURE |
+     *   BufferUsage.COMPOSER_OUTPUT
      *
      * The format and dataspace provided must be sufficient such that if a
      * correctly-configured buffer is passed into setReadbackBuffer, filled by
@@ -539,8 +485,8 @@
      * Returns the render intents supported by the specified display and color
      * mode.
      *
-     * For SDR color modes, RenderIntent::COLORIMETRIC must be supported. For
-     * HDR color modes, RenderIntent::TONE_MAP_COLORIMETRIC must be supported.
+     * For SDR color modes, RenderIntent.COLORIMETRIC must be supported. For
+     * HDR color modes, RenderIntent.TONE_MAP_COLORIMETRIC must be supported.
      *
      * @param display is the display to query.
      * @param mode is the color mode to query.
@@ -554,11 +500,11 @@
 
     /**
      * Provides a list of all the content types supported by this display (any of
-     * ContentType::{GRAPHICS, PHOTO, CINEMA, GAME}). This list must not change after
+     * ContentType.{GRAPHICS, PHOTO, CINEMA, GAME}). This list must not change after
      * initialization.
      *
      * Content types are introduced in HDMI 1.4 and supporting them is optional. The
-     * ContentType::NONE is always supported and will not be returned by this method..
+     * ContentType.NONE is always supported and will not be returned by this method..
      *
      * @return out is a list of supported content types.
      *
@@ -625,7 +571,7 @@
      * be triggered.
      *
      * This function should only be called if the display reports support for
-     * DisplayCapability::AUTO_LOW_LATENCY_MODE from getDisplayCapabilities_2_4.
+     * DisplayCapability.AUTO_LOW_LATENCY_MODE from getDisplayCapabilities_2_4.
      *
      * @exception EX_BAD_DISPLAY when an invalid display handle was passed in.
      * @exception EX_UNSUPPORTED when AUTO_LOW_LATENCY_MODE is not supported by the composer
@@ -649,8 +595,8 @@
      * The color mode and render intent change must take effect on next
      * presentDisplay.
      *
-     * All devices must support at least ColorMode::NATIVE and
-     * RenderIntent::COLORIMETRIC, and displays are assumed to be in this mode
+     * All devices must support at least ColorMode.NATIVE and
+     * RenderIntent.COLORIMETRIC, and displays are assumed to be in this mode
      * upon hotplug.
      *
      * @param display is the display to which the color mode is set.
@@ -732,20 +678,12 @@
             long display, boolean enable, FormatColorComponent componentMask, long maxFrames);
 
     /**
-     * Sets the input command message queue.
-     *
-     * @param descriptor is the descriptor of the input command message queue.
-     * @exception EX_NO_RESOURCES when failed to set the queue temporarily.
-     */
-    void setInputCommandQueue(in MQDescriptor<int, SynchronizedReadWrite> descriptor);
-
-    /**
      * Sets the power mode of the given display. The transition must be
      * complete when this function returns. It is valid to call this function
      * multiple times with the same power mode.
      *
-     * All displays must support PowerMode::ON and PowerMode::OFF.  Whether a
-     * display supports PowerMode::DOZE or PowerMode::DOZE_SUSPEND may be
+     * All displays must support PowerMode.ON and PowerMode.OFF.  Whether a
+     * display supports PowerMode.DOZE or PowerMode.DOZE_SUSPEND may be
      * queried using getDozeSupport.
      *
      * @param display is the display to which the power mode is set.
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl
new file mode 100644
index 0000000..761da9a
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl
@@ -0,0 +1,295 @@
+/**
+ * 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.graphics.composer3;
+
+import android.hardware.common.NativeHandle;
+import android.hardware.graphics.common.FRect;
+import android.hardware.graphics.common.Point;
+import android.hardware.graphics.common.Rect;
+import android.hardware.graphics.composer3.Buffer;
+import android.hardware.graphics.composer3.Color;
+import android.hardware.graphics.composer3.FloatColor;
+import android.hardware.graphics.composer3.GenericMetadata;
+import android.hardware.graphics.composer3.ParcelableBlendMode;
+import android.hardware.graphics.composer3.ParcelableComposition;
+import android.hardware.graphics.composer3.ParcelableDataspace;
+import android.hardware.graphics.composer3.ParcelableTransform;
+import android.hardware.graphics.composer3.PerFrameMetadata;
+import android.hardware.graphics.composer3.PerFrameMetadataBlob;
+import android.hardware.graphics.composer3.PlaneAlpha;
+import android.hardware.graphics.composer3.WhitePointNits;
+import android.hardware.graphics.composer3.ZOrder;
+
+@VintfStability
+parcelable LayerCommand {
+    /**
+     * The layer which this commands refers to.
+     * @see IComposer.createLayer
+     */
+    long layer;
+
+    /**
+     * Asynchronously sets the position of a cursor layer.
+     *
+     * Prior to validateDisplay, a layer may be marked as Composition.CURSOR.
+     * If validation succeeds (i.e., the device does not request a composition
+     * change for that layer), then once a buffer has been set for the layer
+     * and it has been presented, its position may be set by this function at
+     * any time between presentDisplay and any subsequent validateDisplay
+     * calls for this display.
+     *
+     * Once validateDisplay is called, this function must not be called again
+     * until the validate/present sequence is completed.
+     *
+     * May be called from any thread so long as it is not interleaved with the
+     * validate/present sequence as described above.
+     */
+    @nullable Point cursorPosition;
+
+    /**
+     * Sets the buffer handle to be displayed for this layer. If the buffer
+     * properties set at allocation time (width, height, format, and usage)
+     * have not changed since the previous frame, it is not necessary to call
+     * validateDisplay before calling presentDisplay unless new state needs to
+     * be validated in the interim.
+     *
+     * Also provides a file descriptor referring to an acquire sync fence
+     * object, which must be signaled when it is safe to read from the given
+     * buffer. If it is already safe to read from the buffer, an empty handle
+     * may be passed instead.
+     *
+     * This function must return NONE and have no other effect if called for a
+     * layer with a composition type of Composition.SOLID_COLOR (because it
+     * has no buffer) or Composition.SIDEBAND or Composition.CLIENT (because
+     * synchronization and buffer updates for these layers are handled
+     * elsewhere).
+     */
+    @nullable Buffer buffer;
+
+    /**
+     * Provides the region of the source buffer which has been modified since
+     * the last frame. This region does not need to be validated before
+     * calling presentDisplay.
+     *
+     * Once set through this function, the damage region remains the same
+     * until a subsequent call to this function.
+     *
+     * If damage is non-empty, then it may be assumed that any portion of the
+     * source buffer not covered by one of the rects has not been modified
+     * this frame. If damage is empty, then the whole source buffer must be
+     * treated as if it has been modified.
+     *
+     * If the layer's contents are not modified relative to the prior frame,
+     * damage must contain exactly one empty rect([0, 0, 0, 0]).
+     *
+     * The damage rects are relative to the pre-transformed buffer, and their
+     * origin is the top-left corner. They must not exceed the dimensions of
+     * the latched buffer.
+     */
+    @nullable Rect[] damage;
+
+    /**
+     * Sets the blend mode of the given layer.
+     */
+    @nullable ParcelableBlendMode blendMode;
+
+    /**
+     * Sets the color of the given layer. If the composition type of the layer
+     * is not Composition.SOLID_COLOR, this call must succeed and have no
+     * other effect.
+     */
+    @nullable Color color;
+
+    /**
+     * Sets the color of the given layer. If the composition type of the layer
+     * is not Composition.SOLID_COLOR, this call must succeed and have no
+     * other effect.
+     */
+    @nullable FloatColor floatColor;
+
+    /**
+     * Sets the desired composition type of the given layer. During
+     * validateDisplay, the device may request changes to the composition
+     * types of any of the layers as described in the definition of
+     * Composition above.
+     */
+    @nullable ParcelableComposition composition;
+
+    /**
+     * Sets the dataspace of the layer.
+     *
+     * The dataspace provides more information about how to interpret the buffer
+     * or solid color, such as the encoding standard and color transform.
+     *
+     * See the values of ParcelableDataspace for more information.
+     */
+    @nullable ParcelableDataspace dataspace;
+
+    /**
+     * Sets the display frame (the portion of the display covered by a layer)
+     * of the given layer. This frame must not exceed the display dimensions.
+     */
+    @nullable Rect displayFrame;
+
+    /**
+     * Sets an alpha value (a floating point value in the range [0.0, 1.0])
+     * which will be applied to the whole layer. It can be conceptualized as a
+     * preprocessing step which applies the following function:
+     *   if (blendMode == BlendMode.PREMULTIPLIED)
+     *       out.rgb = in.rgb * planeAlpha
+     *   out.a = in.a * planeAlpha
+     *
+     * If the device does not support this operation on a layer which is
+     * marked Composition.DEVICE, it must request a composition type change
+     * to Composition.CLIENT upon the next validateDisplay call.
+     *
+     */
+    @nullable PlaneAlpha planeAlpha;
+
+    /**
+     * Sets the sideband stream for this layer. If the composition type of the
+     * given layer is not Composition.SIDEBAND, this call must succeed and
+     * have no other effect.
+     */
+    @nullable NativeHandle sidebandStream;
+
+    /**
+     * Sets the source crop (the portion of the source buffer which will fill
+     * the display frame) of the given layer. This crop rectangle must not
+     * exceed the dimensions of the latched buffer.
+     *
+     * If the device is not capable of supporting a true float source crop
+     * (i.e., it will truncate or round the floats to integers), it must set
+     * this layer to Composition.CLIENT when crop is non-integral for the
+     * most accurate rendering.
+     *
+     * If the device cannot support float source crops, but still wants to
+     * handle the layer, it must use the following code (or similar) to
+     * convert to an integer crop:
+     *   intCrop.left = (int) ceilf(crop.left);
+     *   intCrop.top = (int) ceilf(crop.top);
+     *   intCrop.right = (int) floorf(crop.right);
+     *   intCrop.bottom = (int) floorf(crop.bottom);
+     */
+    @nullable FRect sourceCrop;
+
+    /**
+     * Sets the transform (rotation/flip) of the given layer.
+     */
+    @nullable ParcelableTransform transform;
+
+    /**
+     * Specifies the portion of the layer that is visible, including portions
+     * under translucent areas of other layers. The region is in screen space,
+     * and must not exceed the dimensions of the screen.
+     */
+    @nullable Rect[] visibleRegion;
+
+    /**
+     * Sets the desired Z order (height) of the given layer. A layer with a
+     * greater Z value occludes a layer with a lesser Z value.
+     */
+    @nullable ZOrder z;
+
+    /**
+     * Sets a matrix for color transform which will be applied on this layer
+     * before composition.
+     *
+     * If the device is not capable of apply the matrix on this layer, it must force
+     * this layer to client composition during VALIDATE_DISPLAY.
+     *
+     * The matrix provided is an affine color transformation of the following
+     * form:
+     *
+     * |r.r r.g r.b 0|
+     * |g.r g.g g.b 0|
+     * |b.r b.g b.b 0|
+     * |Tr  Tg  Tb  1|
+     *
+     * This matrix must be provided in row-major form:
+     *
+     * {r.r, r.g, r.b, 0, g.r, ...}.
+     *
+     * Given a matrix of this form and an input color [R_in, G_in, B_in],
+     * the input color must first be converted to linear space
+     * [R_linear, G_linear, B_linear], then the output linear color
+     * [R_out_linear, G_out_linear, B_out_linear] will be:
+     *
+     * R_out_linear = R_linear * r.r + G_linear * g.r + B_linear * b.r + Tr
+     * G_out_linear = R_linear * r.g + G_linear * g.g + B_linear * b.g + Tg
+     * B_out_linear = R_linear * r.b + G_linear * g.b + B_linear * b.b + Tb
+     *
+     * [R_out_linear, G_out_linear, B_out_linear] must then be converted to
+     * gamma space: [R_out, G_out, B_out] before blending.
+     */
+    @nullable float[] colorTransform;
+
+    /**
+     * Sets the desired white point for the layer. This is intended to be used when presenting
+     * an SDR layer alongside HDR content. The HDR content will be presented at the display
+     * brightness in nits, and accordingly SDR content shall be dimmed to the desired white point
+     * provided.
+     */
+    @nullable WhitePointNits whitePointNits;
+
+    /**
+     * Sets a piece of generic metadata for the given layer. If this
+     * function is called twice with the same key but different values, the
+     * newer value must override the older one. Calling this function with a
+     * 0-length value must reset that key's metadata as if it had not been
+     * set.
+     *
+     * A given piece of metadata may either be mandatory or a hint
+     * (non-mandatory) as indicated by the second parameter. Mandatory
+     * metadata may affect the composition result, which is to say that it
+     * may cause a visible change in the final image. By contrast, hints may
+     * only affect the composition strategy, such as which layers are
+     * composited by the client, but must not cause a visible change in the
+     * final image. The value of the mandatory flag shall match the value
+     * returned from getLayerGenericMetadataKeys for the given key.
+     *
+     * Only keys which have been returned from getLayerGenericMetadataKeys()
+     * shall be accepted. Any other keys must result in an UNSUPPORTED error.
+     *
+     * The value passed into this function shall be the binary
+     * representation of a stable AIDL type corresponding to the given key. For
+     * example, a key of 'com.example.Foo-V2' shall be paired with a
+     * value of type com.exampleFoo-V2, which would be defined in a
+     * vendor HAL extension.
+     */
+    @nullable GenericMetadata genericMetadata;
+
+    /**
+     * Sets the PerFrameMetadata for the display. This metadata must be used
+     * by the implementation to better tone map content to that display.
+     *
+     * This is a command that may be called every frame.
+     */
+    @nullable PerFrameMetadata[] perFrameMetadata;
+
+    /**
+     * This command sends metadata that may be used for tone-mapping the
+     * associated layer.  The metadata structure follows a {key, blob}
+     * format (see the PerFrameMetadataBlob struct).  All keys must be
+     * returned by a prior call to getPerFrameMetadataKeys and must
+     * be part of the list of keys associated with blob-type metadata
+     * (see PerFrameMetadataKey).
+     *
+     * This command may be called every frame.
+     */
+    @nullable PerFrameMetadataBlob[] perFrameMetadataBlob;
+}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/ParcelableBlendMode.aidl
similarity index 68%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/composer/aidl/android/hardware/graphics/composer3/ParcelableBlendMode.aidl
index 10de558..a6c016a 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/ParcelableBlendMode.aidl
@@ -16,16 +16,9 @@
 
 package android.hardware.graphics.composer3;
 
-/**
- * Layer requests returned from getDisplayRequests.
- */
+import android.hardware.graphics.common.BlendMode;
+
 @VintfStability
-@Backing(type="int")
-enum LayerRequest {
-    /**
-     * The client must clear its target with transparent pixels where
-     * this layer would be. The client may ignore this request if the
-     * layer must be blended.
-     */
-    CLEAR_CLIENT_TARGET = 1 << 0,
+parcelable ParcelableBlendMode {
+    BlendMode blendMode;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/ParcelableComposition.aidl
similarity index 68%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/composer/aidl/android/hardware/graphics/composer3/ParcelableComposition.aidl
index 10de558..0946ce7 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/ParcelableComposition.aidl
@@ -16,16 +16,9 @@
 
 package android.hardware.graphics.composer3;
 
-/**
- * Layer requests returned from getDisplayRequests.
- */
+import android.hardware.graphics.composer3.Composition;
+
 @VintfStability
-@Backing(type="int")
-enum LayerRequest {
-    /**
-     * The client must clear its target with transparent pixels where
-     * this layer would be. The client may ignore this request if the
-     * layer must be blended.
-     */
-    CLEAR_CLIENT_TARGET = 1 << 0,
+parcelable ParcelableComposition {
+    Composition composition;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/ParcelableDataspace.aidl
similarity index 68%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/composer/aidl/android/hardware/graphics/composer3/ParcelableDataspace.aidl
index 10de558..528cdf9 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/ParcelableDataspace.aidl
@@ -16,16 +16,9 @@
 
 package android.hardware.graphics.composer3;
 
-/**
- * Layer requests returned from getDisplayRequests.
- */
+import android.hardware.graphics.common.Dataspace;
+
 @VintfStability
-@Backing(type="int")
-enum LayerRequest {
-    /**
-     * The client must clear its target with transparent pixels where
-     * this layer would be. The client may ignore this request if the
-     * layer must be blended.
-     */
-    CLEAR_CLIENT_TARGET = 1 << 0,
+parcelable ParcelableDataspace {
+    Dataspace dataspace;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/ParcelableTransform.aidl
similarity index 68%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/composer/aidl/android/hardware/graphics/composer3/ParcelableTransform.aidl
index 10de558..75f9f7e 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/ParcelableTransform.aidl
@@ -16,16 +16,9 @@
 
 package android.hardware.graphics.composer3;
 
-/**
- * Layer requests returned from getDisplayRequests.
- */
+import android.hardware.graphics.common.Transform;
+
 @VintfStability
-@Backing(type="int")
-enum LayerRequest {
-    /**
-     * The client must clear its target with transparent pixels where
-     * this layer would be. The client may ignore this request if the
-     * layer must be blended.
-     */
-    CLEAR_CLIENT_TARGET = 1 << 0,
+parcelable ParcelableTransform {
+    Transform transform;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/PerFrameMetadataKey.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/PerFrameMetadataKey.aidl
index b666e6a..3962920 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/PerFrameMetadataKey.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/PerFrameMetadataKey.aidl
@@ -16,8 +16,6 @@
 
 package android.hardware.graphics.composer3;
 
-import android.hardware.graphics.composer3.PerFrameMetadataKey;
-
 /**
  * PerFrameMetadataKey
  *
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/PlaneAlpha.aidl
similarity index 69%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/composer/aidl/android/hardware/graphics/composer3/PlaneAlpha.aidl
index 10de558..347dc19 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/PlaneAlpha.aidl
@@ -16,16 +16,12 @@
 
 package android.hardware.graphics.composer3;
 
-/**
- * Layer requests returned from getDisplayRequests.
- */
 @VintfStability
-@Backing(type="int")
-enum LayerRequest {
+parcelable PlaneAlpha {
     /**
-     * The client must clear its target with transparent pixels where
-     * this layer would be. The client may ignore this request if the
-     * layer must be blended.
+     * An alpha value (a floating point value in the range [0.0, 1.0])
+     * which will be applied to a whole layer.
+     * @see LayerCommand.planeAlpha
      */
-    CLEAR_CLIENT_TARGET = 1 << 0,
+    float alpha;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/PresentFence.aidl
similarity index 69%
rename from graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
rename to graphics/composer/aidl/android/hardware/graphics/composer3/PresentFence.aidl
index 10de558..244b4e5 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/PresentFence.aidl
@@ -16,16 +16,16 @@
 
 package android.hardware.graphics.composer3;
 
-/**
- * Layer requests returned from getDisplayRequests.
- */
 @VintfStability
-@Backing(type="int")
-enum LayerRequest {
+parcelable PresentFence {
     /**
-     * The client must clear its target with transparent pixels where
-     * this layer would be. The client may ignore this request if the
-     * layer must be blended.
+     * The display which this commands refers to.
+     * @see IComposer.createDisplay
      */
-    CLEAR_CLIENT_TARGET = 1 << 0,
+    long display;
+
+    /**
+     * The present fence for this display.
+     */
+    ParcelFileDescriptor fence;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/PresentOrValidate.aidl
similarity index 69%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/composer/aidl/android/hardware/graphics/composer3/PresentOrValidate.aidl
index 10de558..f3153bd 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/PresentOrValidate.aidl
@@ -16,16 +16,17 @@
 
 package android.hardware.graphics.composer3;
 
-/**
- * Layer requests returned from getDisplayRequests.
- */
 @VintfStability
-@Backing(type="int")
-enum LayerRequest {
+parcelable PresentOrValidate {
     /**
-     * The client must clear its target with transparent pixels where
-     * this layer would be. The client may ignore this request if the
-     * layer must be blended.
+     * The display which this commands refers to.
+     * @see IComposer.createDisplay
      */
-    CLEAR_CLIENT_TARGET = 1 << 0,
+    long display;
+
+    /**
+     * Whether PresentOrValidate presented or validated the display.
+     */
+    @VintfStability enum Result { Presented, Validated }
+    Result result;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/ReleaseFences.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/ReleaseFences.aidl
new file mode 100644
index 0000000..459a042
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/ReleaseFences.aidl
@@ -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 android.hardware.graphics.composer3;
+
+@VintfStability
+parcelable ReleaseFences {
+    /**
+     * The display which this commands refers to.
+     * @see IComposer.createDisplay
+     */
+    long display;
+    @VintfStability
+    parcelable Layer {
+        /**
+         * The layer which this commands refers to.
+         * @see IComposer.createLayer
+         */
+        long layer;
+
+        /**
+         * The release fence for this layer.
+         */
+        ParcelFileDescriptor fence;
+    }
+
+    /**
+     * The layers which has release fences.
+     */
+    Layer[] layers;
+}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/RenderIntent.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/RenderIntent.aidl
index 043b24d..debf32c 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/RenderIntent.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/RenderIntent.aidl
@@ -25,8 +25,8 @@
  * modes should not affect the mapping.
  *
  * RenderIntent overrides the render intents defined for individual color
- * modes. It is ignored when the color mode is ColorMode::NATIVE, because
- * ColorMode::NATIVE colors are already display colors.
+ * modes. It is ignored when the color mode is ColorMode.NATIVE, because
+ * ColorMode.NATIVE colors are already display colors.
  */
 @VintfStability
 @Backing(type="int")
@@ -36,7 +36,7 @@
      * gamut are hard-clipped.
      *
      * This implies that the display must have been calibrated unless
-     * ColorMode::NATIVE is the only supported color mode.
+     * ColorMode.NATIVE is the only supported color mode.
      */
     COLORIMETRIC = 0,
     /**
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/WhitePointNits.aidl
similarity index 64%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/composer/aidl/android/hardware/graphics/composer3/WhitePointNits.aidl
index 10de558..2a1d1c6 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/WhitePointNits.aidl
@@ -16,16 +16,14 @@
 
 package android.hardware.graphics.composer3;
 
-/**
- * Layer requests returned from getDisplayRequests.
- */
 @VintfStability
-@Backing(type="int")
-enum LayerRequest {
+parcelable WhitePointNits {
     /**
-     * The client must clear its target with transparent pixels where
-     * this layer would be. The client may ignore this request if the
-     * layer must be blended.
+     * The desired white point for the layer. This is intended to be used when presenting
+     * an SDR layer alongside HDR content. The HDR content will be presented at the display
+     * brightness in nits, and accordingly SDR content shall be dimmed to the desired white point
+     * provided.
+     * @see LayerCommand.whitePointNits.
      */
-    CLEAR_CLIENT_TARGET = 1 << 0,
+    float nits;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/ZOrder.aidl
similarity index 69%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
copy to graphics/composer/aidl/android/hardware/graphics/composer3/ZOrder.aidl
index 10de558..56cc200 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/ZOrder.aidl
@@ -16,16 +16,12 @@
 
 package android.hardware.graphics.composer3;
 
-/**
- * Layer requests returned from getDisplayRequests.
- */
 @VintfStability
-@Backing(type="int")
-enum LayerRequest {
+parcelable ZOrder {
     /**
-     * The client must clear its target with transparent pixels where
-     * this layer would be. The client may ignore this request if the
-     * layer must be blended.
+     * The desired Z order (height) of the given layer. A layer with a
+     * greater Z value occludes a layer with a lesser Z value.
+     * @see LayerCommand.z;
      */
-    CLEAR_CLIENT_TARGET = 1 << 0,
+    int z;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/translate-ndk.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/translate-ndk.cpp
index d59190d..a3c8176 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/translate-ndk.cpp
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/translate-ndk.cpp
@@ -74,25 +74,25 @@
 static_assert(aidl::android::hardware::graphics::composer3::Capability::SKIP_VALIDATE ==
               static_cast<aidl::android::hardware::graphics::composer3::Capability>(4));
 
-static_assert(aidl::android::hardware::graphics::composer3::LayerRequest::CLEAR_CLIENT_TARGET ==
-              static_cast<aidl::android::hardware::graphics::composer3::LayerRequest>(
-                      ::android::hardware::graphics::composer::V2_1::IComposerClient::LayerRequest::
-                              CLEAR_CLIENT_TARGET));
+static_assert(aidl::android::hardware::graphics::composer3::DisplayRequest::LayerRequest::
+                      CLEAR_CLIENT_TARGET ==
+              static_cast<int>(::android::hardware::graphics::composer::V2_1::IComposerClient::
+                                       LayerRequest::CLEAR_CLIENT_TARGET));
 
-static_assert(aidl::android::hardware::graphics::composer3::BlendMode::INVALID ==
-              static_cast<aidl::android::hardware::graphics::composer3::BlendMode>(
+static_assert(aidl::android::hardware::graphics::common::BlendMode::INVALID ==
+              static_cast<aidl::android::hardware::graphics::common::BlendMode>(
                       ::android::hardware::graphics::composer::V2_1::IComposerClient::BlendMode::
                               INVALID));
 static_assert(
-        aidl::android::hardware::graphics::composer3::BlendMode::NONE ==
-        static_cast<aidl::android::hardware::graphics::composer3::BlendMode>(
+        aidl::android::hardware::graphics::common::BlendMode::NONE ==
+        static_cast<aidl::android::hardware::graphics::common::BlendMode>(
                 ::android::hardware::graphics::composer::V2_1::IComposerClient::BlendMode::NONE));
-static_assert(aidl::android::hardware::graphics::composer3::BlendMode::PREMULTIPLIED ==
-              static_cast<aidl::android::hardware::graphics::composer3::BlendMode>(
+static_assert(aidl::android::hardware::graphics::common::BlendMode::PREMULTIPLIED ==
+              static_cast<aidl::android::hardware::graphics::common::BlendMode>(
                       ::android::hardware::graphics::composer::V2_1::IComposerClient::BlendMode::
                               PREMULTIPLIED));
-static_assert(aidl::android::hardware::graphics::composer3::BlendMode::COVERAGE ==
-              static_cast<aidl::android::hardware::graphics::composer3::BlendMode>(
+static_assert(aidl::android::hardware::graphics::common::BlendMode::COVERAGE ==
+              static_cast<aidl::android::hardware::graphics::common::BlendMode>(
                       ::android::hardware::graphics::composer::V2_1::IComposerClient::BlendMode::
                               COVERAGE));
 
@@ -122,14 +122,12 @@
                               SIDEBAND));
 
 static_assert(aidl::android::hardware::graphics::composer3::DisplayRequest::FLIP_CLIENT_TARGET ==
-              static_cast<aidl::android::hardware::graphics::composer3::DisplayRequest>(
-                      ::android::hardware::graphics::composer::V2_1::IComposerClient::
-                              DisplayRequest::FLIP_CLIENT_TARGET));
+              static_cast<int>(::android::hardware::graphics::composer::V2_1::IComposerClient::
+                                       DisplayRequest::FLIP_CLIENT_TARGET));
 static_assert(aidl::android::hardware::graphics::composer3::DisplayRequest::
                       WRITE_CLIENT_TARGET_TO_OUTPUT ==
-              static_cast<aidl::android::hardware::graphics::composer3::DisplayRequest>(
-                      ::android::hardware::graphics::composer::V2_1::IComposerClient::
-                              DisplayRequest::WRITE_CLIENT_TARGET_TO_OUTPUT));
+              static_cast<int>(::android::hardware::graphics::composer::V2_1::IComposerClient::
+                                       DisplayRequest::WRITE_CLIENT_TARGET_TO_OUTPUT));
 
 static_assert(aidl::android::hardware::graphics::composer3::HandleIndex::EMPTY ==
               static_cast<aidl::android::hardware::graphics::composer3::HandleIndex>(
@@ -188,162 +186,6 @@
                 ::android::hardware::graphics::composer::V2_4::IComposerClient::DisplayCapability::
                         AUTO_LOW_LATENCY_MODE));
 
-static_assert(aidl::android::hardware::graphics::composer3::Command::LENGTH_MASK ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              LENGTH_MASK));
-static_assert(aidl::android::hardware::graphics::composer3::Command::OPCODE_SHIFT ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              OPCODE_SHIFT));
-static_assert(aidl::android::hardware::graphics::composer3::Command::OPCODE_MASK ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              OPCODE_MASK));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SELECT_DISPLAY ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SELECT_DISPLAY));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SELECT_LAYER ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SELECT_LAYER));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_ERROR ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_ERROR));
-static_assert(
-        aidl::android::hardware::graphics::composer3::Command::SET_CHANGED_COMPOSITION_TYPES ==
-        static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                        SET_CHANGED_COMPOSITION_TYPES));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_DISPLAY_REQUESTS ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_DISPLAY_REQUESTS));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_PRESENT_FENCE ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_PRESENT_FENCE));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_RELEASE_FENCES ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_RELEASE_FENCES));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_COLOR_TRANSFORM ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_COLOR_TRANSFORM));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_CLIENT_TARGET ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_CLIENT_TARGET));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_OUTPUT_BUFFER ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_OUTPUT_BUFFER));
-static_assert(aidl::android::hardware::graphics::composer3::Command::VALIDATE_DISPLAY ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              VALIDATE_DISPLAY));
-static_assert(aidl::android::hardware::graphics::composer3::Command::ACCEPT_DISPLAY_CHANGES ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              ACCEPT_DISPLAY_CHANGES));
-static_assert(aidl::android::hardware::graphics::composer3::Command::PRESENT_DISPLAY ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              PRESENT_DISPLAY));
-static_assert(aidl::android::hardware::graphics::composer3::Command::PRESENT_OR_VALIDATE_DISPLAY ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              PRESENT_OR_VALIDATE_DISPLAY));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_CURSOR_POSITION ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_LAYER_CURSOR_POSITION));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_BUFFER ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_LAYER_BUFFER));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_SURFACE_DAMAGE ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_LAYER_SURFACE_DAMAGE));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_BLEND_MODE ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_LAYER_BLEND_MODE));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_COLOR ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_LAYER_COLOR));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_COMPOSITION_TYPE ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_LAYER_COMPOSITION_TYPE));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_DATASPACE ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_LAYER_DATASPACE));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_DISPLAY_FRAME ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_LAYER_DISPLAY_FRAME));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_PLANE_ALPHA ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_LAYER_PLANE_ALPHA));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_SIDEBAND_STREAM ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_LAYER_SIDEBAND_STREAM));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_SOURCE_CROP ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_LAYER_SOURCE_CROP));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_TRANSFORM ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_LAYER_TRANSFORM));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_VISIBLE_REGION ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_LAYER_VISIBLE_REGION));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_Z_ORDER ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_LAYER_Z_ORDER));
-static_assert(aidl::android::hardware::graphics::composer3::Command::
-                      SET_PRESENT_OR_VALIDATE_DISPLAY_RESULT ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_PRESENT_OR_VALIDATE_DISPLAY_RESULT));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_PER_FRAME_METADATA ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_LAYER_PER_FRAME_METADATA));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_FLOAT_COLOR ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_LAYER_FLOAT_COLOR));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_COLOR_TRANSFORM ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_LAYER_COLOR_TRANSFORM));
-static_assert(
-        aidl::android::hardware::graphics::composer3::Command::SET_LAYER_PER_FRAME_METADATA_BLOBS ==
-        static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                        SET_LAYER_PER_FRAME_METADATA_BLOBS));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_CLIENT_TARGET_PROPERTY ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_CLIENT_TARGET_PROPERTY));
-static_assert(aidl::android::hardware::graphics::composer3::Command::SET_LAYER_GENERIC_METADATA ==
-              static_cast<aidl::android::hardware::graphics::composer3::Command>(
-                      ::android::hardware::graphics::composer::V2_4::IComposerClient::Command::
-                              SET_LAYER_GENERIC_METADATA));
-
 static_assert(aidl::android::hardware::graphics::composer3::DisplayAttribute::INVALID ==
               static_cast<aidl::android::hardware::graphics::composer3::DisplayAttribute>(
                       ::android::hardware::graphics::composer::V2_4::IComposerClient::Attribute::
@@ -612,4 +454,4 @@
     return true;
 }
 
-}  // namespace android::h2a
\ No newline at end of file
+}  // namespace android::h2a
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/Android.bp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/Android.bp
index 9bf8609..741572d 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/Android.bp
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/Android.bp
@@ -35,7 +35,6 @@
         "VtsHalGraphicsComposer3_TargetTest.cpp",
         "VtsHalGraphicsComposer3_ReadbackTest.cpp",
         "composer-vts/GraphicsComposerCallback.cpp",
-        "composer-vts/TestCommandReader.cpp",
     ],
 
     shared_libs: [
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_ReadbackTest.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_ReadbackTest.cpp
index 6f83b90..34dea9e 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_ReadbackTest.cpp
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_ReadbackTest.cpp
@@ -28,7 +28,6 @@
 #include <ui/PixelFormat.h>
 #include <ui/Rect.h>
 #include "composer-vts/include/GraphicsComposerCallback.h"
-#include "composer-vts/include/TestCommandReader.h"
 
 namespace aidl::android::hardware::graphics::composer3::vts {
 namespace {
@@ -51,6 +50,8 @@
         // assume the first display is primary and is never removed
         mPrimaryDisplay = waitForFirstDisplay();
 
+        ASSERT_NO_FATAL_FAILURE(mInvalidDisplayId = GetInvalidDisplayId());
+
         int32_t activeConfig;
         EXPECT_TRUE(mComposerClient->getActiveConfig(mPrimaryDisplay, &activeConfig).isOk());
         EXPECT_TRUE(mComposerClient
@@ -68,9 +69,7 @@
         EXPECT_TRUE(mComposerClient->setVsyncEnabled(mPrimaryDisplay, false).isOk());
         mComposerCallback->setVsyncAllowed(false);
 
-        // set up command writer/reader and gralloc
-        mWriter = std::make_shared<CommandWriterBase>(1024);
-        mReader = std::make_unique<TestCommandReader>();
+        // set up gralloc
         mGraphicBuffer = allocate();
 
         ASSERT_NO_FATAL_FAILURE(mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::ON));
@@ -102,8 +101,15 @@
 
     void TearDown() override {
         ASSERT_NO_FATAL_FAILURE(mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::OFF));
-        EXPECT_EQ(0, mReader->mErrors.size());
-        EXPECT_EQ(0, mReader->mCompositionChanges.size());
+        const auto errors = mReader.takeErrors();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+
+        std::vector<int64_t> layers;
+        std::vector<Composition> types;
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &layers, &types);
+
+        ASSERT_TRUE(layers.empty());
+        ASSERT_TRUE(types.empty());
         if (mComposerCallback != nullptr) {
             EXPECT_EQ(0, mComposerCallback->getInvalidHotplugCount());
             EXPECT_EQ(0, mComposerCallback->getInvalidRefreshCount());
@@ -120,11 +126,6 @@
                 "VtsHalGraphicsComposer3_ReadbackTest");
     }
 
-    void clearCommandReaderState() {
-        mReader->mCompositionChanges.clear();
-        mReader->mErrors.clear();
-    }
-
     void writeLayers(const std::vector<std::shared_ptr<TestLayer>>& layers) {
         for (auto layer : layers) {
             layer->write(mWriter);
@@ -133,31 +134,27 @@
     }
 
     void execute() {
-        TestCommandReader* reader = mReader.get();
-        CommandWriterBase* writer = mWriter.get();
-        bool queueChanged = false;
-        int32_t commandLength = 0;
-        std::vector<NativeHandle> commandHandles;
-        ASSERT_TRUE(writer->writeQueue(&queueChanged, &commandLength, &commandHandles));
-
-        if (queueChanged) {
-            auto ret = mComposerClient->setInputCommandQueue(writer->getMQDescriptor());
-            ASSERT_TRUE(ret.isOk());
+        const auto& commands = mWriter.getPendingCommands();
+        if (commands.empty()) {
+            mWriter.reset();
+            return;
         }
 
-        ExecuteCommandsStatus commandStatus;
-        EXPECT_TRUE(mComposerClient->executeCommands(commandLength, commandHandles, &commandStatus)
-                            .isOk());
+        std::vector<CommandResultPayload> results;
+        const auto status = mComposerClient->executeCommands(commands, &results);
+        ASSERT_TRUE(status.isOk()) << "executeCommands failed " << status.getDescription();
 
-        if (commandStatus.queueChanged) {
-            MQDescriptor<int32_t, SynchronizedReadWrite> outputCommandQueue;
-            ASSERT_TRUE(mComposerClient->getOutputCommandQueue(&outputCommandQueue).isOk());
-            reader->setMQDescriptor(outputCommandQueue);
-        }
-        ASSERT_TRUE(reader->readQueue(commandStatus.length, std::move(commandStatus.handles)));
-        reader->parse();
-        reader->reset();
-        writer->reset();
+        mReader.parse(results);
+        mWriter.reset();
+    }
+
+    bool getHasReadbackBuffer() {
+        ReadbackBufferAttributes readBackBufferAttributes;
+        const auto error = mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay,
+                                                                        &readBackBufferAttributes);
+        mPixelFormat = readBackBufferAttributes.format;
+        mDataspace = readBackBufferAttributes.dataspace;
+        return error.isOk() && ReadbackHelper::readbackSupported(mPixelFormat, mDataspace);
     }
 
     std::shared_ptr<IComposer> mComposer;
@@ -166,15 +163,15 @@
     std::shared_ptr<GraphicsComposerCallback> mComposerCallback;
     // the first display and is assumed never to be removed
     int64_t mPrimaryDisplay;
+    int64_t mInvalidDisplayId;
     int32_t mDisplayWidth;
     int32_t mDisplayHeight;
     std::vector<ColorMode> mTestColorModes;
-    std::shared_ptr<CommandWriterBase> mWriter;
-    std::unique_ptr<TestCommandReader> mReader;
+    ComposerClientWriter mWriter;
+    ComposerClientReader mReader;
     ::android::sp<::android::GraphicBuffer> mGraphicBuffer;
     std::unique_ptr<TestRenderEngine> mTestRenderEngine;
 
-    bool mHasReadbackBuffer;
     common::PixelFormat mPixelFormat;
     common::Dataspace mDataspace;
 
@@ -204,6 +201,27 @@
             }
         }
     }
+
+    // returns an invalid display id (one that has not been registered to a
+    // display.  Currently assuming that a device will never have close to
+    // std::numeric_limit<uint64_t>::max() displays registered while running tests
+    int64_t GetInvalidDisplayId() {
+        int64_t id = std::numeric_limits<int64_t>::max();
+        std::vector<int64_t> displays = mComposerCallback->getDisplays();
+        while (id > 0) {
+            if (std::none_of(displays.begin(), displays.end(),
+                             [&](const auto& display) { return id == display; })) {
+                return id;
+            }
+            id--;
+        }
+
+        // Although 0 could be an invalid display, a return value of 0
+        // from GetInvalidDisplayId means all other ids are in use, a condition which
+        // we are assuming a device will never have
+        EXPECT_NE(0, id);
+        return id;
+    }
 };
 
 class GraphicsCompositionTest : public GraphicsCompositionTestBase,
@@ -214,20 +232,10 @@
 
 TEST_P(GraphicsCompositionTest, SingleSolidColorLayer) {
     for (ColorMode mode : mTestColorModes) {
-        mWriter->selectDisplay(mPrimaryDisplay);
         ASSERT_NO_FATAL_FAILURE(
                 mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
 
-        ReadbackBufferAttributes readBackBufferAttributes;
-        const auto error = mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay,
-                                                                        &readBackBufferAttributes);
-
-        mPixelFormat = readBackBufferAttributes.format;
-        mDataspace = readBackBufferAttributes.dataspace;
-        mHasReadbackBuffer =
-                error.isOk() && ReadbackHelper::readbackSupported(mPixelFormat, mDataspace);
-
-        if (!mHasReadbackBuffer) {
+        if (!getHasReadbackBuffer()) {
             GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
             return;
         }
@@ -249,20 +257,23 @@
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
 
         writeLayers(layers);
-        ASSERT_EQ(0, mReader->mErrors.size());
-        mWriter->validateDisplay();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.validateDisplay(mPrimaryDisplay);
         execute();
         // if hwc cannot handle and asks for composition change,
         // just succeed the test
-        if (mReader->mCompositionChanges.size() != 0) {
-            clearCommandReaderState();
+        std::vector<int64_t> changedCompositionLayers;
+        std::vector<Composition> changedCompositionTypes;
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+                                            &changedCompositionTypes);
+        if (!changedCompositionLayers.empty()) {
             GTEST_SUCCEED();
             return;
         }
-        ASSERT_EQ(0, mReader->mErrors.size());
-        mWriter->presentDisplay();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.presentDisplay(mPrimaryDisplay);
         execute();
-        ASSERT_EQ(0, mReader->mErrors.size());
+        ASSERT_TRUE(mReader.takeErrors().empty());
 
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
         mTestRenderEngine->setRenderLayers(layers);
@@ -273,26 +284,14 @@
 
 TEST_P(GraphicsCompositionTest, SetLayerBuffer) {
     for (ColorMode mode : mTestColorModes) {
-        mWriter->selectDisplay(mPrimaryDisplay);
         ASSERT_NO_FATAL_FAILURE(
                 mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
 
-        ReadbackBufferAttributes readBackBufferAttributes;
-        const auto error = mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay,
-                                                                        &readBackBufferAttributes);
-
-        mPixelFormat = readBackBufferAttributes.format;
-        mDataspace = readBackBufferAttributes.dataspace;
-        mHasReadbackBuffer =
-                error.isOk() && ReadbackHelper::readbackSupported(mPixelFormat, mDataspace);
-
-        if (!mHasReadbackBuffer) {
+        if (!getHasReadbackBuffer()) {
             GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
             return;
         }
 
-        mWriter->selectDisplay(mPrimaryDisplay);
-
         ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGraphicBuffer,
                                       mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace);
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
@@ -317,21 +316,24 @@
         std::vector<std::shared_ptr<TestLayer>> layers = {layer};
 
         writeLayers(layers);
-        ASSERT_EQ(0, mReader->mErrors.size());
-        mWriter->validateDisplay();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.validateDisplay(mPrimaryDisplay);
         execute();
 
-        if (mReader->mCompositionChanges.size() != 0) {
-            clearCommandReaderState();
+        std::vector<int64_t> changedCompositionLayers;
+        std::vector<Composition> changedCompositionTypes;
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+                                            &changedCompositionTypes);
+        if (!changedCompositionLayers.empty()) {
             GTEST_SUCCEED();
             return;
         }
-        ASSERT_EQ(0, mReader->mErrors.size());
+        ASSERT_TRUE(mReader.takeErrors().empty());
 
-        mWriter->presentDisplay();
+        mWriter.presentDisplay(mPrimaryDisplay);
         execute();
 
-        ASSERT_EQ(0, mReader->mErrors.size());
+        ASSERT_TRUE(mReader.takeErrors().empty());
 
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
         mTestRenderEngine->setRenderLayers(layers);
@@ -342,20 +344,10 @@
 
 TEST_P(GraphicsCompositionTest, SetLayerBufferNoEffect) {
     for (ColorMode mode : mTestColorModes) {
-        mWriter->selectDisplay(mPrimaryDisplay);
         ASSERT_NO_FATAL_FAILURE(
                 mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
 
-        ReadbackBufferAttributes readBackBufferAttributes;
-        const auto error = mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay,
-                                                                        &readBackBufferAttributes);
-
-        mPixelFormat = readBackBufferAttributes.format;
-        mDataspace = readBackBufferAttributes.dataspace;
-        mHasReadbackBuffer =
-                error.isOk() && ReadbackHelper::readbackSupported(mPixelFormat, mDataspace);
-
-        if (!mHasReadbackBuffer) {
+        if (!getHasReadbackBuffer()) {
             GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
             return;
         }
@@ -375,7 +367,7 @@
         mGraphicBuffer->reallocate(static_cast<uint32_t>(mDisplayWidth),
                                    static_cast<uint32_t>(mDisplayHeight), 1,
                                    static_cast<uint32_t>(common::PixelFormat::RGBA_8888), usage);
-        mWriter->setLayerBuffer(0, mGraphicBuffer->handle, -1);
+        mWriter.setLayerBuffer(mPrimaryDisplay, layer->getLayer(), 0, mGraphicBuffer->handle, -1);
 
         // expected color for each pixel
         std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
@@ -385,48 +377,97 @@
                                       mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace);
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
 
-        mWriter->validateDisplay();
+        mWriter.validateDisplay(mPrimaryDisplay);
         execute();
 
-        if (mReader->mCompositionChanges.size() != 0) {
-            clearCommandReaderState();
+        std::vector<int64_t> changedCompositionLayers;
+        std::vector<Composition> changedCompositionTypes;
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+                                            &changedCompositionTypes);
+        if (!changedCompositionLayers.empty()) {
             GTEST_SUCCEED();
             return;
         }
-        ASSERT_EQ(0, mReader->mErrors.size());
-        mWriter->presentDisplay();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.presentDisplay(mPrimaryDisplay);
         execute();
-        ASSERT_EQ(0, mReader->mErrors.size());
+        ASSERT_TRUE(mReader.takeErrors().empty());
 
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
     }
 }
 
+TEST_P(GraphicsCompositionTest, SetReadbackBuffer) {
+    if (!getHasReadbackBuffer()) {
+        GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+        return;
+    }
+
+    ReadbackBuffer readbackBuffer(mPrimaryDisplay, mComposerClient, mGraphicBuffer, mDisplayWidth,
+                                  mDisplayHeight, mPixelFormat, mDataspace);
+
+    ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+}
+
+TEST_P(GraphicsCompositionTest, SetReadbackBufferBadDisplay) {
+    if (!getHasReadbackBuffer()) {
+        GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+        return;
+    }
+
+    ASSERT_NE(nullptr, mGraphicBuffer);
+    ASSERT_EQ(::android::OK, mGraphicBuffer->initCheck());
+    aidl::android::hardware::common::NativeHandle bufferHandle =
+            ::android::dupToAidl(mGraphicBuffer->handle);
+    ::ndk::ScopedFileDescriptor fence = ::ndk::ScopedFileDescriptor(-1);
+
+    const auto error = mComposerClient->setReadbackBuffer(mInvalidDisplayId, bufferHandle, fence);
+
+    EXPECT_FALSE(error.isOk());
+    ASSERT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError());
+}
+
+TEST_P(GraphicsCompositionTest, SetReadbackBufferBadParameter) {
+    if (!getHasReadbackBuffer()) {
+        GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+        return;
+    }
+
+    aidl::android::hardware::common::NativeHandle bufferHandle = ::android::dupToAidl(nullptr);
+    ndk::ScopedFileDescriptor releaseFence = ndk::ScopedFileDescriptor(-1);
+    const auto error =
+            mComposerClient->setReadbackBuffer(mPrimaryDisplay, bufferHandle, releaseFence);
+
+    EXPECT_FALSE(error.isOk());
+    ASSERT_EQ(IComposerClient::EX_BAD_PARAMETER, error.getServiceSpecificError());
+}
+
+TEST_P(GraphicsCompositionTest, GetReadbackBufferFenceInactive) {
+    if (!getHasReadbackBuffer()) {
+        GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
+        return;
+    }
+
+    ndk::ScopedFileDescriptor releaseFence;
+    const auto error = mComposerClient->getReadbackBufferFence(mPrimaryDisplay, &releaseFence);
+
+    EXPECT_TRUE(error.isOk());
+    EXPECT_EQ(IComposerClient::EX_UNSUPPORTED, error.getServiceSpecificError());
+}
+
 TEST_P(GraphicsCompositionTest, ClientComposition) {
     EXPECT_TRUE(mComposerClient->setClientTargetSlotCount(mPrimaryDisplay, kClientTargetSlotCount)
                         .isOk());
 
     for (ColorMode mode : mTestColorModes) {
-        mWriter->selectDisplay(mPrimaryDisplay);
         EXPECT_TRUE(mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC)
                             .isOk());
 
-        ReadbackBufferAttributes readBackBufferAttributes;
-        const auto error = mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay,
-                                                                        &readBackBufferAttributes);
-
-        mPixelFormat = readBackBufferAttributes.format;
-        mDataspace = readBackBufferAttributes.dataspace;
-        mHasReadbackBuffer =
-                error.isOk() && ReadbackHelper::readbackSupported(mPixelFormat, mDataspace);
-
-        if (!mHasReadbackBuffer) {
+        if (!getHasReadbackBuffer()) {
             GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
             return;
         }
 
-        mWriter->selectDisplay(mPrimaryDisplay);
-
         std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
         ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
                                        {0, 0, mDisplayWidth, mDisplayHeight / 4}, RED);
@@ -450,13 +491,18 @@
                                       mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace);
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
         writeLayers(layers);
-        ASSERT_EQ(0, mReader->mErrors.size());
-        mWriter->validateDisplay();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.validateDisplay(mPrimaryDisplay);
         execute();
 
-        if (!mReader->mCompositionChanges.empty()) {
-            ASSERT_EQ(1, mReader->mCompositionChanges.size());
-            ASSERT_EQ(1, mReader->mCompositionChanges[0].second);
+        std::vector<int64_t> changedCompositionLayers;
+        std::vector<Composition> changedCompositionTypes;
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+                                            &changedCompositionTypes);
+        if (!changedCompositionLayers.empty()) {
+            ASSERT_EQ(1, changedCompositionLayers.size());
+            ASSERT_EQ(1, changedCompositionTypes.size());
+            ASSERT_EQ(Composition::CLIENT, changedCompositionTypes[0]);
 
             PixelFormat clientFormat = PixelFormat::RGBA_8888;
             auto clientUsage = static_cast<uint32_t>(
@@ -487,18 +533,20 @@
                     mComposerClient->getReadbackBufferFence(mPrimaryDisplay, &fenceHandle).isOk());
 
             layer->setToClientComposition(mWriter);
-            mWriter->acceptDisplayChanges();
-            mWriter->setClientTarget(0, mGraphicBuffer->handle, fenceHandle.get(), clientDataspace,
-                                     std::vector<common::Rect>(1, damage));
+            mWriter.acceptDisplayChanges(mPrimaryDisplay);
+            mWriter.setClientTarget(mPrimaryDisplay, 0, mGraphicBuffer->handle, fenceHandle.get(),
+                                    clientDataspace, std::vector<common::Rect>(1, damage));
             execute();
-            ASSERT_EQ(0, mReader->mCompositionChanges.size());
+            mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+                                                &changedCompositionTypes);
+            ASSERT_TRUE(changedCompositionLayers.empty());
         }
-        ASSERT_EQ(0, mReader->mErrors.size());
+        ASSERT_TRUE(mReader.takeErrors().empty());
 
-        mWriter->presentDisplay();
+        mWriter.presentDisplay(mPrimaryDisplay);
         execute();
 
-        ASSERT_EQ(0, mReader->mErrors.size());
+        ASSERT_TRUE(mReader.takeErrors().empty());
 
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
     }
@@ -509,20 +557,10 @@
             mComposerClient->setClientTargetSlotCount(mPrimaryDisplay, kClientTargetSlotCount));
 
     for (ColorMode mode : mTestColorModes) {
-        mWriter->selectDisplay(mPrimaryDisplay);
         ASSERT_NO_FATAL_FAILURE(
                 mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
 
-        ReadbackBufferAttributes readBackBufferAttributes;
-        const auto error = mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay,
-                                                                        &readBackBufferAttributes);
-
-        mPixelFormat = readBackBufferAttributes.format;
-        mDataspace = readBackBufferAttributes.dataspace;
-        mHasReadbackBuffer =
-                error.isOk() && ReadbackHelper::readbackSupported(mPixelFormat, mDataspace);
-
-        if (!mHasReadbackBuffer) {
+        if (!getHasReadbackBuffer()) {
             GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
             return;
         }
@@ -568,15 +606,18 @@
         clientLayer->setDisplayFrame(clientFrame);
         clientLayer->setZOrder(0);
         clientLayer->write(mWriter);
-        mWriter->validateDisplay();
+        mWriter.validateDisplay(mPrimaryDisplay);
         execute();
 
-        if (mReader->mCompositionChanges.size() != 1) {
-            mReader->mCompositionChanges.clear();
+        std::vector<int64_t> changedCompositionLayers;
+        std::vector<Composition> changedCompositionTypes;
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+                                            &changedCompositionTypes);
+        if (changedCompositionTypes.size() != 1) {
             continue;
         }
         // create client target buffer
-        ASSERT_EQ(1, mReader->mCompositionChanges[0].second);
+        ASSERT_EQ(Composition::CLIENT, changedCompositionTypes[0]);
         mGraphicBuffer->reallocate(static_cast<uint32_t>(mDisplayWidth),
                                    static_cast<uint32_t>(mDisplayHeight),
                                    static_cast<int32_t>(common::PixelFormat::RGBA_8888),
@@ -597,42 +638,32 @@
         EXPECT_TRUE(mComposerClient->getReadbackBufferFence(mPrimaryDisplay, &fenceHandle).isOk());
 
         clientLayer->setToClientComposition(mWriter);
-        mWriter->acceptDisplayChanges();
-        mWriter->setClientTarget(0, mGraphicBuffer->handle, fenceHandle.get(), clientDataspace,
-                                 std::vector<common::Rect>(1, clientFrame));
+        mWriter.acceptDisplayChanges(mPrimaryDisplay);
+        mWriter.setClientTarget(mPrimaryDisplay, 0, mGraphicBuffer->handle, fenceHandle.get(),
+                                clientDataspace, std::vector<common::Rect>(1, clientFrame));
         execute();
-        ASSERT_EQ(0, mReader->mCompositionChanges.size());
-        ASSERT_EQ(0, mReader->mErrors.size());
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+                                            &changedCompositionTypes);
+        ASSERT_EQ(0, changedCompositionLayers.size());
+        ASSERT_TRUE(mReader.takeErrors().empty());
 
-        mWriter->presentDisplay();
+        mWriter.presentDisplay(mPrimaryDisplay);
         execute();
-        ASSERT_EQ(0, mReader->mErrors.size());
+        ASSERT_TRUE(mReader.takeErrors().empty());
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
     }
 }
 
 TEST_P(GraphicsCompositionTest, SetLayerDamage) {
     for (ColorMode mode : mTestColorModes) {
-        mWriter->selectDisplay(mPrimaryDisplay);
         ASSERT_NO_FATAL_FAILURE(
                 mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
 
-        ReadbackBufferAttributes readBackBufferAttributes;
-        const auto error = mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay,
-                                                                        &readBackBufferAttributes);
-
-        mPixelFormat = readBackBufferAttributes.format;
-        mDataspace = readBackBufferAttributes.dataspace;
-        mHasReadbackBuffer =
-                error.isOk() && ReadbackHelper::readbackSupported(mPixelFormat, mDataspace);
-
-        if (!mHasReadbackBuffer) {
+        if (!getHasReadbackBuffer()) {
             GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
             return;
         }
 
-        mWriter->selectDisplay(mPrimaryDisplay);
-
         common::Rect redRect = {0, 0, mDisplayWidth / 4, mDisplayHeight / 4};
 
         std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
@@ -653,18 +684,21 @@
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
 
         writeLayers(layers);
-        ASSERT_EQ(0, mReader->mErrors.size());
-        mWriter->validateDisplay();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.validateDisplay(mPrimaryDisplay);
         execute();
-        if (mReader->mCompositionChanges.size() != 0) {
-            clearCommandReaderState();
+        std::vector<int64_t> changedCompositionLayers;
+        std::vector<Composition> changedCompositionTypes;
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+                                            &changedCompositionTypes);
+        if (!changedCompositionLayers.empty()) {
             GTEST_SUCCEED();
             return;
         }
-        ASSERT_EQ(0, mReader->mErrors.size());
-        mWriter->presentDisplay();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.presentDisplay(mPrimaryDisplay);
         execute();
-        ASSERT_EQ(0, mReader->mErrors.size());
+        ASSERT_TRUE(mReader.takeErrors().empty());
 
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
 
@@ -680,14 +714,17 @@
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
 
         writeLayers(layers);
-        ASSERT_EQ(0, mReader->mErrors.size());
-        mWriter->validateDisplay();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.validateDisplay(mPrimaryDisplay);
         execute();
-        ASSERT_EQ(0, mReader->mErrors.size());
-        ASSERT_EQ(0, mReader->mCompositionChanges.size());
-        mWriter->presentDisplay();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+                                            &changedCompositionTypes);
+        ASSERT_TRUE(changedCompositionLayers.empty());
+        ASSERT_TRUE(changedCompositionTypes.empty());
+        mWriter.presentDisplay(mPrimaryDisplay);
         execute();
-        ASSERT_EQ(0, mReader->mErrors.size());
+        ASSERT_TRUE(mReader.takeErrors().empty());
 
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
     }
@@ -695,20 +732,10 @@
 
 TEST_P(GraphicsCompositionTest, SetLayerPlaneAlpha) {
     for (ColorMode mode : mTestColorModes) {
-        mWriter->selectDisplay(mPrimaryDisplay);
         ASSERT_NO_FATAL_FAILURE(
                 mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
 
-        ReadbackBufferAttributes readBackBufferAttributes;
-        const auto error = mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay,
-                                                                        &readBackBufferAttributes);
-
-        mPixelFormat = readBackBufferAttributes.format;
-        mDataspace = readBackBufferAttributes.dataspace;
-        mHasReadbackBuffer =
-                error.isOk() && ReadbackHelper::readbackSupported(mPixelFormat, mDataspace);
-
-        if (!mHasReadbackBuffer) {
+        if (!getHasReadbackBuffer()) {
             GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
             return;
         }
@@ -728,19 +755,22 @@
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
 
         writeLayers(layers);
-        ASSERT_EQ(0, mReader->mErrors.size());
-        mWriter->validateDisplay();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.validateDisplay(mPrimaryDisplay);
         execute();
-        if (mReader->mCompositionChanges.size() != 0) {
-            clearCommandReaderState();
+        std::vector<int64_t> changedCompositionLayers;
+        std::vector<Composition> changedCompositionTypes;
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+                                            &changedCompositionTypes);
+        if (!changedCompositionLayers.empty()) {
             GTEST_SUCCEED();
             return;
         }
-        ASSERT_EQ(0, mReader->mErrors.size());
+        ASSERT_TRUE(mReader.takeErrors().empty());
 
-        mWriter->presentDisplay();
+        mWriter.presentDisplay(mPrimaryDisplay);
         execute();
-        ASSERT_EQ(0, mReader->mErrors.size());
+        ASSERT_TRUE(mReader.takeErrors().empty());
 
         std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
 
@@ -753,26 +783,14 @@
 
 TEST_P(GraphicsCompositionTest, SetLayerSourceCrop) {
     for (ColorMode mode : mTestColorModes) {
-        mWriter->selectDisplay(mPrimaryDisplay);
         ASSERT_NO_FATAL_FAILURE(
                 mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
 
-        ReadbackBufferAttributes readBackBufferAttributes;
-        const auto error = mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay,
-                                                                        &readBackBufferAttributes);
-
-        mPixelFormat = readBackBufferAttributes.format;
-        mDataspace = readBackBufferAttributes.dataspace;
-        mHasReadbackBuffer =
-                error.isOk() && ReadbackHelper::readbackSupported(mPixelFormat, mDataspace);
-
-        if (!mHasReadbackBuffer) {
+        if (!getHasReadbackBuffer()) {
             GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
             return;
         }
 
-        mWriter->selectDisplay(mPrimaryDisplay);
-
         std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
         ReadbackHelper::fillColorsArea(expectedColors, mDisplayWidth,
                                        {0, 0, mDisplayWidth, mDisplayHeight / 4}, RED);
@@ -800,18 +818,21 @@
                                       mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace);
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
         writeLayers(layers);
-        ASSERT_EQ(0, mReader->mErrors.size());
-        mWriter->validateDisplay();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.validateDisplay(mPrimaryDisplay);
         execute();
-        if (mReader->mCompositionChanges.size() != 0) {
-            clearCommandReaderState();
+        std::vector<int64_t> changedCompositionLayers;
+        std::vector<Composition> changedCompositionTypes;
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+                                            &changedCompositionTypes);
+        if (!changedCompositionLayers.empty()) {
             GTEST_SUCCEED();
             return;
         }
-        ASSERT_EQ(0, mReader->mErrors.size());
-        mWriter->presentDisplay();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.presentDisplay(mPrimaryDisplay);
         execute();
-        ASSERT_EQ(0, mReader->mErrors.size());
+        ASSERT_TRUE(mReader.takeErrors().empty());
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
         mTestRenderEngine->setRenderLayers(layers);
         ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
@@ -821,20 +842,10 @@
 
 TEST_P(GraphicsCompositionTest, SetLayerZOrder) {
     for (ColorMode mode : mTestColorModes) {
-        mWriter->selectDisplay(mPrimaryDisplay);
         ASSERT_NO_FATAL_FAILURE(
                 mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
 
-        ReadbackBufferAttributes readBackBufferAttributes;
-        const auto error = mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay,
-                                                                        &readBackBufferAttributes);
-
-        mPixelFormat = readBackBufferAttributes.format;
-        mDataspace = readBackBufferAttributes.dataspace;
-        mHasReadbackBuffer =
-                error.isOk() && ReadbackHelper::readbackSupported(mPixelFormat, mDataspace);
-
-        if (!mHasReadbackBuffer) {
+        if (!getHasReadbackBuffer()) {
             GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
             return;
         }
@@ -865,17 +876,20 @@
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
 
         writeLayers(layers);
-        ASSERT_EQ(0, mReader->mErrors.size());
-        mWriter->validateDisplay();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.validateDisplay(mPrimaryDisplay);
         execute();
-        if (mReader->mCompositionChanges.size() != 0) {
-            clearCommandReaderState();
+        std::vector<int64_t> changedCompositionLayers;
+        std::vector<Composition> changedCompositionTypes;
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+                                            &changedCompositionTypes);
+        if (!changedCompositionLayers.empty()) {
             GTEST_SUCCEED();
             return;
         }
-        mWriter->presentDisplay();
+        mWriter.presentDisplay(mPrimaryDisplay);
         execute();
-        ASSERT_EQ(0, mReader->mErrors.size());
+        ASSERT_TRUE(mReader.takeErrors().empty());
 
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
 
@@ -887,14 +901,17 @@
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
 
         writeLayers(layers);
-        ASSERT_EQ(0, mReader->mErrors.size());
-        mWriter->validateDisplay();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.validateDisplay(mPrimaryDisplay);
         execute();
-        ASSERT_EQ(0, mReader->mCompositionChanges.size());
-        ASSERT_EQ(0, mReader->mErrors.size());
-        mWriter->presentDisplay();
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+                                            &changedCompositionTypes);
+        ASSERT_TRUE(changedCompositionLayers.empty());
+        ASSERT_TRUE(changedCompositionTypes.empty());
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.presentDisplay(mPrimaryDisplay);
         execute();
-        ASSERT_EQ(0, mReader->mErrors.size());
+        ASSERT_TRUE(mReader.takeErrors().empty());
 
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
         mTestRenderEngine->setRenderLayers(layers);
@@ -990,26 +1007,14 @@
 
 TEST_P(GraphicsBlendModeCompositionTest, None) {
     for (ColorMode mode : mTestColorModes) {
-        mWriter->selectDisplay(mPrimaryDisplay);
         ASSERT_NO_FATAL_FAILURE(
                 mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
 
-        ReadbackBufferAttributes readBackBufferAttributes;
-        const auto error = mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay,
-                                                                        &readBackBufferAttributes);
-
-        mPixelFormat = readBackBufferAttributes.format;
-        mDataspace = readBackBufferAttributes.dataspace;
-        mHasReadbackBuffer =
-                error.isOk() && ReadbackHelper::readbackSupported(mPixelFormat, mDataspace);
-
-        if (!mHasReadbackBuffer) {
+        if (!getHasReadbackBuffer()) {
             GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
             return;
         }
 
-        mWriter->selectDisplay(mPrimaryDisplay);
-
         std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
 
         setBackgroundColor(BLACK);
@@ -1021,18 +1026,21 @@
                                       mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace);
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
         writeLayers(mLayers);
-        ASSERT_EQ(0, mReader->mErrors.size());
-        mWriter->validateDisplay();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.validateDisplay(mPrimaryDisplay);
         execute();
-        if (mReader->mCompositionChanges.size() != 0) {
-            clearCommandReaderState();
+        std::vector<int64_t> changedCompositionLayers;
+        std::vector<Composition> changedCompositionTypes;
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+                                            &changedCompositionTypes);
+        if (!changedCompositionLayers.empty()) {
             GTEST_SUCCEED();
             return;
         }
-        ASSERT_EQ(0, mReader->mErrors.size());
-        mWriter->presentDisplay();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.presentDisplay(mPrimaryDisplay);
         execute();
-        ASSERT_EQ(0, mReader->mErrors.size());
+        ASSERT_TRUE(mReader.takeErrors().empty());
 
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
         mTestRenderEngine->setRenderLayers(mLayers);
@@ -1043,26 +1051,14 @@
 
 TEST_P(GraphicsBlendModeCompositionTest, Coverage) {
     for (ColorMode mode : mTestColorModes) {
-        mWriter->selectDisplay(mPrimaryDisplay);
         ASSERT_NO_FATAL_FAILURE(
                 mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
 
-        ReadbackBufferAttributes readBackBufferAttributes;
-        const auto error = mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay,
-                                                                        &readBackBufferAttributes);
-
-        mPixelFormat = readBackBufferAttributes.format;
-        mDataspace = readBackBufferAttributes.dataspace;
-        mHasReadbackBuffer =
-                error.isOk() && ReadbackHelper::readbackSupported(mPixelFormat, mDataspace);
-
-        if (!mHasReadbackBuffer) {
+        if (!getHasReadbackBuffer()) {
             GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
             return;
         }
 
-        mWriter->selectDisplay(mPrimaryDisplay);
-
         std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
 
         setBackgroundColor(BLACK);
@@ -1075,42 +1071,34 @@
                                       mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace);
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
         writeLayers(mLayers);
-        ASSERT_EQ(0, mReader->mErrors.size());
-        mWriter->validateDisplay();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.validateDisplay(mPrimaryDisplay);
         execute();
-        if (mReader->mCompositionChanges.size() != 0) {
-            clearCommandReaderState();
+        std::vector<int64_t> changedCompositionLayers;
+        std::vector<Composition> changedCompositionTypes;
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+                                            &changedCompositionTypes);
+        if (!changedCompositionLayers.empty()) {
             GTEST_SUCCEED();
             return;
         }
-        ASSERT_EQ(0, mReader->mErrors.size());
-        mWriter->presentDisplay();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.presentDisplay(mPrimaryDisplay);
         execute();
-        ASSERT_EQ(0, mReader->mErrors.size());
+        ASSERT_TRUE(mReader.takeErrors().empty());
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
     }
 }
 
 TEST_P(GraphicsBlendModeCompositionTest, Premultiplied) {
     for (ColorMode mode : mTestColorModes) {
-        mWriter->selectDisplay(mPrimaryDisplay);
         ASSERT_NO_FATAL_FAILURE(
                 mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
 
-        ReadbackBufferAttributes readBackBufferAttributes;
-        const auto error = mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay,
-                                                                        &readBackBufferAttributes);
-
-        mPixelFormat = readBackBufferAttributes.format;
-        mDataspace = readBackBufferAttributes.dataspace;
-        mHasReadbackBuffer =
-                error.isOk() && ReadbackHelper::readbackSupported(mPixelFormat, mDataspace);
-
-        if (!mHasReadbackBuffer) {
+        if (!getHasReadbackBuffer()) {
             GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
             return;
         }
-        mWriter->selectDisplay(mPrimaryDisplay);
 
         std::vector<Color> expectedColors(static_cast<size_t>(mDisplayWidth * mDisplayHeight));
 
@@ -1123,18 +1111,21 @@
                                       mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace);
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
         writeLayers(mLayers);
-        ASSERT_EQ(0, mReader->mErrors.size());
-        mWriter->validateDisplay();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.validateDisplay(mPrimaryDisplay);
         execute();
-        if (mReader->mCompositionChanges.size() != 0) {
-            clearCommandReaderState();
+        std::vector<int64_t> changedCompositionLayers;
+        std::vector<Composition> changedCompositionTypes;
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+                                            &changedCompositionTypes);
+        if (!changedCompositionLayers.empty()) {
             GTEST_SUCCEED();
             return;
         }
-        ASSERT_EQ(0, mReader->mErrors.size());
-        mWriter->presentDisplay();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.presentDisplay(mPrimaryDisplay);
         execute();
-        ASSERT_EQ(0, mReader->mErrors.size());
+        ASSERT_TRUE(mReader.takeErrors().empty());
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
         mTestRenderEngine->setRenderLayers(mLayers);
         ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
@@ -1146,7 +1137,7 @@
   protected:
     void SetUp() override {
         GraphicsCompositionTest::SetUp();
-        mWriter->selectDisplay(mPrimaryDisplay);
+
         auto backgroundLayer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay);
         backgroundLayer->setColor({0, 0, 0, 0});
         backgroundLayer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
@@ -1177,8 +1168,6 @@
 
 TEST_P(GraphicsTransformCompositionTest, FLIP_H) {
     for (ColorMode mode : mTestColorModes) {
-        ASSERT_NE(nullptr, mWriter);
-        mWriter->selectDisplay(mPrimaryDisplay);
         auto error =
                 mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC);
         if (!error.isOk() &&
@@ -1188,16 +1177,7 @@
             return;
         }
 
-        ReadbackBufferAttributes readBackBufferAttributes;
-        error = mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay,
-                                                             &readBackBufferAttributes);
-
-        mPixelFormat = readBackBufferAttributes.format;
-        mDataspace = readBackBufferAttributes.dataspace;
-        mHasReadbackBuffer =
-                error.isOk() && ReadbackHelper::readbackSupported(mPixelFormat, mDataspace);
-
-        if (!mHasReadbackBuffer) {
+        if (!getHasReadbackBuffer()) {
             GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
             return;
         }
@@ -1214,18 +1194,21 @@
                                        {0, mSideLength / 2, mSideLength / 2, mSideLength}, BLUE);
 
         writeLayers(mLayers);
-        ASSERT_EQ(0, mReader->mErrors.size());
-        mWriter->validateDisplay();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.validateDisplay(mPrimaryDisplay);
         execute();
-        if (mReader->mCompositionChanges.size() != 0) {
-            clearCommandReaderState();
+        std::vector<int64_t> changedCompositionLayers;
+        std::vector<Composition> changedCompositionTypes;
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+                                            &changedCompositionTypes);
+        if (!changedCompositionLayers.empty()) {
             GTEST_SUCCEED();
             return;
         }
-        ASSERT_EQ(0, mReader->mErrors.size());
-        mWriter->presentDisplay();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.presentDisplay(mPrimaryDisplay);
         execute();
-        ASSERT_EQ(0, mReader->mErrors.size());
+        ASSERT_TRUE(mReader.takeErrors().empty());
 
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
         mTestRenderEngine->setRenderLayers(mLayers);
@@ -1236,20 +1219,10 @@
 
 TEST_P(GraphicsTransformCompositionTest, FLIP_V) {
     for (ColorMode mode : mTestColorModes) {
-        mWriter->selectDisplay(mPrimaryDisplay);
         ASSERT_NO_FATAL_FAILURE(
                 mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
 
-        ReadbackBufferAttributes readBackBufferAttributes;
-        const auto error = mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay,
-                                                                        &readBackBufferAttributes);
-
-        mPixelFormat = readBackBufferAttributes.format;
-        mDataspace = readBackBufferAttributes.dataspace;
-        mHasReadbackBuffer =
-                error.isOk() && ReadbackHelper::readbackSupported(mPixelFormat, mDataspace);
-
-        if (!mHasReadbackBuffer) {
+        if (!getHasReadbackBuffer()) {
             GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
             return;
         }
@@ -1267,18 +1240,21 @@
                                        {mSideLength / 2, 0, mSideLength, mSideLength / 2}, BLUE);
 
         writeLayers(mLayers);
-        ASSERT_EQ(0, mReader->mErrors.size());
-        mWriter->validateDisplay();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.validateDisplay(mPrimaryDisplay);
         execute();
-        if (mReader->mCompositionChanges.size() != 0) {
-            clearCommandReaderState();
+        std::vector<int64_t> changedCompositionLayers;
+        std::vector<Composition> changedCompositionTypes;
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
+                                            &changedCompositionTypes);
+        if (!changedCompositionLayers.empty()) {
             GTEST_SUCCEED();
             return;
         }
-        ASSERT_EQ(0, mReader->mErrors.size());
-        mWriter->presentDisplay();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.presentDisplay(mPrimaryDisplay);
         execute();
-        ASSERT_EQ(0, mReader->mErrors.size());
+        ASSERT_TRUE(mReader.takeErrors().empty());
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
         mTestRenderEngine->setRenderLayers(mLayers);
         ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
@@ -1288,19 +1264,10 @@
 
 TEST_P(GraphicsTransformCompositionTest, ROT_180) {
     for (ColorMode mode : mTestColorModes) {
-        mWriter->selectDisplay(mPrimaryDisplay);
         ASSERT_NO_FATAL_FAILURE(
                 mComposerClient->setColorMode(mPrimaryDisplay, mode, RenderIntent::COLORIMETRIC));
 
-        ReadbackBufferAttributes readBackBufferAttributes;
-        const auto error = mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay,
-                                                                        &readBackBufferAttributes);
-
-        mPixelFormat = readBackBufferAttributes.format;
-        mDataspace = readBackBufferAttributes.dataspace;
-        mHasReadbackBuffer =
-                error.isOk() && ReadbackHelper::readbackSupported(mPixelFormat, mDataspace);
-        if (!mHasReadbackBuffer) {
+        if (!getHasReadbackBuffer()) {
             GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
             return;
         }
@@ -1319,18 +1286,20 @@
                                        {0, 0, mSideLength / 2, mSideLength / 2}, BLUE);
 
         writeLayers(mLayers);
-        ASSERT_EQ(0, mReader->mErrors.size());
-        mWriter->validateDisplay();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.validateDisplay(mPrimaryDisplay);
         execute();
-        if (!mReader->mCompositionChanges.empty()) {
-            clearCommandReaderState();
+        std::vector<int64_t> layers;
+        std::vector<Composition> types;
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &layers, &types);
+        if (!layers.empty()) {
             GTEST_SUCCEED();
             return;
         }
-        ASSERT_EQ(0, mReader->mErrors.size());
-        mWriter->presentDisplay();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.presentDisplay(mPrimaryDisplay);
         execute();
-        ASSERT_EQ(0, mReader->mErrors.size());
+        ASSERT_TRUE(mReader.takeErrors().empty());
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
         mTestRenderEngine->setRenderLayers(mLayers);
         ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
@@ -1357,4 +1326,4 @@
         ::android::PrintInstanceNameToString);
 
 }  // namespace
-}  // namespace aidl::android::hardware::graphics::composer3::vts
\ No newline at end of file
+}  // namespace aidl::android::hardware::graphics::composer3::vts
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp
index b9460c8..1f30475 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp
@@ -4,16 +4,17 @@
 
 #include <aidl/Gtest.h>
 #include <aidl/Vintf.h>
+#include <aidl/android/hardware/graphics/common/BlendMode.h>
 #include <aidl/android/hardware/graphics/common/BufferUsage.h>
 #include <aidl/android/hardware/graphics/common/FRect.h>
 #include <aidl/android/hardware/graphics/common/Rect.h>
-#include <aidl/android/hardware/graphics/composer3/BlendMode.h>
 #include <aidl/android/hardware/graphics/composer3/Composition.h>
 #include <aidl/android/hardware/graphics/composer3/IComposer.h>
 #include <android-base/properties.h>
 #include <android/binder_manager.h>
 #include <android/binder_process.h>
-#include <android/hardware/graphics/composer3/command-buffer.h>
+#include <android/hardware/graphics/composer3/ComposerClientReader.h>
+#include <android/hardware/graphics/composer3/ComposerClientWriter.h>
 #include <binder/ProcessState.h>
 #include <gtest/gtest.h>
 #include <ui/GraphicBuffer.h>
@@ -27,7 +28,6 @@
 #include <unordered_set>
 #include <utility>
 #include "composer-vts/include/GraphicsComposerCallback.h"
-#include "composer-vts/include/TestCommandReader.h"
 
 // TODO(b/129481165): remove the #pragma below and fix conversion issues
 #pragma clang diagnostic pop  // ignored "-Wconversion
@@ -567,25 +567,6 @@
     }
 }
 
-TEST_P(GraphicsComposerAidlTest, getDisplayCapabilitiesBasic) {
-    std::vector<DisplayCapability> capabilities;
-    const auto error = mComposerClient->getDisplayCapabilities(mPrimaryDisplay, &capabilities);
-    ASSERT_TRUE(error.isOk());
-    const bool hasDozeSupport = std::find(capabilities.begin(), capabilities.end(),
-                                          DisplayCapability::DOZE) != capabilities.end();
-    bool isDozeSupported = false;
-    EXPECT_TRUE(mComposerClient->getDozeSupport(mPrimaryDisplay, &isDozeSupported).isOk());
-    EXPECT_EQ(hasDozeSupport, isDozeSupported);
-
-    bool hasBrightnessSupport = std::find(capabilities.begin(), capabilities.end(),
-                                          DisplayCapability::BRIGHTNESS) != capabilities.end();
-    bool isBrightnessSupported = false;
-    EXPECT_TRUE(
-            mComposerClient->getDisplayBrightnessSupport(mPrimaryDisplay, &isBrightnessSupported)
-                    .isOk());
-    EXPECT_EQ(isBrightnessSupported, hasBrightnessSupport);
-}
-
 /*
  * Test that if brightness operations are supported, setDisplayBrightness works as expected.
  */
@@ -1010,16 +991,14 @@
     }
 }
 
-TEST_P(GraphicsComposerAidlTest, GetDozeSupportBadDisplay) {
-    bool isDozeSupport;
-    const auto error = mComposerClient->getDozeSupport(mInvalidDisplayId, &isDozeSupport);
-    EXPECT_FALSE(error.isOk());
-    ASSERT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError());
-}
-
 TEST_P(GraphicsComposerAidlTest, SetPowerModeUnsupported) {
-    bool isDozeSupported;
-    mComposerClient->getDozeSupport(mPrimaryDisplay, &isDozeSupported).isOk();
+    std::vector<DisplayCapability> capabilities;
+    const auto error = mComposerClient->getDisplayCapabilities(mPrimaryDisplay, &capabilities);
+    ASSERT_TRUE(error.isOk());
+    const bool isDozeSupported = std::find(capabilities.begin(), capabilities.end(),
+                                           DisplayCapability::DOZE) != capabilities.end();
+    const bool isSuspendSupported = std::find(capabilities.begin(), capabilities.end(),
+                                              DisplayCapability::SUSPEND) != capabilities.end();
     if (!isDozeSupported) {
         auto error = mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::DOZE);
         EXPECT_FALSE(error.isOk());
@@ -1029,6 +1008,16 @@
         EXPECT_FALSE(error.isOk());
         EXPECT_EQ(IComposerClient::EX_UNSUPPORTED, error.getServiceSpecificError());
     }
+
+    if (!isSuspendSupported) {
+        auto error = mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::ON_SUSPEND);
+        EXPECT_FALSE(error.isOk());
+        EXPECT_EQ(IComposerClient::EX_UNSUPPORTED, error.getServiceSpecificError());
+
+        error = mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::DOZE_SUSPEND);
+        EXPECT_FALSE(error.isOk());
+        EXPECT_EQ(IComposerClient::EX_UNSUPPORTED, error.getServiceSpecificError());
+    }
 }
 
 TEST_P(GraphicsComposerAidlTest, SetVsyncEnabled) {
@@ -1042,15 +1031,27 @@
 }
 
 TEST_P(GraphicsComposerAidlTest, SetPowerMode) {
+    std::vector<DisplayCapability> capabilities;
+    const auto error = mComposerClient->getDisplayCapabilities(mPrimaryDisplay, &capabilities);
+    ASSERT_TRUE(error.isOk());
+    const bool isDozeSupported = std::find(capabilities.begin(), capabilities.end(),
+                                           DisplayCapability::DOZE) != capabilities.end();
+    const bool isSuspendSupported = std::find(capabilities.begin(), capabilities.end(),
+                                              DisplayCapability::SUSPEND) != capabilities.end();
+
     std::vector<PowerMode> modes;
     modes.push_back(PowerMode::OFF);
-    modes.push_back(PowerMode::ON_SUSPEND);
     modes.push_back(PowerMode::ON);
 
-    bool isDozeSupported;
-    EXPECT_TRUE(mComposerClient->getDozeSupport(mPrimaryDisplay, &isDozeSupported).isOk());
+    if (isSuspendSupported) {
+        modes.push_back(PowerMode::ON_SUSPEND);
+    }
+
     if (isDozeSupported) {
         modes.push_back(PowerMode::DOZE);
+    }
+
+    if (isSuspendSupported && isDozeSupported) {
         modes.push_back(PowerMode::DOZE_SUSPEND);
     }
 
@@ -1060,6 +1061,14 @@
 }
 
 TEST_P(GraphicsComposerAidlTest, SetPowerModeVariations) {
+    std::vector<DisplayCapability> capabilities;
+    const auto error = mComposerClient->getDisplayCapabilities(mPrimaryDisplay, &capabilities);
+    ASSERT_TRUE(error.isOk());
+    const bool isDozeSupported = std::find(capabilities.begin(), capabilities.end(),
+                                           DisplayCapability::DOZE) != capabilities.end();
+    const bool isSuspendSupported = std::find(capabilities.begin(), capabilities.end(),
+                                              DisplayCapability::SUSPEND) != capabilities.end();
+
     std::vector<PowerMode> modes;
 
     modes.push_back(PowerMode::OFF);
@@ -1084,15 +1093,15 @@
     }
     modes.clear();
 
-    modes.push_back(PowerMode::ON_SUSPEND);
-    modes.push_back(PowerMode::ON_SUSPEND);
-    for (auto mode : modes) {
-        EXPECT_TRUE(mComposerClient->setPowerMode(mPrimaryDisplay, mode).isOk());
+    if (isSuspendSupported) {
+        modes.push_back(PowerMode::ON_SUSPEND);
+        modes.push_back(PowerMode::ON_SUSPEND);
+        for (auto mode : modes) {
+            EXPECT_TRUE(mComposerClient->setPowerMode(mPrimaryDisplay, mode).isOk());
+        }
+        modes.clear();
     }
-    modes.clear();
 
-    bool isDozeSupported = false;
-    ASSERT_TRUE(mComposerClient->getDozeSupport(mPrimaryDisplay, &isDozeSupported).isOk());
     if (isDozeSupported) {
         modes.push_back(PowerMode::DOZE);
         modes.push_back(PowerMode::DOZE);
@@ -1100,12 +1109,15 @@
             EXPECT_TRUE(mComposerClient->setPowerMode(mPrimaryDisplay, mode).isOk());
         }
         modes.clear();
+    }
 
+    if (isSuspendSupported && isDozeSupported) {
         modes.push_back(PowerMode::DOZE_SUSPEND);
         modes.push_back(PowerMode::DOZE_SUSPEND);
         for (auto mode : modes) {
             EXPECT_TRUE(mComposerClient->setPowerMode(mPrimaryDisplay, mode).isOk());
         }
+        modes.clear();
     }
 }
 
@@ -1148,45 +1160,33 @@
 // Tests for Command.
 class GraphicsComposerAidlCommandTest : public GraphicsComposerAidlTest {
   protected:
-    void SetUp() override {
-        ASSERT_NO_FATAL_FAILURE(GraphicsComposerAidlTest::SetUp());
-
-        mWriter = std::make_unique<CommandWriterBase>(1024);
-        mReader = std::make_unique<TestCommandReader>();
-    }
-
     void TearDown() override {
-        ASSERT_EQ(0, mReader->mErrors.size());
-        ASSERT_EQ(0, mReader->mCompositionChanges.size());
+        const auto errors = mReader.takeErrors();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+
+        std::vector<int64_t> layers;
+        std::vector<Composition> types;
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &layers, &types);
+
+        ASSERT_TRUE(layers.empty());
+        ASSERT_TRUE(types.empty());
+
         ASSERT_NO_FATAL_FAILURE(GraphicsComposerAidlTest::TearDown());
     }
 
     void execute() {
-        TestCommandReader* reader = mReader.get();
-        CommandWriterBase* writer = mWriter.get();
-        bool queueChanged = false;
-        int32_t commandLength = 0;
-        std::vector<NativeHandle> commandHandles;
-        ASSERT_TRUE(writer->writeQueue(&queueChanged, &commandLength, &commandHandles));
-
-        if (queueChanged) {
-            auto ret = mComposerClient->setInputCommandQueue(writer->getMQDescriptor());
-            ASSERT_TRUE(ret.isOk());
+        const auto& commands = mWriter.getPendingCommands();
+        if (commands.empty()) {
+            mWriter.reset();
+            return;
         }
 
-        ExecuteCommandsStatus commandStatus;
-        EXPECT_TRUE(mComposerClient->executeCommands(commandLength, commandHandles, &commandStatus)
-                            .isOk());
+        std::vector<CommandResultPayload> results;
+        const auto status = mComposerClient->executeCommands(commands, &results);
+        ASSERT_TRUE(status.isOk()) << "executeCommands failed " << status.getDescription();
 
-        if (commandStatus.queueChanged) {
-            MQDescriptor<int32_t, SynchronizedReadWrite> outputCommandQueue;
-            ASSERT_TRUE(mComposerClient->getOutputCommandQueue(&outputCommandQueue).isOk());
-            reader->setMQDescriptor(outputCommandQueue);
-        }
-        ASSERT_TRUE(reader->readQueue(commandStatus.length, std::move(commandStatus.handles)));
-        reader->parse();
-        reader->reset();
-        writer->reset();
+        mReader.parse(results);
+        mWriter.reset();
     }
 
     static inline auto toTimePoint(nsecs_t time) {
@@ -1255,7 +1255,6 @@
             std::this_thread::sleep_until(toTimePoint(timeline->refreshTimeNanos));
         }
 
-        mWriter->selectDisplay(display.get());
         EXPECT_TRUE(mComposerClient->setPowerMode(display.get(), PowerMode::ON).isOk());
         EXPECT_TRUE(
                 mComposerClient
@@ -1265,47 +1264,46 @@
         int64_t layer = 0;
         ASSERT_NO_FATAL_FAILURE(layer = createLayer(display));
         {
-            auto buffer = allocate();
+            const auto buffer = allocate();
             ASSERT_NE(nullptr, buffer);
             ASSERT_EQ(::android::OK, buffer->initCheck());
             ASSERT_NE(nullptr, buffer->handle);
 
-            mWriter->selectLayer(layer);
-            mWriter->setLayerCompositionType(Composition::DEVICE);
-            mWriter->setLayerDisplayFrame(display.getFrameRect());
-            mWriter->setLayerPlaneAlpha(1);
-            mWriter->setLayerSourceCrop(display.getCrop());
-            mWriter->setLayerTransform(static_cast<Transform>(0));
-            mWriter->setLayerVisibleRegion(std::vector<Rect>(1, display.getFrameRect()));
-            mWriter->setLayerZOrder(10);
-            mWriter->setLayerBlendMode(BlendMode::NONE);
-            mWriter->setLayerSurfaceDamage(std::vector<Rect>(1, display.getFrameRect()));
-            mWriter->setLayerBuffer(0, buffer->handle, -1);
-            mWriter->setLayerDataspace(common::Dataspace::UNKNOWN);
+            mWriter.setLayerCompositionType(display.get(), layer, Composition::DEVICE);
+            mWriter.setLayerDisplayFrame(display.get(), layer, display.getFrameRect());
+            mWriter.setLayerPlaneAlpha(display.get(), layer, 1);
+            mWriter.setLayerSourceCrop(display.get(), layer, display.getCrop());
+            mWriter.setLayerTransform(display.get(), layer, static_cast<Transform>(0));
+            mWriter.setLayerVisibleRegion(display.get(), layer,
+                                          std::vector<Rect>(1, display.getFrameRect()));
+            mWriter.setLayerZOrder(display.get(), layer, 10);
+            mWriter.setLayerBlendMode(display.get(), layer, BlendMode::NONE);
+            mWriter.setLayerSurfaceDamage(display.get(), layer,
+                                          std::vector<Rect>(1, display.getFrameRect()));
+            mWriter.setLayerBuffer(display.get(), layer, 0, buffer->handle, -1);
+            mWriter.setLayerDataspace(display.get(), layer, common::Dataspace::UNKNOWN);
 
-            mWriter->validateDisplay();
+            mWriter.validateDisplay(display.get());
             execute();
-            ASSERT_EQ(0, mReader->mErrors.size());
-            mReader->mCompositionChanges.clear();
+            ASSERT_TRUE(mReader.takeErrors().empty());
 
-            mWriter->presentDisplay();
+            mWriter.presentDisplay(display.get());
             execute();
-            ASSERT_EQ(0, mReader->mErrors.size());
+            ASSERT_TRUE(mReader.takeErrors().empty());
         }
 
         {
-            auto buffer = allocate();
+            const auto buffer = allocate();
             ASSERT_NE(nullptr, buffer->handle);
 
-            mWriter->selectLayer(layer);
-            mWriter->setLayerBuffer(0, buffer->handle, -1);
-            mWriter->setLayerSurfaceDamage(std::vector<Rect>(1, {0, 0, 10, 10}));
-            mWriter->validateDisplay();
+            mWriter.setLayerBuffer(display.get(), layer, 0, buffer->handle, -1);
+            mWriter.setLayerSurfaceDamage(display.get(), layer,
+                                          std::vector<Rect>(1, {0, 0, 10, 10}));
+            mWriter.validateDisplay(display.get());
             execute();
-            ASSERT_EQ(0, mReader->mErrors.size());
-            mReader->mCompositionChanges.clear();
+            ASSERT_TRUE(mReader.takeErrors().empty());
 
-            mWriter->presentDisplay();
+            mWriter.presentDisplay(display.get());
             execute();
         }
 
@@ -1411,26 +1409,23 @@
     }};
     // clang-format on
 
-    std::unique_ptr<CommandWriterBase> mWriter;
-    std::unique_ptr<TestCommandReader> mReader;
+    ComposerClientWriter mWriter;
+    ComposerClientReader mReader;
 };
 
 TEST_P(GraphicsComposerAidlCommandTest, SET_COLOR_TRANSFORM) {
-    mWriter->selectDisplay(mPrimaryDisplay);
-    mWriter->setColorTransform(kIdentity.data(), ColorTransform::IDENTITY);
+    mWriter.setColorTransform(mPrimaryDisplay, kIdentity.data(), ColorTransform::IDENTITY);
     execute();
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SetLayerColorTransform) {
     int64_t layer;
     EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
-    mWriter->selectDisplay(mPrimaryDisplay);
-    mWriter->selectLayer(layer);
-    mWriter->setLayerColorTransform(kIdentity.data());
+    mWriter.setLayerColorTransform(mPrimaryDisplay, layer, kIdentity.data());
     execute();
 
-    if (mReader->mErrors.size() == 1 && mReader->mErrors[0].second == EX_UNSUPPORTED_OPERATION) {
-        mReader->mErrors.clear();
+    const auto errors = mReader.takeErrors();
+    if (errors.size() == 1 && errors[0].errorCode == EX_UNSUPPORTED_OPERATION) {
         GTEST_SUCCEED() << "setLayerColorTransform is not supported";
         return;
     }
@@ -1440,8 +1435,8 @@
     EXPECT_TRUE(
             mComposerClient->setClientTargetSlotCount(mPrimaryDisplay, kBufferSlotCount).isOk());
 
-    mWriter->selectDisplay(mPrimaryDisplay);
-    mWriter->setClientTarget(0, nullptr, -1, Dataspace::UNKNOWN, std::vector<Rect>());
+    mWriter.setClientTarget(mPrimaryDisplay, 0, nullptr, -1, Dataspace::UNKNOWN,
+                            std::vector<Rect>());
 
     execute();
 }
@@ -1460,30 +1455,27 @@
                                                kBufferSlotCount, &display)
                         .isOk());
 
-    mWriter->selectDisplay(display.display);
-    auto handle = allocate()->handle;
-    mWriter->setOutputBuffer(0, handle, -1);
+    const auto buffer = allocate();
+    const auto handle = buffer->handle;
+    mWriter.setOutputBuffer(display.display, 0, handle, -1);
     execute();
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, VALIDATE_DISPLAY) {
-    mWriter->selectDisplay(mPrimaryDisplay);
-    mWriter->validateDisplay();
+    mWriter.validateDisplay(mPrimaryDisplay);
     execute();
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, ACCEPT_DISPLAY_CHANGES) {
-    mWriter->selectDisplay(mPrimaryDisplay);
-    mWriter->validateDisplay();
-    mWriter->acceptDisplayChanges();
+    mWriter.validateDisplay(mPrimaryDisplay);
+    mWriter.acceptDisplayChanges(mPrimaryDisplay);
     execute();
 }
 
 // TODO(b/208441745) fix the test failure
 TEST_P(GraphicsComposerAidlCommandTest, PRESENT_DISPLAY) {
-    mWriter->selectDisplay(mPrimaryDisplay);
-    mWriter->validateDisplay();
-    mWriter->presentDisplay();
+    mWriter.validateDisplay(mPrimaryDisplay);
+    mWriter.presentDisplay(mPrimaryDisplay);
     execute();
 }
 
@@ -1503,7 +1495,6 @@
         GTEST_SUCCEED() << "Device does not have skip validate capability, skipping";
         return;
     }
-    mWriter->selectDisplay(mPrimaryDisplay);
     mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::ON);
 
     std::vector<RenderIntent> renderIntents;
@@ -1511,44 +1502,48 @@
     for (auto intent : renderIntents) {
         mComposerClient->setColorMode(mPrimaryDisplay, ColorMode::NATIVE, intent);
 
-        auto handle = allocate()->handle;
+        const auto buffer = allocate();
+        const auto handle = buffer->handle;
         ASSERT_NE(nullptr, handle);
 
         Rect displayFrame{0, 0, mDisplayWidth, mDisplayHeight};
 
         int64_t layer;
         EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
-        mWriter->selectLayer(layer);
-        mWriter->setLayerCompositionType(Composition::DEVICE);
-        mWriter->setLayerDisplayFrame(displayFrame);
-        mWriter->setLayerPlaneAlpha(1);
-        mWriter->setLayerSourceCrop({0, 0, (float)mDisplayWidth, (float)mDisplayHeight});
-        mWriter->setLayerTransform(static_cast<Transform>(0));
-        mWriter->setLayerVisibleRegion(std::vector<Rect>(1, displayFrame));
-        mWriter->setLayerZOrder(10);
-        mWriter->setLayerBlendMode(BlendMode::NONE);
-        mWriter->setLayerSurfaceDamage(std::vector<Rect>(1, displayFrame));
-        mWriter->setLayerBuffer(0, handle, -1);
-        mWriter->setLayerDataspace(Dataspace::UNKNOWN);
+        mWriter.setLayerCompositionType(mPrimaryDisplay, layer, Composition::DEVICE);
+        mWriter.setLayerDisplayFrame(mPrimaryDisplay, layer, displayFrame);
+        mWriter.setLayerPlaneAlpha(mPrimaryDisplay, layer, 1);
+        mWriter.setLayerSourceCrop(mPrimaryDisplay, layer,
+                                   {0, 0, (float)mDisplayWidth, (float)mDisplayHeight});
+        mWriter.setLayerTransform(mPrimaryDisplay, layer, static_cast<Transform>(0));
+        mWriter.setLayerVisibleRegion(mPrimaryDisplay, layer, std::vector<Rect>(1, displayFrame));
+        mWriter.setLayerZOrder(mPrimaryDisplay, layer, 10);
+        mWriter.setLayerBlendMode(mPrimaryDisplay, layer, BlendMode::NONE);
+        mWriter.setLayerSurfaceDamage(mPrimaryDisplay, layer, std::vector<Rect>(1, displayFrame));
+        mWriter.setLayerBuffer(mPrimaryDisplay, layer, 0, handle, -1);
+        mWriter.setLayerDataspace(mPrimaryDisplay, layer, Dataspace::UNKNOWN);
 
-        mWriter->validateDisplay();
+        mWriter.validateDisplay(mPrimaryDisplay);
         execute();
-        if (mReader->mCompositionChanges.size() != 0) {
+        std::vector<int64_t> layers;
+        std::vector<Composition> types;
+        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &layers, &types);
+        if (!layers.empty()) {
             GTEST_SUCCEED() << "Composition change requested, skipping test";
             return;
         }
 
-        ASSERT_EQ(0, mReader->mErrors.size());
-        mWriter->presentDisplay();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+        mWriter.presentDisplay(mPrimaryDisplay);
         execute();
-        ASSERT_EQ(0, mReader->mErrors.size());
+        ASSERT_TRUE(mReader.takeErrors().empty());
 
-        mWriter->selectLayer(layer);
-        auto handle2 = allocate()->handle;
+        const auto buffer2 = allocate();
+        const auto handle2 = buffer2->handle;
         ASSERT_NE(nullptr, handle2);
-        mWriter->setLayerBuffer(0, handle2, -1);
-        mWriter->setLayerSurfaceDamage(std::vector<Rect>(1, {0, 0, 10, 10}));
-        mWriter->presentDisplay();
+        mWriter.setLayerBuffer(mPrimaryDisplay, layer, 0, handle2, -1);
+        mWriter.setLayerSurfaceDamage(mPrimaryDisplay, layer, std::vector<Rect>(1, {0, 0, 10, 10}));
+        mWriter.presentDisplay(mPrimaryDisplay);
         execute();
     }
 }
@@ -1558,50 +1553,53 @@
     int64_t layer;
     EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
 
-    auto handle = allocate()->handle;
+    const auto buffer = allocate();
+    const auto handle = buffer->handle;
     ASSERT_NE(nullptr, handle);
     Rect displayFrame{0, 0, mDisplayWidth, mDisplayHeight};
 
-    mWriter->selectDisplay(mPrimaryDisplay);
-    mWriter->selectLayer(layer);
-    mWriter->setLayerBuffer(0, handle, -1);
-    mWriter->setLayerCompositionType(Composition::CURSOR);
-    mWriter->setLayerDisplayFrame(displayFrame);
-    mWriter->setLayerPlaneAlpha(1);
-    mWriter->setLayerSourceCrop({0, 0, (float)mDisplayWidth, (float)mDisplayHeight});
-    mWriter->setLayerTransform(static_cast<Transform>(0));
-    mWriter->setLayerVisibleRegion(std::vector<Rect>(1, displayFrame));
-    mWriter->setLayerZOrder(10);
-    mWriter->setLayerBlendMode(BlendMode::NONE);
-    mWriter->setLayerSurfaceDamage(std::vector<Rect>(1, displayFrame));
-    mWriter->setLayerDataspace(Dataspace::UNKNOWN);
-    mWriter->validateDisplay();
+    mWriter.setLayerBuffer(mPrimaryDisplay, layer, 0, handle, -1);
+    mWriter.setLayerCompositionType(mPrimaryDisplay, layer, Composition::CURSOR);
+    mWriter.setLayerDisplayFrame(mPrimaryDisplay, layer, displayFrame);
+    mWriter.setLayerPlaneAlpha(mPrimaryDisplay, layer, 1);
+    mWriter.setLayerSourceCrop(mPrimaryDisplay, layer,
+                               {0, 0, (float)mDisplayWidth, (float)mDisplayHeight});
+    mWriter.setLayerTransform(mPrimaryDisplay, layer, static_cast<Transform>(0));
+    mWriter.setLayerVisibleRegion(mPrimaryDisplay, layer, std::vector<Rect>(1, displayFrame));
+    mWriter.setLayerZOrder(mPrimaryDisplay, layer, 10);
+    mWriter.setLayerBlendMode(mPrimaryDisplay, layer, BlendMode::NONE);
+    mWriter.setLayerSurfaceDamage(mPrimaryDisplay, layer, std::vector<Rect>(1, displayFrame));
+    mWriter.setLayerDataspace(mPrimaryDisplay, layer, Dataspace::UNKNOWN);
+    mWriter.validateDisplay(mPrimaryDisplay);
 
     execute();
-    if (mReader->mCompositionChanges.size() != 0) {
+    std::vector<int64_t> layers;
+    std::vector<Composition> types;
+    mReader.takeChangedCompositionTypes(mPrimaryDisplay, &layers, &types);
+    if (!layers.empty()) {
         GTEST_SUCCEED() << "Composition change requested, skipping test";
         return;
     }
-    mWriter->presentDisplay();
-    ASSERT_EQ(0, mReader->mErrors.size());
+    mWriter.presentDisplay(mPrimaryDisplay);
+    ASSERT_TRUE(mReader.takeErrors().empty());
 
-    mWriter->setLayerCursorPosition(1, 1);
-    mWriter->setLayerCursorPosition(0, 0);
-    mWriter->validateDisplay();
-    mWriter->presentDisplay();
+    mWriter.setLayerCursorPosition(mPrimaryDisplay, layer, 1, 1);
+    execute();
+
+    mWriter.setLayerCursorPosition(mPrimaryDisplay, layer, 0, 0);
+    mWriter.validateDisplay(mPrimaryDisplay);
+    mWriter.presentDisplay(mPrimaryDisplay);
     execute();
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_BUFFER) {
-    auto handle = allocate()->handle;
+    const auto buffer = allocate();
+    const auto handle = buffer->handle;
     ASSERT_NE(nullptr, handle);
 
     int64_t layer;
     EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
-
-    mWriter->selectDisplay(mPrimaryDisplay);
-    mWriter->selectLayer(layer);
-    mWriter->setLayerBuffer(0, handle, -1);
+    mWriter.setLayerBuffer(mPrimaryDisplay, layer, 0, handle, -1);
     execute();
 }
 
@@ -1612,58 +1610,77 @@
     Rect empty{0, 0, 0, 0};
     Rect unit{0, 0, 1, 1};
 
-    mWriter->selectDisplay(mPrimaryDisplay);
-    mWriter->selectLayer(layer);
-    mWriter->setLayerSurfaceDamage(std::vector<Rect>(1, empty));
-    mWriter->setLayerSurfaceDamage(std::vector<Rect>(1, unit));
-    mWriter->setLayerSurfaceDamage(std::vector<Rect>());
+    mWriter.setLayerSurfaceDamage(mPrimaryDisplay, layer, std::vector<Rect>(1, empty));
     execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerSurfaceDamage(mPrimaryDisplay, layer, std::vector<Rect>(1, unit));
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerSurfaceDamage(mPrimaryDisplay, layer, std::vector<Rect>());
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_BLEND_MODE) {
     int64_t layer;
     EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
 
-    mWriter->selectDisplay(mPrimaryDisplay);
-    mWriter->selectLayer(layer);
-    mWriter->setLayerBlendMode(BlendMode::NONE);
-    mWriter->setLayerBlendMode(BlendMode::PREMULTIPLIED);
-    mWriter->setLayerBlendMode(BlendMode::COVERAGE);
+    mWriter.setLayerBlendMode(mPrimaryDisplay, layer, BlendMode::NONE);
     execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerBlendMode(mPrimaryDisplay, layer, BlendMode::PREMULTIPLIED);
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerBlendMode(mPrimaryDisplay, layer, BlendMode::COVERAGE);
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_COLOR) {
     int64_t layer;
     EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
 
-    mWriter->selectDisplay(mPrimaryDisplay);
-    mWriter->selectLayer(layer);
-    mWriter->setLayerColor(Color{static_cast<int8_t>(0xff), static_cast<int8_t>(0xff),
-                                 static_cast<int8_t>(0xff), static_cast<int8_t>(0xff)});
-    mWriter->setLayerColor(Color{0, 0, 0, 0});
+    mWriter.setLayerColor(mPrimaryDisplay, layer,
+                          Color{static_cast<int8_t>(0xff), static_cast<int8_t>(0xff),
+                                static_cast<int8_t>(0xff), static_cast<int8_t>(0xff)});
     execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerColor(mPrimaryDisplay, layer, Color{0, 0, 0, 0});
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_COMPOSITION_TYPE) {
     int64_t layer;
     EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
 
-    mWriter->selectDisplay(mPrimaryDisplay);
-    mWriter->selectLayer(layer);
-    mWriter->setLayerCompositionType(Composition::CLIENT);
-    mWriter->setLayerCompositionType(Composition::DEVICE);
-    mWriter->setLayerCompositionType(Composition::SOLID_COLOR);
-    mWriter->setLayerCompositionType(Composition::CURSOR);
+    mWriter.setLayerCompositionType(mPrimaryDisplay, layer, Composition::CLIENT);
     execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerCompositionType(mPrimaryDisplay, layer, Composition::DEVICE);
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerCompositionType(mPrimaryDisplay, layer, Composition::SOLID_COLOR);
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerCompositionType(mPrimaryDisplay, layer, Composition::CURSOR);
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_DATASPACE) {
     int64_t layer;
     EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
 
-    mWriter->selectDisplay(mPrimaryDisplay);
-    mWriter->selectLayer(layer);
-    mWriter->setLayerDataspace(Dataspace::UNKNOWN);
+    mWriter.setLayerDataspace(mPrimaryDisplay, layer, Dataspace::UNKNOWN);
     execute();
 }
 
@@ -1671,9 +1688,7 @@
     int64_t layer;
     EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
 
-    mWriter->selectDisplay(mPrimaryDisplay);
-    mWriter->selectLayer(layer);
-    mWriter->setLayerDisplayFrame(Rect{0, 0, 1, 1});
+    mWriter.setLayerDisplayFrame(mPrimaryDisplay, layer, Rect{0, 0, 1, 1});
     execute();
 }
 
@@ -1681,11 +1696,13 @@
     int64_t layer;
     EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
 
-    mWriter->selectDisplay(mPrimaryDisplay);
-    mWriter->selectLayer(layer);
-    mWriter->setLayerPlaneAlpha(0.0f);
-    mWriter->setLayerPlaneAlpha(1.0f);
+    mWriter.setLayerPlaneAlpha(mPrimaryDisplay, layer, 0.0f);
     execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerPlaneAlpha(mPrimaryDisplay, layer, 1.0f);
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_SIDEBAND_STREAM) {
@@ -1697,15 +1714,14 @@
         return;
     }
 
-    auto handle = allocate()->handle;
+    const auto buffer = allocate();
+    const auto handle = buffer->handle;
     ASSERT_NE(nullptr, handle);
 
     int64_t layer;
     EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
 
-    mWriter->selectDisplay(mPrimaryDisplay);
-    mWriter->selectLayer(layer);
-    mWriter->setLayerSidebandStream(handle);
+    mWriter.setLayerSidebandStream(mPrimaryDisplay, layer, handle);
     execute();
 }
 
@@ -1713,9 +1729,7 @@
     int64_t layer;
     EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
 
-    mWriter->selectDisplay(mPrimaryDisplay);
-    mWriter->selectLayer(layer);
-    mWriter->setLayerSourceCrop(FRect{0.0f, 0.0f, 1.0f, 1.0f});
+    mWriter.setLayerSourceCrop(mPrimaryDisplay, layer, FRect{0.0f, 0.0f, 1.0f, 1.0f});
     execute();
 }
 
@@ -1723,19 +1737,41 @@
     int64_t layer;
     EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
 
-    mWriter->selectDisplay(mPrimaryDisplay);
-    mWriter->selectLayer(layer);
-    mWriter->setLayerTransform(static_cast<Transform>(0));
-    mWriter->setLayerTransform(Transform::FLIP_H);
-    mWriter->setLayerTransform(Transform::FLIP_V);
-    mWriter->setLayerTransform(Transform::ROT_90);
-    mWriter->setLayerTransform(Transform::ROT_180);
-    mWriter->setLayerTransform(Transform::ROT_270);
-    mWriter->setLayerTransform(static_cast<Transform>(static_cast<int>(Transform::FLIP_H) |
-                                                      static_cast<int>(Transform::ROT_90)));
-    mWriter->setLayerTransform(static_cast<Transform>(static_cast<int>(Transform::FLIP_V) |
-                                                      static_cast<int>(Transform::ROT_90)));
+    mWriter.setLayerTransform(mPrimaryDisplay, layer, static_cast<Transform>(0));
     execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerTransform(mPrimaryDisplay, layer, Transform::FLIP_H);
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerTransform(mPrimaryDisplay, layer, Transform::FLIP_V);
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerTransform(mPrimaryDisplay, layer, Transform::ROT_90);
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerTransform(mPrimaryDisplay, layer, Transform::ROT_180);
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerTransform(mPrimaryDisplay, layer, Transform::ROT_270);
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerTransform(mPrimaryDisplay, layer,
+                              static_cast<Transform>(static_cast<int>(Transform::FLIP_H) |
+                                                     static_cast<int>(Transform::ROT_90)));
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerTransform(mPrimaryDisplay, layer,
+                              static_cast<Transform>(static_cast<int>(Transform::FLIP_V) |
+                                                     static_cast<int>(Transform::ROT_90)));
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_VISIBLE_REGION) {
@@ -1745,32 +1781,36 @@
     Rect empty{0, 0, 0, 0};
     Rect unit{0, 0, 1, 1};
 
-    mWriter->selectDisplay(mPrimaryDisplay);
-    mWriter->selectLayer(layer);
-    mWriter->setLayerVisibleRegion(std::vector<Rect>(1, empty));
-    mWriter->setLayerVisibleRegion(std::vector<Rect>(1, unit));
-    mWriter->setLayerVisibleRegion(std::vector<Rect>());
+    mWriter.setLayerVisibleRegion(mPrimaryDisplay, layer, std::vector<Rect>(1, empty));
     execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerVisibleRegion(mPrimaryDisplay, layer, std::vector<Rect>(1, unit));
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerVisibleRegion(mPrimaryDisplay, layer, std::vector<Rect>());
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_Z_ORDER) {
     int64_t layer;
     EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
 
-    mWriter->selectDisplay(mPrimaryDisplay);
-    mWriter->selectLayer(layer);
-    mWriter->setLayerZOrder(10);
-    mWriter->setLayerZOrder(0);
+    mWriter.setLayerZOrder(mPrimaryDisplay, layer, 10);
     execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setLayerZOrder(mPrimaryDisplay, layer, 0);
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SET_LAYER_PER_FRAME_METADATA) {
     int64_t layer;
     EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
 
-    mWriter->selectDisplay(mPrimaryDisplay);
-    mWriter->selectLayer(layer);
-
     /**
      * DISPLAY_P3 is a color space that uses the DCI_P3 primaries,
      * the D65 white point and the SRGB transfer functions.
@@ -1796,11 +1836,11 @@
     aidlMetadata.push_back({PerFrameMetadataKey::MIN_LUMINANCE, 0.1f});
     aidlMetadata.push_back({PerFrameMetadataKey::MAX_CONTENT_LIGHT_LEVEL, 78.0});
     aidlMetadata.push_back({PerFrameMetadataKey::MAX_FRAME_AVERAGE_LIGHT_LEVEL, 62.0});
-    mWriter->setLayerPerFrameMetadata(aidlMetadata);
+    mWriter.setLayerPerFrameMetadata(mPrimaryDisplay, layer, aidlMetadata);
     execute();
 
-    if (mReader->mErrors.size() == 1 && mReader->mErrors[0].second == EX_UNSUPPORTED_OPERATION) {
-        mReader->mErrors.clear();
+    const auto errors = mReader.takeErrors();
+    if (errors.size() == 1 && errors[0].errorCode == EX_UNSUPPORTED_OPERATION) {
         GTEST_SUCCEED() << "SetLayerPerFrameMetadata is not supported";
         EXPECT_TRUE(mComposerClient->destroyLayer(mPrimaryDisplay, layer).isOk());
         return;
@@ -1929,5 +1969,41 @@
         ALOGE("Failed to stop init.svc.surfaceflinger");
         return -1;
     }
+
+    android::ProcessState::self()->setThreadPoolMaxThreadCount(4);
+
+    // The binder threadpool we start will inherit sched policy and priority
+    // of (this) creating thread. We want the binder thread pool to have
+    // SCHED_FIFO policy and priority 1 (lowest RT priority)
+    // Once the pool is created we reset this thread's priority back to
+    // original.
+    // This thread policy is based on what we do in the SurfaceFlinger while starting
+    // the thread pool and we need to replicate that for the VTS tests.
+    int newPriority = 0;
+    int origPolicy = sched_getscheduler(0);
+    struct sched_param origSchedParam;
+
+    int errorInPriorityModification = sched_getparam(0, &origSchedParam);
+    if (errorInPriorityModification == 0) {
+        int policy = SCHED_FIFO;
+        newPriority = sched_get_priority_min(policy);
+
+        struct sched_param param;
+        param.sched_priority = newPriority;
+
+        errorInPriorityModification = sched_setscheduler(0, policy, &param);
+    }
+
+    // start the thread pool
+    android::ProcessState::self()->startThreadPool();
+
+    // Reset current thread's policy and priority
+    if (errorInPriorityModification == 0) {
+        errorInPriorityModification = sched_setscheduler(0, origPolicy, &origSchedParam);
+    } else {
+        ALOGE("Failed to set VtsHalGraphicsComposer3_TargetTest binder threadpool priority to "
+              "SCHED_FIFO");
+    }
+
     return RUN_ALL_TESTS();
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/Android.bp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/Android.bp
index 2b058c7..df038db 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/Android.bp
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/Android.bp
@@ -28,7 +28,6 @@
     defaults: ["hidl_defaults"],
     srcs: [
         "GraphicsComposerCallback.cpp",
-        "TestCommandReader.cpp",
         "ReadbackVts.cpp",
         "RenderEngineVts.cpp",
     ],
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/ReadbackVts.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/ReadbackVts.cpp
index b612309..4de2d71 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/ReadbackVts.cpp
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/ReadbackVts.cpp
@@ -32,15 +32,14 @@
 const std::vector<Dataspace> ReadbackHelper::dataspaces = {common::Dataspace::SRGB,
                                                            common::Dataspace::DISPLAY_P3};
 
-void TestLayer::write(const std::shared_ptr<CommandWriterBase>& writer) {
-    writer->selectLayer(mLayer);
-    writer->setLayerDisplayFrame(mDisplayFrame);
-    writer->setLayerSourceCrop(mSourceCrop);
-    writer->setLayerZOrder(mZOrder);
-    writer->setLayerSurfaceDamage(mSurfaceDamage);
-    writer->setLayerTransform(mTransform);
-    writer->setLayerPlaneAlpha(mAlpha);
-    writer->setLayerBlendMode(mBlendMode);
+void TestLayer::write(ComposerClientWriter& writer) {
+    writer.setLayerDisplayFrame(mDisplay, mLayer, mDisplayFrame);
+    writer.setLayerSourceCrop(mDisplay, mLayer, mSourceCrop);
+    writer.setLayerZOrder(mDisplay, mLayer, mZOrder);
+    writer.setLayerSurfaceDamage(mDisplay, mLayer, mSurfaceDamage);
+    writer.setLayerTransform(mDisplay, mLayer, mTransform);
+    writer.setLayerPlaneAlpha(mDisplay, mLayer, mAlpha);
+    writer.setLayerBlendMode(mDisplay, mLayer, mBlendMode);
 }
 
 std::string ReadbackHelper::getColorModeString(ColorMode mode) {
@@ -254,10 +253,10 @@
     EXPECT_EQ(::android::OK, status);
 }
 
-void TestColorLayer::write(const std::shared_ptr<CommandWriterBase>& writer) {
+void TestColorLayer::write(ComposerClientWriter& writer) {
     TestLayer::write(writer);
-    writer->setLayerCompositionType(Composition::SOLID_COLOR);
-    writer->setLayerColor(mColor);
+    writer.setLayerCompositionType(mDisplay, mLayer, Composition::SOLID_COLOR);
+    writer.setLayerColor(mDisplay, mLayer, mColor);
 }
 
 LayerSettings TestColorLayer::toRenderEngineLayerSettings() {
@@ -297,12 +296,12 @@
     setSourceCrop({0, 0, (float)width, (float)height});
 }
 
-void TestBufferLayer::write(const std::shared_ptr<CommandWriterBase>& writer) {
+void TestBufferLayer::write(ComposerClientWriter& writer) {
     TestLayer::write(writer);
-    writer->setLayerCompositionType(mComposition);
-    writer->setLayerVisibleRegion(std::vector<Rect>(1, mDisplayFrame));
+    writer.setLayerCompositionType(mDisplay, mLayer, mComposition);
+    writer.setLayerVisibleRegion(mDisplay, mLayer, std::vector<Rect>(1, mDisplayFrame));
     if (mGraphicBuffer->handle != nullptr)
-        writer->setLayerBuffer(0, mGraphicBuffer->handle, mFillFence);
+        writer.setLayerBuffer(mDisplay, mLayer, 0, mGraphicBuffer->handle, mFillFence);
 }
 
 LayerSettings TestBufferLayer::toRenderEngineLayerSettings() {
@@ -346,15 +345,12 @@
     ASSERT_EQ(::android::OK, mGraphicBuffer->initCheck());
 }
 
-void TestBufferLayer::setDataspace(common::Dataspace dataspace,
-                                   const std::shared_ptr<CommandWriterBase>& writer) {
-    writer->selectLayer(mLayer);
-    writer->setLayerDataspace(dataspace);
+void TestBufferLayer::setDataspace(common::Dataspace dataspace, ComposerClientWriter& writer) {
+    writer.setLayerDataspace(mDisplay, mLayer, dataspace);
 }
 
-void TestBufferLayer::setToClientComposition(const std::shared_ptr<CommandWriterBase>& writer) {
-    writer->selectLayer(mLayer);
-    writer->setLayerCompositionType(Composition::CLIENT);
+void TestBufferLayer::setToClientComposition(ComposerClientWriter& writer) {
+    writer.setLayerCompositionType(mDisplay, mLayer, Composition::CLIENT);
 }
 
-}  // namespace aidl::android::hardware::graphics::composer3::vts
\ No newline at end of file
+}  // namespace aidl::android::hardware::graphics::composer3::vts
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/RenderEngineVts.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/RenderEngineVts.cpp
index e83750e..50ce462 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/RenderEngineVts.cpp
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/RenderEngineVts.cpp
@@ -86,4 +86,4 @@
     ASSERT_EQ(::android::OK, mGraphicBuffer->unlock());
 }
 
-}  // namespace aidl::android::hardware::graphics::composer3::vts
\ No newline at end of file
+}  // namespace aidl::android::hardware::graphics::composer3::vts
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/TestCommandReader.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/TestCommandReader.cpp
deleted file mode 100644
index a5a84d9..0000000
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/TestCommandReader.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "include/TestCommandReader.h"
-#include <gtest/gtest.h>
-
-namespace aidl::android::hardware::graphics::composer3::vts {
-
-void TestCommandReader::parse() {
-    mErrors.clear();
-    mCompositionChanges.clear();
-    while (!isEmpty()) {
-        int32_t command;
-        uint16_t length;
-        ASSERT_TRUE(beginCommand(&command, &length));
-
-        parseSingleCommand(command, length);
-
-        endCommand();
-    }
-}
-
-void TestCommandReader::parseSingleCommand(int32_t commandRaw, uint16_t length) {
-    auto command = static_cast<Command>(commandRaw);
-
-    switch (command) {
-        case Command::SET_CLIENT_TARGET_PROPERTY: {
-            ASSERT_EQ(2, length);
-            read();
-            close(readFence());
-        } break;
-        case Command::SELECT_DISPLAY: {
-            ASSERT_EQ(2, length);
-            read64();  // display
-        } break;
-        case Command::SET_ERROR: {
-            ASSERT_EQ(2, length);
-            auto loc = read();
-            auto err = readSigned();
-            std::pair<uint32_t, uint32_t> error(loc, err);
-            mErrors.push_back(error);
-        } break;
-        case Command::SET_CHANGED_COMPOSITION_TYPES: {
-            ASSERT_EQ(0, length % 3);
-            for (uint16_t count = 0; count < length / 3; ++count) {
-                uint64_t layerId = read64();
-                uint32_t composition = read();
-
-                std::pair<uint64_t, uint32_t> compositionChange(layerId, composition);
-                mCompositionChanges.push_back(compositionChange);
-            }
-        } break;
-        case Command::SET_DISPLAY_REQUESTS: {
-            ASSERT_EQ(1, length % 3);
-            read();  // displayRequests, ignored for now
-            for (uint16_t count = 0; count < (length - 1) / 3; ++count) {
-                read64();  // layer
-                // silently eat requests to clear the client target, since we won't be testing
-                // client composition anyway
-                ASSERT_EQ(1u, read());
-            }
-        } break;
-        case Command::SET_PRESENT_FENCE: {
-            ASSERT_EQ(1, length);
-            close(readFence());
-        } break;
-        case Command::SET_RELEASE_FENCES: {
-            ASSERT_EQ(0, length % 3);
-            for (uint16_t count = 0; count < length / 3; ++count) {
-                read64();
-                close(readFence());
-            }
-        } break;
-        default:
-            GTEST_FAIL() << "unexpected return command " << std::hex << static_cast<int>(command);
-            break;
-    }
-}
-}  // namespace aidl::android::hardware::graphics::composer3::vts
\ No newline at end of file
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/ReadbackVts.h b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/ReadbackVts.h
index 85b4fdc..60a036e 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/ReadbackVts.h
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/ReadbackVts.h
@@ -21,10 +21,10 @@
 #pragma clang diagnostic ignored "-Wconversion"
 
 #include <GraphicsComposerCallback.h>
-#include <TestCommandReader.h>
 #include <aidl/android/hardware/graphics/composer3/IComposerClient.h>
 #include <android-base/unique_fd.h>
-#include <android/hardware/graphics/composer3/command-buffer.h>
+#include <android/hardware/graphics/composer3/ComposerClientReader.h>
+#include <android/hardware/graphics/composer3/ComposerClientWriter.h>
 #include <mapper-vts/2.1/MapperVts.h>
 #include <renderengine/RenderEngine.h>
 #include <ui/GraphicBuffer.h>
@@ -54,7 +54,7 @@
 class TestLayer {
   public:
     TestLayer(const std::shared_ptr<IComposerClient>& client, int64_t display)
-        : mComposerClient(client) {
+        : mDisplay(display), mComposerClient(client) {
         client->createLayer(display, kBufferSlotCount, &mLayer);
     }
 
@@ -62,7 +62,7 @@
     // call destroyLayers here
     virtual ~TestLayer(){};
 
-    virtual void write(const std::shared_ptr<CommandWriterBase>& writer);
+    virtual void write(ComposerClientWriter& writer);
     virtual LayerSettings toRenderEngineLayerSettings();
 
     void setDisplayFrame(Rect frame) { mDisplayFrame = frame; }
@@ -83,7 +83,10 @@
 
     float getAlpha() const { return mAlpha; }
 
+    int64_t getLayer() const { return mLayer; }
+
   protected:
+    int64_t mDisplay;
     int64_t mLayer;
     Rect mDisplayFrame = {0, 0, 0, 0};
     std::vector<Rect> mSurfaceDamage;
@@ -103,7 +106,7 @@
     TestColorLayer(const std::shared_ptr<IComposerClient>& client, int64_t display)
         : TestLayer{client, display} {}
 
-    void write(const std::shared_ptr<CommandWriterBase>& writer) override;
+    void write(ComposerClientWriter& writer) override;
 
     LayerSettings toRenderEngineLayerSettings() override;
 
@@ -121,7 +124,7 @@
                     uint32_t height, common::PixelFormat format,
                     Composition composition = Composition::DEVICE);
 
-    void write(const std::shared_ptr<CommandWriterBase>& writer) override;
+    void write(ComposerClientWriter& writer) override;
 
     LayerSettings toRenderEngineLayerSettings() override;
 
@@ -129,9 +132,9 @@
 
     void setBuffer(std::vector<Color> colors);
 
-    void setDataspace(Dataspace dataspace, const std::shared_ptr<CommandWriterBase>& writer);
+    void setDataspace(Dataspace dataspace, ComposerClientWriter& writer);
 
-    void setToClientComposition(const std::shared_ptr<CommandWriterBase>& writer);
+    void setToClientComposition(ComposerClientWriter& writer);
 
     uint32_t getWidth() const { return mWidth; }
 
@@ -211,4 +214,4 @@
     native_handle_t mBufferHandle;
 };
 
-}  // namespace aidl::android::hardware::graphics::composer3::vts
\ No newline at end of file
+}  // namespace aidl::android::hardware::graphics::composer3::vts
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/RenderEngineVts.h b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/RenderEngineVts.h
index eaff6d7..2798e09 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/RenderEngineVts.h
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/RenderEngineVts.h
@@ -68,4 +68,4 @@
     DisplaySettings mDisplaySettings;
 };
 
-}  // namespace aidl::android::hardware::graphics::composer3::vts
\ No newline at end of file
+}  // namespace aidl::android::hardware::graphics::composer3::vts
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/TestCommandReader.h b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/TestCommandReader.h
deleted file mode 100644
index 852a56e..0000000
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/TestCommandReader.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#pragma once
-
-// TODO(b/129481165): remove the #pragma below and fix conversion issues
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wconversion"
-
-#include <android/hardware/graphics/composer3/command-buffer.h>
-
-// TODO(b/129481165): remove the #pragma below and fix conversion issues
-#pragma clang diagnostic pop  // ignored "-Wconversion
-
-namespace aidl::android::hardware::graphics::composer3::vts {
-
-class TestCommandReader : public CommandReaderBase {
-  public:
-    virtual ~TestCommandReader() = default;
-
-    std::vector<std::pair<uint32_t, uint32_t>> mErrors;
-    std::vector<std::pair<uint64_t, uint32_t>> mCompositionChanges;
-
-    // Parse all commands in the return command queue.  Call GTEST_FAIL() for
-    // unexpected errors or commands.
-    void parse();
-    virtual void parseSingleCommand(int32_t commandRaw, uint16_t length);
-};
-}  // namespace aidl::android::hardware::graphics::composer3::vts
diff --git a/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientReader.h b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientReader.h
new file mode 100644
index 0000000..1dc9145
--- /dev/null
+++ b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientReader.h
@@ -0,0 +1,319 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <algorithm>
+#include <limits>
+#include <memory>
+#include <unordered_map>
+#include <unordered_set>
+#include <vector>
+
+#include <inttypes.h>
+#include <string.h>
+
+#include <aidl/android/hardware/graphics/common/BlendMode.h>
+#include <aidl/android/hardware/graphics/composer3/ClientTargetProperty.h>
+#include <aidl/android/hardware/graphics/composer3/Color.h>
+#include <aidl/android/hardware/graphics/composer3/Composition.h>
+#include <aidl/android/hardware/graphics/composer3/FloatColor.h>
+#include <aidl/android/hardware/graphics/composer3/HandleIndex.h>
+#include <aidl/android/hardware/graphics/composer3/IComposer.h>
+#include <aidl/android/hardware/graphics/composer3/IComposerClient.h>
+#include <aidl/android/hardware/graphics/composer3/PerFrameMetadata.h>
+#include <aidl/android/hardware/graphics/composer3/PerFrameMetadataBlob.h>
+
+#include <aidl/android/hardware/graphics/composer3/CommandResultPayload.h>
+#include <aidl/android/hardware/graphics/composer3/DisplayCommand.h>
+
+#include <aidl/android/hardware/graphics/common/ColorTransform.h>
+#include <aidl/android/hardware/graphics/common/FRect.h>
+#include <aidl/android/hardware/graphics/common/Rect.h>
+#include <aidl/android/hardware/graphics/common/Transform.h>
+
+#include <log/log.h>
+#include <sync/sync.h>
+
+#include <aidlcommonsupport/NativeHandle.h>
+
+using aidl::android::hardware::graphics::common::BlendMode;
+using aidl::android::hardware::graphics::common::ColorTransform;
+using aidl::android::hardware::graphics::common::Dataspace;
+using aidl::android::hardware::graphics::common::FRect;
+using aidl::android::hardware::graphics::common::Rect;
+using aidl::android::hardware::graphics::common::Transform;
+
+using namespace aidl::android::hardware::graphics::composer3;
+
+using aidl::android::hardware::common::NativeHandle;
+
+namespace aidl::android::hardware::graphics::composer3 {
+
+class ComposerClientReader {
+  public:
+    ~ComposerClientReader() { resetData(); }
+
+    // Parse and execute commands from the command queue.  The commands are
+    // actually return values from the server and will be saved in ReturnData.
+    void parse(const std::vector<CommandResultPayload>& results) {
+        resetData();
+
+        for (const auto& result : results) {
+            switch (result.getTag()) {
+                case CommandResultPayload::Tag::error:
+                    parseSetError(result.get<CommandResultPayload::Tag::error>());
+                    break;
+                case CommandResultPayload::Tag::changedCompositionTypes:
+                    parseSetChangedCompositionTypes(
+                            result.get<CommandResultPayload::Tag::changedCompositionTypes>());
+                    break;
+                case CommandResultPayload::Tag::displayRequest:
+                    parseSetDisplayRequests(
+                            result.get<CommandResultPayload::Tag::displayRequest>());
+                    break;
+                case CommandResultPayload::Tag::presentFence:
+                    parseSetPresentFence(result.get<CommandResultPayload::Tag::presentFence>());
+                    break;
+                case CommandResultPayload::Tag::releaseFences:
+                    parseSetReleaseFences(result.get<CommandResultPayload::Tag::releaseFences>());
+                    break;
+                case CommandResultPayload::Tag::presentOrValidateResult:
+                    parseSetPresentOrValidateDisplayResult(
+                            result.get<CommandResultPayload::Tag::presentOrValidateResult>());
+                    break;
+                case CommandResultPayload::Tag::clientTargetProperty:
+                    parseSetClientTargetProperty(
+                            result.get<CommandResultPayload::Tag::clientTargetProperty>());
+                    break;
+            }
+        }
+    }
+
+    std::vector<CommandError> takeErrors() { return std::move(mErrors); }
+
+    bool hasChanges(int64_t display, uint32_t* outNumChangedCompositionTypes,
+                    uint32_t* outNumLayerRequestMasks) const {
+        auto found = mReturnData.find(display);
+        if (found == mReturnData.end()) {
+            *outNumChangedCompositionTypes = 0;
+            *outNumLayerRequestMasks = 0;
+            return false;
+        }
+
+        const ReturnData& data = found->second;
+
+        *outNumChangedCompositionTypes = static_cast<uint32_t>(data.compositionTypes.size());
+        *outNumLayerRequestMasks = static_cast<uint32_t>(data.requestMasks.size());
+
+        return !(data.compositionTypes.empty() && data.requestMasks.empty());
+    }
+
+    // Get and clear saved changed composition types.
+    void takeChangedCompositionTypes(int64_t display, std::vector<int64_t>* outLayers,
+                                     std::vector<Composition>* outTypes) {
+        auto found = mReturnData.find(display);
+        if (found == mReturnData.end()) {
+            outLayers->clear();
+            outTypes->clear();
+            return;
+        }
+
+        ReturnData& data = found->second;
+
+        *outLayers = std::move(data.changedLayers);
+        *outTypes = std::move(data.compositionTypes);
+    }
+
+    // Get and clear saved display requests.
+    void takeDisplayRequests(int64_t display, uint32_t* outDisplayRequestMask,
+                             std::vector<int64_t>* outLayers,
+                             std::vector<uint32_t>* outLayerRequestMasks) {
+        auto found = mReturnData.find(display);
+        if (found == mReturnData.end()) {
+            *outDisplayRequestMask = 0;
+            outLayers->clear();
+            outLayerRequestMasks->clear();
+            return;
+        }
+
+        ReturnData& data = found->second;
+
+        *outDisplayRequestMask = data.displayRequests;
+        *outLayers = std::move(data.requestedLayers);
+        *outLayerRequestMasks = std::move(data.requestMasks);
+    }
+
+    // Get and clear saved release fences.
+    void takeReleaseFences(int64_t display, std::vector<int64_t>* outLayers,
+                           std::vector<int>* outReleaseFences) {
+        auto found = mReturnData.find(display);
+        if (found == mReturnData.end()) {
+            outLayers->clear();
+            outReleaseFences->clear();
+            return;
+        }
+
+        ReturnData& data = found->second;
+
+        *outLayers = std::move(data.releasedLayers);
+        *outReleaseFences = std::move(data.releaseFences);
+    }
+
+    // Get and clear saved present fence.
+    void takePresentFence(int64_t display, int* outPresentFence) {
+        auto found = mReturnData.find(display);
+        if (found == mReturnData.end()) {
+            *outPresentFence = -1;
+            return;
+        }
+
+        ReturnData& data = found->second;
+
+        *outPresentFence = data.presentFence;
+        data.presentFence = -1;
+    }
+
+    // Get what stage succeeded during PresentOrValidate: Present or Validate
+    void takePresentOrValidateStage(int64_t display, uint32_t* state) {
+        auto found = mReturnData.find(display);
+        if (found == mReturnData.end()) {
+            *state = static_cast<uint32_t>(-1);
+            return;
+        }
+        ReturnData& data = found->second;
+        *state = data.presentOrValidateState;
+    }
+
+    // Get the client target properties requested by hardware composer.
+    void takeClientTargetProperty(int64_t display, ClientTargetProperty* outClientTargetProperty,
+                                  float* outWhitePointNits) {
+        auto found = mReturnData.find(display);
+
+        // If not found, return the default values.
+        if (found == mReturnData.end()) {
+            outClientTargetProperty->pixelFormat = common::PixelFormat::RGBA_8888;
+            outClientTargetProperty->dataspace = Dataspace::UNKNOWN;
+            *outWhitePointNits = -1.f;
+            return;
+        }
+
+        ReturnData& data = found->second;
+        *outClientTargetProperty = data.clientTargetProperty;
+        *outWhitePointNits = data.clientTargetWhitePointNits;
+    }
+
+  private:
+    void resetData() {
+        mErrors.clear();
+
+        for (auto& data : mReturnData) {
+            if (data.second.presentFence >= 0) {
+                close(data.second.presentFence);
+            }
+            for (auto fence : data.second.releaseFences) {
+                if (fence >= 0) {
+                    close(fence);
+                }
+            }
+        }
+
+        mReturnData.clear();
+    }
+
+    void parseSetError(const CommandError& error) { mErrors.emplace_back(error); }
+
+    void parseSetChangedCompositionTypes(const ChangedCompositionTypes& changedCompositionTypes) {
+        auto& data = mReturnData[changedCompositionTypes.display];
+
+        data.changedLayers.reserve(changedCompositionTypes.layers.size());
+        data.compositionTypes.reserve(changedCompositionTypes.layers.size());
+        for (const auto& layer : changedCompositionTypes.layers) {
+            data.changedLayers.push_back(layer.layer);
+            data.compositionTypes.push_back(layer.composition);
+        }
+    }
+
+    void parseSetDisplayRequests(const DisplayRequest& displayRequest) {
+        auto& data = mReturnData[displayRequest.display];
+
+        data.displayRequests = displayRequest.mask;
+        data.requestedLayers.reserve(displayRequest.layerRequests.size());
+        data.requestMasks.reserve(displayRequest.layerRequests.size());
+        for (const auto& layerRequest : displayRequest.layerRequests) {
+            data.requestedLayers.push_back(layerRequest.layer);
+            data.requestMasks.push_back(layerRequest.mask);
+        }
+    }
+
+    void parseSetPresentFence(const PresentFence& presentFence) {
+        auto& data = mReturnData[presentFence.display];
+        if (data.presentFence >= 0) {
+            close(data.presentFence);
+        }
+        data.presentFence = dup(presentFence.fence.get());
+    }
+
+    void parseSetReleaseFences(const ReleaseFences& releaseFences) {
+        auto& data = mReturnData[releaseFences.display];
+        data.releasedLayers.reserve(releaseFences.layers.size());
+        data.releaseFences.reserve(releaseFences.layers.size());
+        for (const auto& layer : releaseFences.layers) {
+            data.releasedLayers.push_back(layer.layer);
+            data.releaseFences.push_back(dup(layer.fence.get()));
+        }
+    }
+
+    void parseSetPresentOrValidateDisplayResult(const PresentOrValidate& presentOrValidate) {
+        auto& data = mReturnData[presentOrValidate.display];
+        data.presentOrValidateState =
+                presentOrValidate.result == PresentOrValidate::Result::Presented ? 1 : 0;
+    }
+
+    void parseSetClientTargetProperty(const ClientTargetPropertyWithNits& clientTargetProperty) {
+        auto& data = mReturnData[clientTargetProperty.display];
+        data.clientTargetProperty.pixelFormat =
+                clientTargetProperty.clientTargetProperty.pixelFormat;
+        data.clientTargetProperty.dataspace = clientTargetProperty.clientTargetProperty.dataspace;
+        data.clientTargetWhitePointNits = clientTargetProperty.whitePointNits;
+    }
+
+    struct ReturnData {
+        int32_t displayRequests = 0;
+
+        std::vector<int64_t> changedLayers;
+        std::vector<Composition> compositionTypes;
+
+        std::vector<int64_t> requestedLayers;
+        std::vector<uint32_t> requestMasks;
+
+        int presentFence = -1;
+
+        std::vector<int64_t> releasedLayers;
+        std::vector<int> releaseFences;
+
+        uint32_t presentOrValidateState;
+
+        ClientTargetProperty clientTargetProperty{common::PixelFormat::RGBA_8888,
+                                                  Dataspace::UNKNOWN};
+        float clientTargetWhitePointNits = -1.f;
+    };
+
+    std::vector<CommandError> mErrors;
+    std::unordered_map<int64_t, ReturnData> mReturnData;
+};
+
+}  // namespace aidl::android::hardware::graphics::composer3
diff --git a/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h
new file mode 100644
index 0000000..bd03673
--- /dev/null
+++ b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h
@@ -0,0 +1,272 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <algorithm>
+#include <limits>
+#include <memory>
+#include <unordered_map>
+#include <unordered_set>
+#include <vector>
+
+#include <inttypes.h>
+#include <string.h>
+
+#include <aidl/android/hardware/graphics/common/BlendMode.h>
+#include <aidl/android/hardware/graphics/composer3/Color.h>
+#include <aidl/android/hardware/graphics/composer3/Composition.h>
+#include <aidl/android/hardware/graphics/composer3/FloatColor.h>
+#include <aidl/android/hardware/graphics/composer3/HandleIndex.h>
+#include <aidl/android/hardware/graphics/composer3/IComposer.h>
+#include <aidl/android/hardware/graphics/composer3/IComposerClient.h>
+#include <aidl/android/hardware/graphics/composer3/PerFrameMetadata.h>
+#include <aidl/android/hardware/graphics/composer3/PerFrameMetadataBlob.h>
+
+#include <aidl/android/hardware/graphics/composer3/DisplayCommand.h>
+
+#include <aidl/android/hardware/graphics/common/ColorTransform.h>
+#include <aidl/android/hardware/graphics/common/FRect.h>
+#include <aidl/android/hardware/graphics/common/Rect.h>
+#include <aidl/android/hardware/graphics/common/Transform.h>
+
+#include <log/log.h>
+#include <sync/sync.h>
+
+#include <aidlcommonsupport/NativeHandle.h>
+
+using aidl::android::hardware::graphics::common::BlendMode;
+using aidl::android::hardware::graphics::common::ColorTransform;
+using aidl::android::hardware::graphics::common::Dataspace;
+using aidl::android::hardware::graphics::common::FRect;
+using aidl::android::hardware::graphics::common::Rect;
+using aidl::android::hardware::graphics::common::Transform;
+
+using namespace aidl::android::hardware::graphics::composer3;
+
+using aidl::android::hardware::common::NativeHandle;
+
+namespace aidl::android::hardware::graphics::composer3 {
+
+class ComposerClientWriter {
+  public:
+    ComposerClientWriter() { reset(); }
+
+    virtual ~ComposerClientWriter() { reset(); }
+
+    void reset() {
+        mDisplayCommand.reset();
+        mLayerCommand.reset();
+        mCommands.clear();
+    }
+
+    void setColorTransform(int64_t display, const float* matrix, ColorTransform hint) {
+        ColorTransformPayload colorTransformPayload;
+        colorTransformPayload.matrix.assign(matrix, matrix + 16);
+        colorTransformPayload.hint = hint;
+        getDisplayCommand(display).colorTransform.emplace(std::move(colorTransformPayload));
+    }
+
+    void setClientTarget(int64_t display, uint32_t slot, const native_handle_t* target,
+                         int acquireFence, Dataspace dataspace, const std::vector<Rect>& damage) {
+        ClientTarget clientTargetCommand;
+        clientTargetCommand.buffer = getBuffer(slot, target, acquireFence);
+        clientTargetCommand.dataspace = dataspace;
+        clientTargetCommand.damage.assign(damage.begin(), damage.end());
+        getDisplayCommand(display).clientTarget.emplace(std::move(clientTargetCommand));
+    }
+
+    void setOutputBuffer(int64_t display, uint32_t slot, const native_handle_t* buffer,
+                         int releaseFence) {
+        getDisplayCommand(display).virtualDisplayOutputBuffer.emplace(
+                getBuffer(slot, buffer, releaseFence));
+    }
+
+    void validateDisplay(int64_t display) { getDisplayCommand(display).validateDisplay = true; }
+
+    void presentOrvalidateDisplay(int64_t display) {
+        getDisplayCommand(display).presentOrValidateDisplay = true;
+    }
+
+    void acceptDisplayChanges(int64_t display) {
+        getDisplayCommand(display).acceptDisplayChanges = true;
+    }
+
+    void presentDisplay(int64_t display) { getDisplayCommand(display).presentDisplay = true; }
+
+    void setLayerCursorPosition(int64_t display, int64_t layer, int32_t x, int32_t y) {
+        common::Point cursorPosition;
+        cursorPosition.x = x;
+        cursorPosition.y = y;
+        getLayerCommand(display, layer).cursorPosition.emplace(std::move(cursorPosition));
+    }
+
+    void setLayerBuffer(int64_t display, int64_t layer, uint32_t slot,
+                        const native_handle_t* buffer, int acquireFence) {
+        getLayerCommand(display, layer).buffer = getBuffer(slot, buffer, acquireFence);
+    }
+
+    void setLayerSurfaceDamage(int64_t display, int64_t layer, const std::vector<Rect>& damage) {
+        getLayerCommand(display, layer).damage.emplace(damage.begin(), damage.end());
+    }
+
+    void setLayerBlendMode(int64_t display, int64_t layer, BlendMode mode) {
+        ParcelableBlendMode parcelableBlendMode;
+        parcelableBlendMode.blendMode = mode;
+        getLayerCommand(display, layer).blendMode.emplace(std::move(parcelableBlendMode));
+    }
+
+    void setLayerColor(int64_t display, int64_t layer, Color color) {
+        getLayerCommand(display, layer).color.emplace(std::move(color));
+    }
+
+    void setLayerCompositionType(int64_t display, int64_t layer, Composition type) {
+        ParcelableComposition compositionPayload;
+        compositionPayload.composition = type;
+        getLayerCommand(display, layer).composition.emplace(std::move(compositionPayload));
+    }
+
+    void setLayerDataspace(int64_t display, int64_t layer, Dataspace dataspace) {
+        ParcelableDataspace dataspacePayload;
+        dataspacePayload.dataspace = dataspace;
+        getLayerCommand(display, layer).dataspace.emplace(std::move(dataspacePayload));
+    }
+
+    void setLayerDisplayFrame(int64_t display, int64_t layer, const Rect& frame) {
+        getLayerCommand(display, layer).displayFrame.emplace(frame);
+    }
+
+    void setLayerPlaneAlpha(int64_t display, int64_t layer, float alpha) {
+        PlaneAlpha planeAlpha;
+        planeAlpha.alpha = alpha;
+        getLayerCommand(display, layer).planeAlpha.emplace(std::move(planeAlpha));
+    }
+
+    void setLayerSidebandStream(int64_t display, int64_t layer, const native_handle_t* stream) {
+        NativeHandle handle;
+        if (stream) handle = ::android::dupToAidl(stream);
+        getLayerCommand(display, layer).sidebandStream.emplace(std::move(handle));
+    }
+
+    void setLayerSourceCrop(int64_t display, int64_t layer, const FRect& crop) {
+        getLayerCommand(display, layer).sourceCrop.emplace(crop);
+    }
+
+    void setLayerTransform(int64_t display, int64_t layer, Transform transform) {
+        ParcelableTransform transformPayload;
+        transformPayload.transform = transform;
+        getLayerCommand(display, layer).transform.emplace(std::move(transformPayload));
+    }
+
+    void setLayerVisibleRegion(int64_t display, int64_t layer, const std::vector<Rect>& visible) {
+        getLayerCommand(display, layer).visibleRegion.emplace(visible.begin(), visible.end());
+    }
+
+    void setLayerZOrder(int64_t display, int64_t layer, uint32_t z) {
+        ZOrder zorder;
+        zorder.z = z;
+        getLayerCommand(display, layer).z.emplace(std::move(zorder));
+    }
+
+    void setLayerPerFrameMetadata(int64_t display, int64_t layer,
+                                  const std::vector<PerFrameMetadata>& metadataVec) {
+        getLayerCommand(display, layer)
+                .perFrameMetadata.emplace(metadataVec.begin(), metadataVec.end());
+    }
+
+    void setLayerColorTransform(int64_t display, int64_t layer, const float* matrix) {
+        getLayerCommand(display, layer).colorTransform.emplace(matrix, matrix + 16);
+    }
+
+    void setLayerPerFrameMetadataBlobs(int64_t display, int64_t layer,
+                                       const std::vector<PerFrameMetadataBlob>& metadata) {
+        getLayerCommand(display, layer)
+                .perFrameMetadataBlob.emplace(metadata.begin(), metadata.end());
+    }
+
+    void setLayerFloatColor(int64_t display, int64_t layer, FloatColor color) {
+        getLayerCommand(display, layer).floatColor.emplace(color);
+    }
+
+    void setLayerGenericMetadata(int64_t display, int64_t layer, const std::string& key,
+                                 const bool mandatory, const std::vector<uint8_t>& value) {
+        GenericMetadata metadata;
+        metadata.key.name = key;
+        metadata.key.mandatory = mandatory;
+        metadata.value.assign(value.begin(), value.end());
+        getLayerCommand(display, layer).genericMetadata.emplace(std::move(metadata));
+    }
+
+    void setLayerWhitePointNits(int64_t display, int64_t layer, float whitePointNits) {
+        getLayerCommand(display, layer)
+                .whitePointNits.emplace(WhitePointNits{.nits = whitePointNits});
+    }
+
+    const std::vector<DisplayCommand>& getPendingCommands() {
+        flushLayerCommand();
+        flushDisplayCommand();
+        return mCommands;
+    }
+
+  private:
+    std::optional<DisplayCommand> mDisplayCommand;
+    std::optional<LayerCommand> mLayerCommand;
+    std::vector<DisplayCommand> mCommands;
+
+    Buffer getBuffer(int slot, const native_handle_t* bufferHandle, int fence) {
+        Buffer bufferCommand;
+        bufferCommand.slot = slot;
+        if (bufferHandle) bufferCommand.handle.emplace(::android::dupToAidl(bufferHandle));
+        if (fence > 0) bufferCommand.fence = ::ndk::ScopedFileDescriptor(fence);
+        return bufferCommand;
+    }
+
+    void flushLayerCommand() {
+        if (mLayerCommand.has_value()) {
+            mDisplayCommand->layers.emplace_back(std::move(*mLayerCommand));
+            mLayerCommand.reset();
+        }
+    }
+
+    void flushDisplayCommand() {
+        if (mDisplayCommand.has_value()) {
+            mCommands.emplace_back(std::move(*mDisplayCommand));
+            mDisplayCommand.reset();
+        }
+    }
+
+    DisplayCommand& getDisplayCommand(int64_t display) {
+        if (!mDisplayCommand.has_value() || mDisplayCommand->display != display) {
+            flushLayerCommand();
+            flushDisplayCommand();
+            mDisplayCommand.emplace();
+            mDisplayCommand->display = display;
+        }
+        return *mDisplayCommand;
+    }
+
+    LayerCommand& getLayerCommand(int64_t display, int64_t layer) {
+        getDisplayCommand(display);
+        if (!mLayerCommand.has_value() || mLayerCommand->layer != layer) {
+            flushLayerCommand();
+            mLayerCommand.emplace();
+            mLayerCommand->layer = layer;
+        }
+        return *mLayerCommand;
+    }
+};
+
+}  // namespace aidl::android::hardware::graphics::composer3
diff --git a/graphics/composer/aidl/include/android/hardware/graphics/composer3/command-buffer.h b/graphics/composer/aidl/include/android/hardware/graphics/composer3/command-buffer.h
deleted file mode 100644
index d02cf9c..0000000
--- a/graphics/composer/aidl/include/android/hardware/graphics/composer3/command-buffer.h
+++ /dev/null
@@ -1,895 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <algorithm>
-#include <limits>
-#include <memory>
-#include <vector>
-
-#include <inttypes.h>
-#include <string.h>
-
-#include <aidl/android/hardware/graphics/composer3/BlendMode.h>
-#include <aidl/android/hardware/graphics/composer3/ClientTargetProperty.h>
-#include <aidl/android/hardware/graphics/composer3/Color.h>
-#include <aidl/android/hardware/graphics/composer3/Command.h>
-#include <aidl/android/hardware/graphics/composer3/Composition.h>
-#include <aidl/android/hardware/graphics/composer3/FloatColor.h>
-#include <aidl/android/hardware/graphics/composer3/HandleIndex.h>
-#include <aidl/android/hardware/graphics/composer3/IComposer.h>
-#include <aidl/android/hardware/graphics/composer3/IComposerClient.h>
-#include <aidl/android/hardware/graphics/composer3/PerFrameMetadata.h>
-#include <aidl/android/hardware/graphics/composer3/PerFrameMetadataBlob.h>
-
-#include <aidl/android/hardware/graphics/common/ColorTransform.h>
-#include <aidl/android/hardware/graphics/common/FRect.h>
-#include <aidl/android/hardware/graphics/common/Rect.h>
-#include <aidl/android/hardware/graphics/common/Transform.h>
-
-#include <fmq/AidlMessageQueue.h>
-#include <log/log.h>
-#include <sync/sync.h>
-
-#include <aidlcommonsupport/NativeHandle.h>
-
-using aidl::android::hardware::graphics::common::ColorTransform;
-using aidl::android::hardware::graphics::common::Dataspace;
-using aidl::android::hardware::graphics::common::FRect;
-using aidl::android::hardware::graphics::common::Rect;
-using aidl::android::hardware::graphics::common::Transform;
-
-using aidl::android::hardware::graphics::composer3::BlendMode;
-using aidl::android::hardware::graphics::composer3::ClientTargetProperty;
-using aidl::android::hardware::graphics::composer3::Color;
-using aidl::android::hardware::graphics::composer3::Command;
-using aidl::android::hardware::graphics::composer3::Composition;
-using aidl::android::hardware::graphics::composer3::FloatColor;
-using aidl::android::hardware::graphics::composer3::HandleIndex;
-using aidl::android::hardware::graphics::composer3::PerFrameMetadata;
-using aidl::android::hardware::graphics::composer3::PerFrameMetadataBlob;
-
-using aidl::android::hardware::common::NativeHandle;
-using aidl::android::hardware::common::fmq::SynchronizedReadWrite;
-using android::AidlMessageQueue;
-using CommandQueueType = AidlMessageQueue<int32_t, SynchronizedReadWrite>;
-using aidl::android::hardware::common::fmq::MQDescriptor;
-using DescriptorType = MQDescriptor<int32_t, SynchronizedReadWrite>;
-
-namespace aidl::android::hardware::graphics::composer3 {
-
-// This class helps build a command queue.  Note that all sizes/lengths are in
-// units of uint32_t's.
-class CommandWriterBase {
-  public:
-    CommandWriterBase(uint32_t initialMaxSize) : mDataMaxSize(initialMaxSize) {
-        mData = std::make_unique<int32_t[]>(mDataMaxSize);
-        reset();
-    }
-
-    virtual ~CommandWriterBase() { reset(); }
-
-    void reset() {
-        mDataWritten = 0;
-        mCommandEnd = 0;
-
-        // handles in mDataHandles are owned by the caller
-        mDataHandles.clear();
-
-        // handles in mTemporaryHandles are owned by the writer
-        for (auto handle : mTemporaryHandles) {
-            native_handle_close(handle);
-            native_handle_delete(handle);
-        }
-        mTemporaryHandles.clear();
-    }
-
-    Command getCommand(uint32_t offset) {
-        uint32_t val = (offset < mDataWritten) ? mData[offset] : 0;
-        return static_cast<Command>(val & static_cast<uint32_t>(Command::OPCODE_MASK));
-    }
-
-    bool writeQueue(bool* outQueueChanged, int32_t* outCommandLength,
-                    std::vector<NativeHandle>* outCommandHandles) {
-        if (mDataWritten == 0) {
-            *outQueueChanged = false;
-            *outCommandLength = 0;
-            outCommandHandles->clear();
-            return true;
-        }
-
-        // After data are written to the queue, it may not be read by the
-        // remote reader when
-        //
-        //  - the writer does not send them (because of other errors)
-        //  - the hwbinder transaction fails
-        //  - the reader does not read them (because of other errors)
-        //
-        // Discard the stale data here.
-        size_t staleDataSize = mQueue ? mQueue->availableToRead() : 0;
-        if (staleDataSize > 0) {
-            ALOGW("discarding stale data from message queue");
-            CommandQueueType::MemTransaction tx;
-            if (mQueue->beginRead(staleDataSize, &tx)) {
-                mQueue->commitRead(staleDataSize);
-            }
-        }
-
-        // write data to queue, optionally resizing it
-        if (mQueue && (mDataMaxSize <= mQueue->getQuantumCount())) {
-            if (!mQueue->write(mData.get(), mDataWritten)) {
-                ALOGE("failed to write commands to message queue");
-                return false;
-            }
-
-            *outQueueChanged = false;
-        } else {
-            auto newQueue = std::make_unique<CommandQueueType>(mDataMaxSize);
-            if (!newQueue->isValid() || !newQueue->write(mData.get(), mDataWritten)) {
-                ALOGE("failed to prepare a new message queue ");
-                return false;
-            }
-
-            mQueue = std::move(newQueue);
-            *outQueueChanged = true;
-        }
-
-        *outCommandLength = mDataWritten;
-        *outCommandHandles = std::move(mDataHandles);
-
-        return true;
-    }
-
-    DescriptorType getMQDescriptor() const {
-        return (mQueue) ? mQueue->dupeDesc() : DescriptorType{};
-    }
-
-    static constexpr uint16_t kSelectDisplayLength = 2;
-    void selectDisplay(int64_t display) {
-        beginCommand(Command::SELECT_DISPLAY, kSelectDisplayLength);
-        write64(display);
-        endCommand();
-    }
-
-    static constexpr uint16_t kSelectLayerLength = 2;
-    void selectLayer(int64_t layer) {
-        beginCommand(Command::SELECT_LAYER, kSelectLayerLength);
-        write64(layer);
-        endCommand();
-    }
-
-    static constexpr uint16_t kSetErrorLength = 2;
-    void setError(uint32_t location, int32_t error) {
-        beginCommand(Command::SET_ERROR, kSetErrorLength);
-        write(location);
-        writeSigned(error);
-        endCommand();
-    }
-
-    static constexpr uint32_t kPresentOrValidateDisplayResultLength = 1;
-    void setPresentOrValidateResult(uint32_t state) {
-        beginCommand(Command::SET_PRESENT_OR_VALIDATE_DISPLAY_RESULT,
-                     kPresentOrValidateDisplayResultLength);
-        write(state);
-        endCommand();
-    }
-
-    void setChangedCompositionTypes(const std::vector<int64_t>& layers,
-                                    const std::vector<Composition>& types) {
-        size_t totalLayers = std::min(layers.size(), types.size());
-        size_t currentLayer = 0;
-
-        while (currentLayer < totalLayers) {
-            size_t count =
-                    std::min(totalLayers - currentLayer, static_cast<size_t>(kMaxLength) / 3);
-
-            beginCommand(Command::SET_CHANGED_COMPOSITION_TYPES, count * 3);
-            for (size_t i = 0; i < count; i++) {
-                write64(layers[currentLayer + i]);
-                writeSigned(static_cast<int32_t>(types[currentLayer + i]));
-            }
-            endCommand();
-
-            currentLayer += count;
-        }
-    }
-
-    void setDisplayRequests(uint32_t displayRequestMask, const std::vector<int64_t>& layers,
-                            const std::vector<uint32_t>& layerRequestMasks) {
-        size_t totalLayers = std::min(layers.size(), layerRequestMasks.size());
-        size_t currentLayer = 0;
-
-        while (currentLayer < totalLayers) {
-            size_t count =
-                    std::min(totalLayers - currentLayer, static_cast<size_t>(kMaxLength - 1) / 3);
-
-            beginCommand(Command::SET_DISPLAY_REQUESTS, 1 + count * 3);
-            write(displayRequestMask);
-            for (size_t i = 0; i < count; i++) {
-                write64(layers[currentLayer + i]);
-                write(static_cast<int32_t>(layerRequestMasks[currentLayer + i]));
-            }
-            endCommand();
-
-            currentLayer += count;
-        }
-    }
-
-    static constexpr uint16_t kSetPresentFenceLength = 1;
-    void setPresentFence(int presentFence) {
-        beginCommand(Command::SET_PRESENT_FENCE, kSetPresentFenceLength);
-        writeFence(presentFence);
-        endCommand();
-    }
-
-    void setReleaseFences(const std::vector<int64_t>& layers,
-                          const std::vector<int>& releaseFences) {
-        size_t totalLayers = std::min(layers.size(), releaseFences.size());
-        size_t currentLayer = 0;
-
-        while (currentLayer < totalLayers) {
-            size_t count =
-                    std::min(totalLayers - currentLayer, static_cast<size_t>(kMaxLength) / 3);
-
-            beginCommand(Command::SET_RELEASE_FENCES, count * 3);
-            for (size_t i = 0; i < count; i++) {
-                write64(layers[currentLayer + i]);
-                writeFence(releaseFences[currentLayer + i]);
-            }
-            endCommand();
-
-            currentLayer += count;
-        }
-    }
-
-    static constexpr uint16_t kSetColorTransformLength = 17;
-    void setColorTransform(const float* matrix, ColorTransform hint) {
-        beginCommand(Command::SET_COLOR_TRANSFORM, kSetColorTransformLength);
-        for (int i = 0; i < 16; i++) {
-            writeFloat(matrix[i]);
-        }
-        writeSigned(static_cast<int32_t>(hint));
-        endCommand();
-    }
-
-    void setClientTarget(uint32_t slot, const native_handle_t* target, int acquireFence,
-                         Dataspace dataspace, const std::vector<Rect>& damage) {
-        setClientTargetInternal(slot, target, acquireFence, static_cast<int32_t>(dataspace),
-                                damage);
-    }
-
-    static constexpr uint16_t kSetOutputBufferLength = 3;
-    void setOutputBuffer(uint32_t slot, const native_handle_t* buffer, int releaseFence) {
-        beginCommand(Command::SET_OUTPUT_BUFFER, kSetOutputBufferLength);
-        write(slot);
-        writeHandle(buffer, true);
-        writeFence(releaseFence);
-        endCommand();
-    }
-
-    static constexpr uint16_t kValidateDisplayLength = 0;
-    void validateDisplay() {
-        beginCommand(Command::VALIDATE_DISPLAY, kValidateDisplayLength);
-        endCommand();
-    }
-
-    static constexpr uint16_t kPresentOrValidateDisplayLength = 0;
-    void presentOrvalidateDisplay() {
-        beginCommand(Command::PRESENT_OR_VALIDATE_DISPLAY, kPresentOrValidateDisplayLength);
-        endCommand();
-    }
-
-    static constexpr uint16_t kAcceptDisplayChangesLength = 0;
-    void acceptDisplayChanges() {
-        beginCommand(Command::ACCEPT_DISPLAY_CHANGES, kAcceptDisplayChangesLength);
-        endCommand();
-    }
-
-    static constexpr uint16_t kPresentDisplayLength = 0;
-    void presentDisplay() {
-        beginCommand(Command::PRESENT_DISPLAY, kPresentDisplayLength);
-        endCommand();
-    }
-
-    static constexpr uint16_t kSetLayerCursorPositionLength = 2;
-    void setLayerCursorPosition(int32_t x, int32_t y) {
-        beginCommand(Command::SET_LAYER_CURSOR_POSITION, kSetLayerCursorPositionLength);
-        writeSigned(x);
-        writeSigned(y);
-        endCommand();
-    }
-
-    static constexpr uint16_t kSetLayerBufferLength = 3;
-    void setLayerBuffer(uint32_t slot, const native_handle_t* buffer, int acquireFence) {
-        beginCommand(Command::SET_LAYER_BUFFER, kSetLayerBufferLength);
-        write(slot);
-        writeHandle(buffer, true);
-        writeFence(acquireFence);
-        endCommand();
-    }
-
-    void setLayerSurfaceDamage(const std::vector<Rect>& damage) {
-        bool doWrite = (damage.size() <= kMaxLength / 4);
-        size_t length = (doWrite) ? damage.size() * 4 : 0;
-
-        beginCommand(Command::SET_LAYER_SURFACE_DAMAGE, length);
-        // When there are too many rectangles in the damage region and doWrite
-        // is false, we write no rectangle at all which means the entire
-        // layer is damaged.
-        if (doWrite) {
-            writeRegion(damage);
-        }
-        endCommand();
-    }
-
-    static constexpr uint16_t kSetLayerBlendModeLength = 1;
-    void setLayerBlendMode(BlendMode mode) {
-        beginCommand(Command::SET_LAYER_BLEND_MODE, kSetLayerBlendModeLength);
-        writeSigned(static_cast<int32_t>(mode));
-        endCommand();
-    }
-
-    static constexpr uint16_t kSetLayerColorLength = 1;
-    void setLayerColor(Color color) {
-        beginCommand(Command::SET_LAYER_COLOR, kSetLayerColorLength);
-        writeColor(color);
-        endCommand();
-    }
-
-    static constexpr uint16_t kSetLayerCompositionTypeLength = 1;
-    void setLayerCompositionType(Composition type) {
-        beginCommand(Command::SET_LAYER_COMPOSITION_TYPE, kSetLayerCompositionTypeLength);
-        writeSigned(static_cast<int32_t>(type));
-        endCommand();
-    }
-
-    static constexpr uint16_t kSetLayerDataspaceLength = 1;
-    void setLayerDataspace(Dataspace dataspace) {
-        setLayerDataspaceInternal(static_cast<int32_t>(dataspace));
-    }
-
-    static constexpr uint16_t kSetLayerDisplayFrameLength = 4;
-    void setLayerDisplayFrame(const Rect& frame) {
-        beginCommand(Command::SET_LAYER_DISPLAY_FRAME, kSetLayerDisplayFrameLength);
-        writeRect(frame);
-        endCommand();
-    }
-
-    static constexpr uint16_t kSetLayerPlaneAlphaLength = 1;
-    void setLayerPlaneAlpha(float alpha) {
-        beginCommand(Command::SET_LAYER_PLANE_ALPHA, kSetLayerPlaneAlphaLength);
-        writeFloat(alpha);
-        endCommand();
-    }
-
-    static constexpr uint16_t kSetLayerSidebandStreamLength = 1;
-    void setLayerSidebandStream(const native_handle_t* stream) {
-        beginCommand(Command::SET_LAYER_SIDEBAND_STREAM, kSetLayerSidebandStreamLength);
-        writeHandle(stream);
-        endCommand();
-    }
-
-    static constexpr uint16_t kSetLayerSourceCropLength = 4;
-    void setLayerSourceCrop(const FRect& crop) {
-        beginCommand(Command::SET_LAYER_SOURCE_CROP, kSetLayerSourceCropLength);
-        writeFRect(crop);
-        endCommand();
-    }
-
-    static constexpr uint16_t kSetLayerTransformLength = 1;
-    void setLayerTransform(Transform transform) {
-        beginCommand(Command::SET_LAYER_TRANSFORM, kSetLayerTransformLength);
-        writeSigned(static_cast<int32_t>(transform));
-        endCommand();
-    }
-
-    void setLayerVisibleRegion(const std::vector<Rect>& visible) {
-        bool doWrite = (visible.size() <= kMaxLength / 4);
-        size_t length = (doWrite) ? visible.size() * 4 : 0;
-
-        beginCommand(Command::SET_LAYER_VISIBLE_REGION, length);
-        // When there are too many rectangles in the visible region and
-        // doWrite is false, we write no rectangle at all which means the
-        // entire layer is visible.
-        if (doWrite) {
-            writeRegion(visible);
-        }
-        endCommand();
-    }
-
-    static constexpr uint16_t kSetLayerZOrderLength = 1;
-    void setLayerZOrder(uint32_t z) {
-        beginCommand(Command::SET_LAYER_Z_ORDER, kSetLayerZOrderLength);
-        write(z);
-        endCommand();
-    }
-
-    void setLayerPerFrameMetadata(const std::vector<PerFrameMetadata>& metadataVec) {
-        beginCommand(Command::SET_LAYER_PER_FRAME_METADATA, metadataVec.size() * 2);
-        for (const auto& metadata : metadataVec) {
-            writeSigned(static_cast<int32_t>(metadata.key));
-            writeFloat(metadata.value);
-        }
-        endCommand();
-    }
-
-    static constexpr uint16_t kSetLayerColorTransformLength = 16;
-    void setLayerColorTransform(const float* matrix) {
-        beginCommand(Command::SET_LAYER_COLOR_TRANSFORM, kSetLayerColorTransformLength);
-        for (int i = 0; i < 16; i++) {
-            writeFloat(matrix[i]);
-        }
-        endCommand();
-    }
-
-    void setLayerPerFrameMetadataBlobs(const std::vector<PerFrameMetadataBlob>& metadata) {
-        // in units of uint32_t's
-        size_t commandLength = 0;
-
-        if (metadata.size() > std::numeric_limits<uint32_t>::max()) {
-            LOG_FATAL("too many metadata blobs - dynamic metadata size is too large");
-            return;
-        }
-
-        // space for numElements
-        commandLength += 1;
-
-        for (auto metadataBlob : metadata) {
-            commandLength += 1;  // key of metadata blob
-            commandLength += 1;  // size information of metadata blob
-
-            // metadata content size
-            size_t metadataSize = metadataBlob.blob.size() / sizeof(uint32_t);
-            commandLength += metadataSize;
-            commandLength +=
-                    (metadataBlob.blob.size() - (metadataSize * sizeof(uint32_t)) > 0) ? 1 : 0;
-        }
-
-        if (commandLength > std::numeric_limits<uint16_t>::max()) {
-            LOG_FATAL("dynamic metadata size is too large");
-            return;
-        }
-
-        // Blobs are written as:
-        // {numElements, key1, size1, blob1, key2, size2, blob2, key3, size3...}
-        uint16_t length = static_cast<uint16_t>(commandLength);
-        beginCommand(Command::SET_LAYER_PER_FRAME_METADATA_BLOBS, length);
-        write(static_cast<uint32_t>(metadata.size()));
-        for (auto metadataBlob : metadata) {
-            writeSigned(static_cast<int32_t>(metadataBlob.key));
-            write(static_cast<uint32_t>(metadataBlob.blob.size()));
-            writeBlob(static_cast<uint32_t>(metadataBlob.blob.size()), metadataBlob.blob.data());
-        }
-        endCommand();
-    }
-
-    static constexpr uint16_t kSetLayerFloatColorLength = 4;
-    void setLayerFloatColor(FloatColor color) {
-        beginCommand(Command::SET_LAYER_FLOAT_COLOR, kSetLayerFloatColorLength);
-        writeFloatColor(color);
-        endCommand();
-    }
-
-    static constexpr uint16_t kSetClientTargetPropertyLength = 2;
-    void setClientTargetProperty(const ClientTargetProperty& clientTargetProperty) {
-        beginCommand(Command::SET_CLIENT_TARGET_PROPERTY, kSetClientTargetPropertyLength);
-        writeSigned(static_cast<int32_t>(clientTargetProperty.pixelFormat));
-        writeSigned(static_cast<int32_t>(clientTargetProperty.dataspace));
-        endCommand();
-    }
-
-    void setLayerGenericMetadata(const std::string& key, const bool mandatory,
-                                 const std::vector<uint8_t>& value) {
-        const size_t commandSize = 3 + sizeToElements(key.size()) + sizeToElements(value.size());
-        if (commandSize > std::numeric_limits<uint16_t>::max()) {
-            LOG_FATAL("Too much generic metadata (%zu elements)", commandSize);
-            return;
-        }
-
-        beginCommand(Command::SET_LAYER_GENERIC_METADATA, static_cast<uint16_t>(commandSize));
-        write(key.size());
-        writeBlob(key.size(), reinterpret_cast<const unsigned char*>(key.c_str()));
-        write(mandatory);
-        write(value.size());
-        writeBlob(value.size(), value.data());
-        endCommand();
-    }
-
-  protected:
-    template <typename T>
-    void beginCommand(T command, uint16_t length) {
-        beginCommandBase(static_cast<Command>(command), length);
-    }
-
-    void setClientTargetInternal(uint32_t slot, const native_handle_t* target, int acquireFence,
-                                 int32_t dataspace, const std::vector<Rect>& damage) {
-        bool doWrite = (damage.size() <= (kMaxLength - 4) / 4);
-        size_t length = 4 + ((doWrite) ? damage.size() * 4 : 0);
-
-        beginCommand(Command::SET_CLIENT_TARGET, length);
-        write(slot);
-        writeHandle(target, true);
-        writeFence(acquireFence);
-        writeSigned(dataspace);
-        // When there are too many rectangles in the damage region and doWrite
-        // is false, we write no rectangle at all which means the entire
-        // client target is damaged.
-        if (doWrite) {
-            writeRegion(damage);
-        }
-        endCommand();
-    }
-
-    void setLayerDataspaceInternal(int32_t dataspace) {
-        beginCommand(Command::SET_LAYER_DATASPACE, kSetLayerDataspaceLength);
-        writeSigned(dataspace);
-        endCommand();
-    }
-
-    void beginCommandBase(Command command, uint16_t length) {
-        if (mCommandEnd) {
-            LOG_FATAL("endCommand was not called before command 0x%x", command);
-        }
-
-        growData(1 + length);
-        write(static_cast<uint32_t>(command) | length);
-
-        mCommandEnd = mDataWritten + length;
-    }
-
-    void endCommand() {
-        if (!mCommandEnd) {
-            LOG_FATAL("beginCommand was not called");
-        } else if (mDataWritten > mCommandEnd) {
-            LOG_FATAL("too much data written");
-            mDataWritten = mCommandEnd;
-        } else if (mDataWritten < mCommandEnd) {
-            LOG_FATAL("too little data written");
-            while (mDataWritten < mCommandEnd) {
-                write(0);
-            }
-        }
-
-        mCommandEnd = 0;
-    }
-
-    void write(uint32_t val) { mData[mDataWritten++] = val; }
-
-    void writeSigned(int32_t val) { memcpy(&mData[mDataWritten++], &val, sizeof(val)); }
-
-    void writeFloat(float val) { memcpy(&mData[mDataWritten++], &val, sizeof(val)); }
-
-    void write64(uint64_t val) {
-        uint32_t lo = static_cast<uint32_t>(val & 0xffffffff);
-        uint32_t hi = static_cast<uint32_t>(val >> 32);
-        write(lo);
-        write(hi);
-    }
-
-    void writeRect(const Rect& rect) {
-        writeSigned(rect.left);
-        writeSigned(rect.top);
-        writeSigned(rect.right);
-        writeSigned(rect.bottom);
-    }
-
-    void writeRegion(const std::vector<Rect>& region) {
-        for (const auto& rect : region) {
-            writeRect(rect);
-        }
-    }
-
-    void writeFRect(const FRect& rect) {
-        writeFloat(rect.left);
-        writeFloat(rect.top);
-        writeFloat(rect.right);
-        writeFloat(rect.bottom);
-    }
-
-    void writeColor(const Color& color) {
-        write((color.r << 0) | (color.g << 8) | (color.b << 16) | (color.a << 24));
-    }
-
-    void writeFloatColor(const FloatColor& color) {
-        writeFloat(color.r);
-        writeFloat(color.g);
-        writeFloat(color.b);
-        writeFloat(color.a);
-    }
-
-    void writeBlob(uint32_t length, const unsigned char* blob) {
-        memcpy(&mData[mDataWritten], blob, length);
-        uint32_t numElements = length / 4;
-        mDataWritten += numElements;
-        mDataWritten += (length - (numElements * 4) > 0) ? 1 : 0;
-    }
-
-    // ownership of handle is not transferred
-    void writeHandle(const native_handle_t* handle, bool useCache) {
-        if (!handle) {
-            writeSigned(
-                    static_cast<int32_t>((useCache) ? HandleIndex::CACHED : HandleIndex::EMPTY));
-            return;
-        }
-
-        mDataHandles.push_back(::android::dupToAidl(handle));
-        writeSigned(mDataHandles.size() - 1);
-    }
-
-    void writeHandle(const native_handle_t* handle) { writeHandle(handle, false); }
-
-    // ownership of fence is transferred
-    void writeFence(int fence) {
-        native_handle_t* handle = nullptr;
-        if (fence >= 0) {
-            handle = getTemporaryHandle(1, 0);
-            if (handle) {
-                handle->data[0] = fence;
-            } else {
-                ALOGW("failed to get temporary handle for fence %d", fence);
-                sync_wait(fence, -1);
-                close(fence);
-            }
-        }
-
-        writeHandle(handle);
-    }
-
-    native_handle_t* getTemporaryHandle(int numFds, int numInts) {
-        native_handle_t* handle = native_handle_create(numFds, numInts);
-        if (handle) {
-            mTemporaryHandles.push_back(handle);
-        }
-        return handle;
-    }
-
-    static constexpr uint16_t kMaxLength = std::numeric_limits<uint16_t>::max();
-
-    std::unique_ptr<int32_t[]> mData;
-    uint32_t mDataWritten;
-
-  private:
-    void growData(uint32_t grow) {
-        uint32_t newWritten = mDataWritten + grow;
-        if (newWritten < mDataWritten) {
-            LOG_ALWAYS_FATAL("buffer overflowed; data written %" PRIu32 ", growing by %" PRIu32,
-                             mDataWritten, grow);
-        }
-
-        if (newWritten <= mDataMaxSize) {
-            return;
-        }
-
-        uint32_t newMaxSize = mDataMaxSize << 1;
-        if (newMaxSize < newWritten) {
-            newMaxSize = newWritten;
-        }
-
-        auto newData = std::make_unique<int32_t[]>(newMaxSize);
-        std::copy_n(mData.get(), mDataWritten, newData.get());
-        mDataMaxSize = newMaxSize;
-        mData = std::move(newData);
-    }
-
-    uint32_t sizeToElements(uint32_t size) { return (size + 3) / 4; }
-
-    uint32_t mDataMaxSize;
-    // end offset of the current command
-    uint32_t mCommandEnd;
-
-    std::vector<NativeHandle> mDataHandles;
-    std::vector<native_handle_t*> mTemporaryHandles;
-
-    std::unique_ptr<CommandQueueType> mQueue;
-};
-
-// This class helps parse a command queue.  Note that all sizes/lengths are in
-// units of uint32_t's.
-class CommandReaderBase {
-  public:
-    CommandReaderBase() : mDataMaxSize(0) { reset(); }
-
-    bool setMQDescriptor(const DescriptorType& descriptor) {
-        mQueue = std::make_unique<CommandQueueType>(descriptor, false);
-        if (mQueue->isValid()) {
-            return true;
-        } else {
-            mQueue = nullptr;
-            return false;
-        }
-    }
-
-    bool readQueue(int32_t commandLength, std::vector<NativeHandle> commandHandles) {
-        if (!mQueue) {
-            return false;
-        }
-
-        auto quantumCount = mQueue->getQuantumCount();
-        if (mDataMaxSize < quantumCount) {
-            mDataMaxSize = quantumCount;
-            mData = std::make_unique<int32_t[]>(mDataMaxSize);
-        }
-
-        if (commandLength > mDataMaxSize || !mQueue->read(mData.get(), commandLength)) {
-            ALOGE("failed to read commands from message queue");
-            return false;
-        }
-
-        mDataSize = commandLength;
-        mDataRead = 0;
-        mCommandBegin = 0;
-        mCommandEnd = 0;
-        mDataHandles = std::move(commandHandles);
-        return true;
-    }
-
-    void reset() {
-        mDataSize = 0;
-        mDataRead = 0;
-        mCommandBegin = 0;
-        mCommandEnd = 0;
-        mDataHandles.clear();
-    }
-
-  protected:
-    template <typename T>
-    bool beginCommand(T* outCommand, uint16_t* outLength) {
-        return beginCommandBase(reinterpret_cast<Command*>(outCommand), outLength);
-    }
-
-    bool isEmpty() const { return (mDataRead >= mDataSize); }
-
-    bool beginCommandBase(Command* outCommand, uint16_t* outLength) {
-        if (mCommandEnd) {
-            LOG_FATAL("endCommand was not called for last command");
-        }
-
-        constexpr uint32_t opcode_mask = static_cast<uint32_t>(Command::OPCODE_MASK);
-        constexpr uint32_t length_mask = static_cast<uint32_t>(Command::LENGTH_MASK);
-
-        uint32_t val = read();
-        *outCommand = static_cast<Command>(val & opcode_mask);
-        *outLength = static_cast<uint16_t>(val & length_mask);
-
-        if (mDataRead + *outLength > mDataSize) {
-            ALOGE("command 0x%x has invalid command length %" PRIu16, *outCommand, *outLength);
-            // undo the read() above
-            mDataRead--;
-            return false;
-        }
-
-        mCommandEnd = mDataRead + *outLength;
-
-        return true;
-    }
-
-    void endCommand() {
-        if (!mCommandEnd) {
-            LOG_FATAL("beginCommand was not called");
-        } else if (mDataRead > mCommandEnd) {
-            LOG_FATAL("too much data read");
-            mDataRead = mCommandEnd;
-        } else if (mDataRead < mCommandEnd) {
-            LOG_FATAL("too little data read");
-            mDataRead = mCommandEnd;
-        }
-
-        mCommandBegin = mCommandEnd;
-        mCommandEnd = 0;
-    }
-
-    uint32_t getCommandLoc() const { return mCommandBegin; }
-
-    uint32_t read() { return mData[mDataRead++]; }
-
-    int32_t readSigned() {
-        int32_t val;
-        memcpy(&val, &mData[mDataRead++], sizeof(val));
-        return val;
-    }
-
-    float readFloat() {
-        float val;
-        memcpy(&val, &mData[mDataRead++], sizeof(val));
-        return val;
-    }
-
-    uint64_t read64() {
-        uint32_t lo = read();
-        uint32_t hi = read();
-        return (static_cast<uint64_t>(hi) << 32) | lo;
-    }
-
-    Color readColor() {
-        uint32_t val = read();
-        return Color{
-                static_cast<int8_t>((val >> 0) & 0xff),
-                static_cast<int8_t>((val >> 8) & 0xff),
-                static_cast<int8_t>((val >> 16) & 0xff),
-                static_cast<int8_t>((val >> 24) & 0xff),
-        };
-    }
-
-    // ownership of handle is not transferred
-    const native_handle_t* readHandle(bool* outUseCache) {
-        const native_handle_t* handle = nullptr;
-
-        int32_t index = readSigned();
-        switch (index) {
-            case static_cast<int32_t>(HandleIndex::EMPTY):
-                *outUseCache = false;
-                break;
-            case static_cast<int32_t>(HandleIndex::CACHED):
-                *outUseCache = true;
-                break;
-            default:
-                if (static_cast<size_t>(index) < mDataHandles.size()) {
-                    handle = ::android::makeFromAidl(mDataHandles[index]);
-                } else {
-                    ALOGE("invalid handle index %zu", static_cast<size_t>(index));
-                }
-                *outUseCache = false;
-                break;
-        }
-
-        return handle;
-    }
-
-    const native_handle_t* readHandle() {
-        bool useCache;
-        return readHandle(&useCache);
-    }
-
-    // ownership of fence is transferred
-    int readFence() {
-        auto handle = readHandle();
-        if (!handle || handle->numFds == 0) {
-            return -1;
-        }
-
-        if (handle->numFds != 1) {
-            ALOGE("invalid fence handle with %d fds", handle->numFds);
-            return -1;
-        }
-
-        int fd = dup(handle->data[0]);
-        if (fd < 0) {
-            ALOGW("failed to dup fence %d", handle->data[0]);
-            sync_wait(handle->data[0], -1);
-            fd = -1;
-        }
-
-        return fd;
-    }
-
-    std::unique_ptr<int32_t[]> mData;
-    uint32_t mDataRead;
-
-  private:
-    std::unique_ptr<CommandQueueType> mQueue;
-    uint32_t mDataMaxSize;
-
-    uint32_t mDataSize;
-
-    // begin/end offsets of the current command
-    uint32_t mCommandBegin;
-    uint32_t mCommandEnd;
-
-    std::vector<NativeHandle> mDataHandles;
-};
-
-}  // namespace aidl::android::hardware::graphics::composer3
diff --git a/graphics/composer/aidl/include/android/hardware/graphics/composer3/translate-ndk.h b/graphics/composer/aidl/include/android/hardware/graphics/composer3/translate-ndk.h
index c892863..7004955 100644
--- a/graphics/composer/aidl/include/android/hardware/graphics/composer3/translate-ndk.h
+++ b/graphics/composer/aidl/include/android/hardware/graphics/composer3/translate-ndk.h
@@ -17,25 +17,22 @@
 #pragma once
 
 #include <limits>
+#include "aidl/android/hardware/graphics/common/BlendMode.h"
 #include "aidl/android/hardware/graphics/common/FRect.h"
 #include "aidl/android/hardware/graphics/common/Rect.h"
-#include "aidl/android/hardware/graphics/composer3/BlendMode.h"
 #include "aidl/android/hardware/graphics/composer3/Capability.h"
 #include "aidl/android/hardware/graphics/composer3/ClientTargetProperty.h"
 #include "aidl/android/hardware/graphics/composer3/Color.h"
-#include "aidl/android/hardware/graphics/composer3/Command.h"
 #include "aidl/android/hardware/graphics/composer3/Composition.h"
 #include "aidl/android/hardware/graphics/composer3/ContentType.h"
 #include "aidl/android/hardware/graphics/composer3/DisplayAttribute.h"
 #include "aidl/android/hardware/graphics/composer3/DisplayCapability.h"
 #include "aidl/android/hardware/graphics/composer3/DisplayConnectionType.h"
-#include "aidl/android/hardware/graphics/composer3/DisplayRequest.h"
 #include "aidl/android/hardware/graphics/composer3/FloatColor.h"
 #include "aidl/android/hardware/graphics/composer3/FormatColorComponent.h"
 #include "aidl/android/hardware/graphics/composer3/HandleIndex.h"
 #include "aidl/android/hardware/graphics/composer3/IComposer.h"
 #include "aidl/android/hardware/graphics/composer3/LayerGenericMetadataKey.h"
-#include "aidl/android/hardware/graphics/composer3/LayerRequest.h"
 #include "aidl/android/hardware/graphics/composer3/PerFrameMetadata.h"
 #include "aidl/android/hardware/graphics/composer3/PerFrameMetadataBlob.h"
 #include "aidl/android/hardware/graphics/composer3/PerFrameMetadataKey.h"
diff --git a/health/aidl/Android.bp b/health/aidl/Android.bp
index fae7592..6e2f1d4 100644
--- a/health/aidl/Android.bp
+++ b/health/aidl/Android.bp
@@ -25,6 +25,7 @@
     name: "android.hardware.health",
     vendor_available: true,
     recovery_available: true,
+    host_supported: true,
     srcs: ["android/hardware/health/*.aidl"],
     stability: "vintf",
     backend: {
@@ -48,6 +49,7 @@
     name: "android.hardware.health-translate-ndk",
     vendor_available: true,
     recovery_available: true,
+    host_supported: true,
     srcs: ["android/hardware/health/translate-ndk.cpp"],
     shared_libs: [
         "libbinder_ndk",
@@ -61,6 +63,9 @@
         "android.hardware.health@2.0",
         "android.hardware.health@2.1",
     ],
+    defaults: [
+        "libbinder_ndk_host_user",
+    ],
 }
 
 java_library {
diff --git a/health/aidl/android/hardware/health/translate-ndk.cpp b/health/aidl/android/hardware/health/translate-ndk.cpp
index 7fe6ced..78880cc 100644
--- a/health/aidl/android/hardware/health/translate-ndk.cpp
+++ b/health/aidl/android/hardware/health/translate-ndk.cpp
@@ -106,36 +106,41 @@
 }
 
 __attribute__((warn_unused_result)) bool translate(
+        const ::android::hardware::health::V2_0::HealthInfo& in,
+        aidl::android::hardware::health::HealthInfo* out) {
+    out->chargerAcOnline = static_cast<bool>(in.legacy.chargerAcOnline);
+    out->chargerUsbOnline = static_cast<bool>(in.legacy.chargerUsbOnline);
+    out->chargerWirelessOnline = static_cast<bool>(in.legacy.chargerWirelessOnline);
+    out->maxChargingCurrentMicroamps = static_cast<int32_t>(in.legacy.maxChargingCurrent);
+    out->maxChargingVoltageMicrovolts = static_cast<int32_t>(in.legacy.maxChargingVoltage);
+    out->batteryStatus =
+            static_cast<aidl::android::hardware::health::BatteryStatus>(in.legacy.batteryStatus);
+    out->batteryHealth =
+            static_cast<aidl::android::hardware::health::BatteryHealth>(in.legacy.batteryHealth);
+    out->batteryPresent = static_cast<bool>(in.legacy.batteryPresent);
+    out->batteryLevel = static_cast<int32_t>(in.legacy.batteryLevel);
+    out->batteryVoltageMillivolts = static_cast<int32_t>(in.legacy.batteryVoltage);
+    out->batteryTemperatureTenthsCelsius = static_cast<int32_t>(in.legacy.batteryTemperature);
+    out->batteryCurrentMicroamps = static_cast<int32_t>(in.legacy.batteryCurrent);
+    out->batteryCycleCount = static_cast<int32_t>(in.legacy.batteryCycleCount);
+    out->batteryFullChargeUah = static_cast<int32_t>(in.legacy.batteryFullCharge);
+    out->batteryChargeCounterUah = static_cast<int32_t>(in.legacy.batteryChargeCounter);
+    out->batteryTechnology = in.legacy.batteryTechnology;
+    out->batteryCurrentAverageMicroamps = static_cast<int32_t>(in.batteryCurrentAverage);
+    out->diskStats.clear();
+    out->diskStats.resize(in.diskStats.size());
+    for (size_t i = 0; i < in.diskStats.size(); ++i)
+        if (!translate(in.diskStats[i], &out->diskStats[i])) return false;
+    out->storageInfos.clear();
+    out->storageInfos.resize(in.storageInfos.size());
+    for (size_t i = 0; i < in.storageInfos.size(); ++i)
+        if (!translate(in.storageInfos[i], &out->storageInfos[i])) return false;
+    return true;
+}
+__attribute__((warn_unused_result)) bool translate(
         const ::android::hardware::health::V2_1::HealthInfo& in,
         aidl::android::hardware::health::HealthInfo* out) {
-    out->chargerAcOnline = static_cast<bool>(in.legacy.legacy.chargerAcOnline);
-    out->chargerUsbOnline = static_cast<bool>(in.legacy.legacy.chargerUsbOnline);
-    out->chargerWirelessOnline = static_cast<bool>(in.legacy.legacy.chargerWirelessOnline);
-    out->maxChargingCurrentMicroamps = static_cast<int32_t>(in.legacy.legacy.maxChargingCurrent);
-    out->maxChargingVoltageMicrovolts = static_cast<int32_t>(in.legacy.legacy.maxChargingVoltage);
-    out->batteryStatus = static_cast<aidl::android::hardware::health::BatteryStatus>(
-            in.legacy.legacy.batteryStatus);
-    out->batteryHealth = static_cast<aidl::android::hardware::health::BatteryHealth>(
-            in.legacy.legacy.batteryHealth);
-    out->batteryPresent = static_cast<bool>(in.legacy.legacy.batteryPresent);
-    out->batteryLevel = static_cast<int32_t>(in.legacy.legacy.batteryLevel);
-    out->batteryVoltageMillivolts = static_cast<int32_t>(in.legacy.legacy.batteryVoltage);
-    out->batteryTemperatureTenthsCelsius =
-            static_cast<int32_t>(in.legacy.legacy.batteryTemperature);
-    out->batteryCurrentMicroamps = static_cast<int32_t>(in.legacy.legacy.batteryCurrent);
-    out->batteryCycleCount = static_cast<int32_t>(in.legacy.legacy.batteryCycleCount);
-    out->batteryFullChargeUah = static_cast<int32_t>(in.legacy.legacy.batteryFullCharge);
-    out->batteryChargeCounterUah = static_cast<int32_t>(in.legacy.legacy.batteryChargeCounter);
-    out->batteryTechnology = in.legacy.legacy.batteryTechnology;
-    out->batteryCurrentAverageMicroamps = static_cast<int32_t>(in.legacy.batteryCurrentAverage);
-    out->diskStats.clear();
-    out->diskStats.resize(in.legacy.diskStats.size());
-    for (size_t i = 0; i < in.legacy.diskStats.size(); ++i)
-        if (!translate(in.legacy.diskStats[i], &out->diskStats[i])) return false;
-    out->storageInfos.clear();
-    out->storageInfos.resize(in.legacy.storageInfos.size());
-    for (size_t i = 0; i < in.legacy.storageInfos.size(); ++i)
-        if (!translate(in.legacy.storageInfos[i], &out->storageInfos[i])) return false;
+    if (!translate(in.legacy, out)) return false;
     out->batteryCapacityLevel = static_cast<aidl::android::hardware::health::BatteryCapacityLevel>(
             in.batteryCapacityLevel);
     out->batteryChargeTimeToFullNowSeconds =
diff --git a/health/aidl/include/android/hardware/health/translate-ndk.h b/health/aidl/include/android/hardware/health/translate-ndk.h
index 2f8fe04..91add42 100644
--- a/health/aidl/include/android/hardware/health/translate-ndk.h
+++ b/health/aidl/include/android/hardware/health/translate-ndk.h
@@ -33,6 +33,9 @@
         const ::android::hardware::health::V2_0::DiskStats& in,
         aidl::android::hardware::health::DiskStats* out);
 __attribute__((warn_unused_result)) bool translate(
+        const ::android::hardware::health::V2_0::HealthInfo& in,
+        aidl::android::hardware::health::HealthInfo* out);
+__attribute__((warn_unused_result)) bool translate(
         const ::android::hardware::health::V2_1::HealthInfo& in,
         aidl::android::hardware::health::HealthInfo* out);
 
diff --git a/health/utils/libhealthshim/Android.bp b/health/utils/libhealthshim/Android.bp
new file mode 100644
index 0000000..311e951
--- /dev/null
+++ b/health/utils/libhealthshim/Android.bp
@@ -0,0 +1,78 @@
+// 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_defaults {
+    name: "libhealthshim_defaults",
+    host_supported: true, // for testing
+    defaults: [
+        "libbinder_ndk_host_user",
+    ],
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
+    static_libs: [
+        "android.hardware.health-V1-ndk",
+        "android.hardware.health-translate-ndk",
+        "android.hardware.health@1.0",
+        "android.hardware.health@2.0",
+    ],
+    shared_libs: [
+        // These can be expected from the device or from host.
+        "libbase",
+        "libbinder_ndk",
+        "libcutils",
+        "libhidlbase",
+        "liblog",
+        "libutils",
+    ],
+}
+
+// Shim library that wraps a HIDL IHealth object into an AIDL IHealth object.
+cc_library_static {
+    name: "libhealthshim",
+    defaults: ["libhealthshim_defaults"],
+    recovery_available: true,
+    srcs: [
+        "shim.cpp",
+    ],
+    export_include_dirs: [
+        "include",
+    ],
+}
+
+cc_test {
+    name: "libhealthshim_test",
+    defaults: ["libhealthshim_defaults"],
+    static_libs: [
+        "libhealthshim",
+        "libgmock",
+    ],
+    srcs: [
+        "test.cpp",
+    ],
+    test_suites: ["general-tests"],
+    test_options: {
+        unit_test: true,
+    },
+}
diff --git a/health/utils/libhealthshim/include/health-shim/shim.h b/health/utils/libhealthshim/include/health-shim/shim.h
new file mode 100644
index 0000000..f36fa5d
--- /dev/null
+++ b/health/utils/libhealthshim/include/health-shim/shim.h
@@ -0,0 +1,55 @@
+/*
+ * 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 <map>
+
+#include <aidl/android/hardware/health/BnHealth.h>
+#include <android/hardware/health/2.0/IHealth.h>
+
+namespace aidl::android::hardware::health {
+
+// Shim that wraps HIDL IHealth with an AIDL BnHealth.
+// The wrapper always have isRemote() == false because it is BnHealth.
+class HealthShim : public BnHealth {
+    using HidlHealth = ::android::hardware::health::V2_0::IHealth;
+    using HidlHealthInfoCallback = ::android::hardware::health::V2_0::IHealthInfoCallback;
+
+  public:
+    explicit HealthShim(const ::android::sp<HidlHealth>& service);
+
+    ndk::ScopedAStatus registerCallback(
+            const std::shared_ptr<IHealthInfoCallback>& in_callback) override;
+    ndk::ScopedAStatus unregisterCallback(
+            const std::shared_ptr<IHealthInfoCallback>& in_callback) override;
+    ndk::ScopedAStatus update() override;
+    ndk::ScopedAStatus getChargeCounterUah(int32_t* _aidl_return) override;
+    ndk::ScopedAStatus getCurrentNowMicroamps(int32_t* _aidl_return) override;
+    ndk::ScopedAStatus getCurrentAverageMicroamps(int32_t* _aidl_return) override;
+    ndk::ScopedAStatus getCapacity(int32_t* _aidl_return) override;
+    ndk::ScopedAStatus getEnergyCounterNwh(int64_t* _aidl_return) override;
+    ndk::ScopedAStatus getChargeStatus(BatteryStatus* _aidl_return) override;
+    ndk::ScopedAStatus getStorageInfo(std::vector<StorageInfo>* _aidl_return) override;
+    ndk::ScopedAStatus getDiskStats(std::vector<DiskStats>* _aidl_return) override;
+    ndk::ScopedAStatus getHealthInfo(HealthInfo* _aidl_return) override;
+
+  private:
+    ::android::sp<HidlHealth> service_;
+    std::map<std::shared_ptr<IHealthInfoCallback>, ::android::sp<HidlHealthInfoCallback>>
+            callback_map_;
+};
+
+}  // namespace aidl::android::hardware::health
diff --git a/health/utils/libhealthshim/shim.cpp b/health/utils/libhealthshim/shim.cpp
new file mode 100644
index 0000000..1329679
--- /dev/null
+++ b/health/utils/libhealthshim/shim.cpp
@@ -0,0 +1,220 @@
+/*
+ * 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/hardware/health/translate-ndk.h>
+#include <health-shim/shim.h>
+
+using ::android::sp;
+using ::android::h2a::translate;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::health::V2_0::Result;
+using ::android::hardware::health::V2_0::toString;
+using ::ndk::ScopedAStatus;
+using HidlHealth = ::android::hardware::health::V2_0::IHealth;
+using HidlHealthInfoCallback = ::android::hardware::health::V2_0::IHealthInfoCallback;
+using HidlHealthInfo = ::android::hardware::health::V2_0::HealthInfo;
+
+namespace aidl::android::hardware::health {
+
+namespace {
+
+class HealthInfoCallbackShim : public HidlHealthInfoCallback {
+    using AidlHealthInfoCallback = ::aidl::android::hardware::health::IHealthInfoCallback;
+    using AidlHealthInfo = ::aidl::android::hardware::health::HealthInfo;
+
+  public:
+    explicit HealthInfoCallbackShim(const std::shared_ptr<AidlHealthInfoCallback>& impl)
+        : impl_(impl) {}
+    Return<void> healthInfoChanged(const HidlHealthInfo& info) override {
+        AidlHealthInfo aidl_info;
+        // translate() should always return true.
+        CHECK(translate(info, &aidl_info));
+        // This is a oneway function, so we can't (and shouldn't) check for errors.
+        (void)impl_->healthInfoChanged(aidl_info);
+        return Void();
+    }
+
+  private:
+    std::shared_ptr<AidlHealthInfoCallback> impl_;
+};
+
+ScopedAStatus ResultToStatus(Result result) {
+    switch (result) {
+        case Result::SUCCESS:
+            return ScopedAStatus::ok();
+        case Result::NOT_SUPPORTED:
+            return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+        case Result::UNKNOWN:
+            return ScopedAStatus::fromServiceSpecificError(IHealth::STATUS_UNKNOWN);
+        case Result::NOT_FOUND:
+            return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+        case Result::CALLBACK_DIED:
+            return ScopedAStatus::fromServiceSpecificError(IHealth::STATUS_CALLBACK_DIED);
+    }
+    return ScopedAStatus::fromServiceSpecificErrorWithMessage(
+            IHealth::STATUS_UNKNOWN, ("Unrecognized result value " + toString(result)).c_str());
+}
+
+template <typename T>
+ScopedAStatus ReturnAndResultToStatus(const Return<T>& ret, Result result) {
+    if (ret.isOk()) {
+        return ResultToStatus(result);
+    }
+    if (ret.isDeadObject()) {
+        return ScopedAStatus::fromStatus(STATUS_DEAD_OBJECT);
+    }
+    return ScopedAStatus::fromServiceSpecificErrorWithMessage(IHealth::STATUS_UNKNOWN,
+                                                              ret.description().c_str());
+}
+
+ScopedAStatus ReturnResultToStatus(const Return<Result>& return_result) {
+    return ReturnAndResultToStatus(return_result, return_result.isOk()
+                                                          ? static_cast<Result>(return_result)
+                                                          : Result::UNKNOWN);
+}
+
+}  // namespace
+
+HealthShim::HealthShim(const sp<HidlHealth>& service) : service_(service) {}
+
+ScopedAStatus HealthShim::registerCallback(
+        const std::shared_ptr<IHealthInfoCallback>& in_callback) {
+    sp<HidlHealthInfoCallback> shim(new HealthInfoCallbackShim(in_callback));
+    callback_map_.emplace(in_callback, shim);
+    return ReturnResultToStatus(service_->registerCallback(shim));
+}
+
+ScopedAStatus HealthShim::unregisterCallback(
+        const std::shared_ptr<IHealthInfoCallback>& in_callback) {
+    auto it = callback_map_.find(in_callback);
+    if (it == callback_map_.end()) {
+        return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    sp<HidlHealthInfoCallback> shim = it->second;
+    callback_map_.erase(it);
+    return ReturnResultToStatus(service_->unregisterCallback(shim));
+}
+
+ScopedAStatus HealthShim::update() {
+    return ReturnResultToStatus(service_->update());
+}
+
+ScopedAStatus HealthShim::getChargeCounterUah(int32_t* out) {
+    Result out_result = Result::UNKNOWN;
+    auto ret = service_->getChargeCounter([out, &out_result](auto result, auto value) {
+        out_result = result;
+        if (out_result != Result::SUCCESS) return;
+        *out = value;
+    });
+    return ReturnAndResultToStatus(ret, out_result);
+}
+
+ScopedAStatus HealthShim::getCurrentNowMicroamps(int32_t* out) {
+    Result out_result = Result::UNKNOWN;
+    auto ret = service_->getCurrentNow([out, &out_result](auto result, auto value) {
+        out_result = result;
+        if (out_result != Result::SUCCESS) return;
+        *out = value;
+    });
+    return ReturnAndResultToStatus(ret, out_result);
+}
+
+ScopedAStatus HealthShim::getCurrentAverageMicroamps(int32_t* out) {
+    Result out_result = Result::UNKNOWN;
+    auto ret = service_->getCurrentAverage([out, &out_result](auto result, auto value) {
+        out_result = result;
+        if (out_result != Result::SUCCESS) return;
+        *out = value;
+    });
+    return ReturnAndResultToStatus(ret, out_result);
+}
+
+ScopedAStatus HealthShim::getCapacity(int32_t* out) {
+    Result out_result = Result::UNKNOWN;
+    auto ret = service_->getCapacity([out, &out_result](auto result, auto value) {
+        out_result = result;
+        if (out_result != Result::SUCCESS) return;
+        *out = value;
+    });
+    return ReturnAndResultToStatus(ret, out_result);
+}
+
+ScopedAStatus HealthShim::getEnergyCounterNwh(int64_t* out) {
+    Result out_result = Result::UNKNOWN;
+    auto ret = service_->getEnergyCounter([out, &out_result](auto result, auto value) {
+        out_result = result;
+        if (out_result != Result::SUCCESS) return;
+        *out = value;
+    });
+    return ReturnAndResultToStatus(ret, out_result);
+}
+
+ScopedAStatus HealthShim::getChargeStatus(BatteryStatus* out) {
+    Result out_result = Result::UNKNOWN;
+    auto ret = service_->getChargeStatus([out, &out_result](auto result, auto value) {
+        out_result = result;
+        if (out_result != Result::SUCCESS) return;
+        *out = static_cast<BatteryStatus>(value);
+    });
+    return ReturnAndResultToStatus(ret, out_result);
+}
+
+ScopedAStatus HealthShim::getStorageInfo(std::vector<StorageInfo>* out) {
+    Result out_result = Result::UNKNOWN;
+    auto ret = service_->getStorageInfo([out, &out_result](auto result, const auto& value) {
+        out_result = result;
+        if (out_result != Result::SUCCESS) return;
+        out->clear();
+        out->reserve(value.size());
+        for (const auto& hidl_info : value) {
+            auto& aidl_info = out->emplace_back();
+            // translate() should always return true.
+            CHECK(translate(hidl_info, &aidl_info));
+        }
+    });
+    return ReturnAndResultToStatus(ret, out_result);
+}
+
+ScopedAStatus HealthShim::getDiskStats(std::vector<DiskStats>* out) {
+    Result out_result = Result::UNKNOWN;
+    auto ret = service_->getDiskStats([out, &out_result](auto result, const auto& value) {
+        out_result = result;
+        if (out_result != Result::SUCCESS) return;
+        out->clear();
+        out->reserve(value.size());
+        for (const auto& hidl_info : value) {
+            auto& aidl_info = out->emplace_back();
+            // translate() should always return true.
+            CHECK(translate(hidl_info, &aidl_info));
+        }
+    });
+    return ReturnAndResultToStatus(ret, out_result);
+}
+
+ScopedAStatus HealthShim::getHealthInfo(HealthInfo* out) {
+    Result out_result = Result::UNKNOWN;
+    auto ret = service_->getHealthInfo([out, &out_result](auto result, const auto& value) {
+        out_result = result;
+        if (out_result != Result::SUCCESS) return;
+        // translate() should always return true.
+        CHECK(translate(value, out));
+    });
+    return ReturnAndResultToStatus(ret, out_result);
+}
+
+}  // namespace aidl::android::hardware::health
diff --git a/health/utils/libhealthshim/test.cpp b/health/utils/libhealthshim/test.cpp
new file mode 100644
index 0000000..d1dfb8b
--- /dev/null
+++ b/health/utils/libhealthshim/test.cpp
@@ -0,0 +1,163 @@
+/*
+ * 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 <health-shim/shim.h>
+
+#include <android/hardware/health/translate-ndk.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+using HidlHealth = android::hardware::health::V2_0::IHealth;
+using HidlHealthInfoCallback = android::hardware::health::V2_0::IHealthInfoCallback;
+using HidlStorageInfo = android::hardware::health::V2_0::StorageInfo;
+using HidlDiskStats = android::hardware::health::V2_0::DiskStats;
+using HidlHealthInfo = android::hardware::health::V2_0::HealthInfo;
+using HidlBatteryStatus = android::hardware::health::V1_0::BatteryStatus;
+using android::sp;
+using android::hardware::Return;
+using android::hardware::Void;
+using android::hardware::health::V2_0::Result;
+using ndk::SharedRefBase;
+using testing::Invoke;
+using testing::NiceMock;
+
+namespace aidl::android::hardware::health {
+MATCHER(IsOk, "") {
+    *result_listener << "status is " << arg.getDescription();
+    return arg.isOk();
+}
+
+MATCHER_P(ExceptionIs, exception_code, "") {
+    *result_listener << "status is " << arg.getDescription();
+    return arg.getExceptionCode() == exception_code;
+}
+
+class MockHidlHealth : public HidlHealth {
+  public:
+    MOCK_METHOD(Return<Result>, registerCallback, (const sp<HidlHealthInfoCallback>& callback),
+                (override));
+    MOCK_METHOD(Return<Result>, unregisterCallback, (const sp<HidlHealthInfoCallback>& callback),
+                (override));
+    MOCK_METHOD(Return<Result>, update, (), (override));
+    MOCK_METHOD(Return<void>, getChargeCounter, (getChargeCounter_cb _hidl_cb), (override));
+    MOCK_METHOD(Return<void>, getCurrentNow, (getCurrentNow_cb _hidl_cb), (override));
+    MOCK_METHOD(Return<void>, getCurrentAverage, (getCurrentAverage_cb _hidl_cb), (override));
+    MOCK_METHOD(Return<void>, getCapacity, (getCapacity_cb _hidl_cb), (override));
+    MOCK_METHOD(Return<void>, getEnergyCounter, (getEnergyCounter_cb _hidl_cb), (override));
+    MOCK_METHOD(Return<void>, getChargeStatus, (getChargeStatus_cb _hidl_cb), (override));
+    MOCK_METHOD(Return<void>, getStorageInfo, (getStorageInfo_cb _hidl_cb), (override));
+    MOCK_METHOD(Return<void>, getDiskStats, (getDiskStats_cb _hidl_cb), (override));
+    MOCK_METHOD(Return<void>, getHealthInfo, (getHealthInfo_cb _hidl_cb), (override));
+};
+
+class HealthShimTest : public ::testing::Test {
+  public:
+    void SetUp() override {
+        hidl = new NiceMock<MockHidlHealth>();
+        shim = SharedRefBase::make<HealthShim>(hidl);
+    }
+    sp<MockHidlHealth> hidl;
+    std::shared_ptr<IHealth> shim;
+};
+
+#define ADD_TEST(name, aidl_name, AidlValueType, hidl_value, not_supported_hidl_value) \
+    TEST_F(HealthShimTest, name) {                                                     \
+        ON_CALL(*hidl, name).WillByDefault(Invoke([](auto cb) {                        \
+            cb(Result::SUCCESS, hidl_value);                                           \
+            return Void();                                                             \
+        }));                                                                           \
+        AidlValueType value;                                                           \
+        ASSERT_THAT(shim->aidl_name(&value), IsOk());                                  \
+        ASSERT_EQ(value, static_cast<AidlValueType>(hidl_value));                      \
+    }                                                                                  \
+                                                                                       \
+    TEST_F(HealthShimTest, name##Unsupported) {                                        \
+        ON_CALL(*hidl, name).WillByDefault(Invoke([](auto cb) {                        \
+            cb(Result::NOT_SUPPORTED, not_supported_hidl_value);                       \
+            return Void();                                                             \
+        }));                                                                           \
+        AidlValueType value;                                                           \
+        ASSERT_THAT(shim->aidl_name(&value), ExceptionIs(EX_UNSUPPORTED_OPERATION));   \
+    }
+
+ADD_TEST(getChargeCounter, getChargeCounterUah, int32_t, 0xFEEDBEEF, 0)
+ADD_TEST(getCurrentNow, getCurrentNowMicroamps, int32_t, 0xC0FFEE, 0)
+ADD_TEST(getCurrentAverage, getCurrentAverageMicroamps, int32_t, 0xA2D401D, 0)
+ADD_TEST(getCapacity, getCapacity, int32_t, 77, 0)
+ADD_TEST(getEnergyCounter, getEnergyCounterNwh, int64_t, 0x1234567887654321, 0)
+ADD_TEST(getChargeStatus, getChargeStatus, BatteryStatus, HidlBatteryStatus::CHARGING,
+         HidlBatteryStatus::UNKNOWN)
+
+#undef ADD_TEST
+
+template <typename AidlValueType, typename HidlValueType>
+bool Translate(const HidlValueType& hidl_value, AidlValueType* aidl_value) {
+    return ::android::h2a::translate(hidl_value, aidl_value);
+}
+
+template <typename AidlValueType, typename HidlValueType>
+bool Translate(const std::vector<HidlValueType>& hidl_vec, std::vector<AidlValueType>* aidl_vec) {
+    aidl_vec->clear();
+    aidl_vec->reserve(hidl_vec.size());
+    for (const auto& hidl_value : hidl_vec) {
+        auto& aidl_value = aidl_vec->emplace_back();
+        if (!Translate(hidl_value, &aidl_value)) return false;
+    }
+    return true;
+}
+
+#define ADD_INFO_TEST(name, AidlValueType, hidl_value)                               \
+    TEST_F(HealthShimTest, name) {                                                   \
+        AidlValueType expected_aidl_value;                                           \
+        ASSERT_TRUE(Translate(hidl_value, &expected_aidl_value));                    \
+        ON_CALL(*hidl, name).WillByDefault(Invoke([&](auto cb) {                     \
+            cb(Result::SUCCESS, hidl_value);                                         \
+            return Void();                                                           \
+        }));                                                                         \
+        AidlValueType aidl_value;                                                    \
+        ASSERT_THAT(shim->name(&aidl_value), IsOk());                                \
+        ASSERT_EQ(aidl_value, expected_aidl_value);                                  \
+    }                                                                                \
+                                                                                     \
+    TEST_F(HealthShimTest, name##Unsupported) {                                      \
+        ON_CALL(*hidl, name).WillByDefault(Invoke([](auto cb) {                      \
+            cb(Result::NOT_SUPPORTED, {});                                           \
+            return Void();                                                           \
+        }));                                                                         \
+        AidlValueType aidl_value;                                                    \
+        ASSERT_THAT(shim->name(&aidl_value), ExceptionIs(EX_UNSUPPORTED_OPERATION)); \
+    }
+
+ADD_INFO_TEST(getStorageInfo, std::vector<StorageInfo>,
+              (std::vector<HidlStorageInfo>{{
+                      .lifetimeA = 15,
+                      .lifetimeB = 18,
+              }}))
+
+ADD_INFO_TEST(getDiskStats, std::vector<DiskStats>,
+              (std::vector<HidlDiskStats>{{
+                      .reads = 100,
+                      .writes = 200,
+              }}))
+
+ADD_INFO_TEST(getHealthInfo, HealthInfo,
+              (HidlHealthInfo{
+                      .batteryCurrentAverage = 999,
+              }))
+
+#undef ADD_INFO_TEST
+
+}  // namespace aidl::android::hardware::health
diff --git a/identity/aidl/default/service.cpp b/identity/aidl/default/service.cpp
index c290c08..78f4fbc 100644
--- a/identity/aidl/default/service.cpp
+++ b/identity/aidl/default/service.cpp
@@ -43,7 +43,7 @@
 
     const std::string instance = std::string() + IdentityCredentialStore::descriptor + "/default";
     binder_status_t status = AServiceManager_addService(store->asBinder().get(), instance.c_str());
-    CHECK(status == STATUS_OK);
+    CHECK_EQ(status, STATUS_OK);
 
     ABinderProcess_joinThreadPool();
     return EXIT_FAILURE;  // should not reach
diff --git a/keymaster/4.0/vts/functional/Android.bp b/keymaster/4.0/vts/functional/Android.bp
index a7be660..8e5a0ff 100644
--- a/keymaster/4.0/vts/functional/Android.bp
+++ b/keymaster/4.0/vts/functional/Android.bp
@@ -41,6 +41,10 @@
         "general-tests",
         "vts",
     ],
+    sanitize: {
+        cfi: false,
+    },
+
 }
 
 cc_test_library {
diff --git a/light/aidl/default/main.cpp b/light/aidl/default/main.cpp
index a860bf4..54e1316 100644
--- a/light/aidl/default/main.cpp
+++ b/light/aidl/default/main.cpp
@@ -28,7 +28,7 @@
 
     const std::string instance = std::string() + Lights::descriptor + "/default";
     binder_status_t status = AServiceManager_addService(lights->asBinder().get(), instance.c_str());
-    CHECK(status == STATUS_OK);
+    CHECK_EQ(status, STATUS_OK);
 
     ABinderProcess_joinThreadPool();
     return EXIT_FAILURE;  // should not reached
diff --git a/memtrack/aidl/default/main.cpp b/memtrack/aidl/default/main.cpp
index d063d2a..5cf5f94 100644
--- a/memtrack/aidl/default/main.cpp
+++ b/memtrack/aidl/default/main.cpp
@@ -29,7 +29,7 @@
     const std::string instance = std::string() + Memtrack::descriptor + "/default";
     binder_status_t status =
             AServiceManager_addService(memtrack->asBinder().get(), instance.c_str());
-    CHECK(status == STATUS_OK);
+    CHECK_EQ(status, STATUS_OK);
 
     ABinderProcess_joinThreadPool();
     return EXIT_FAILURE;  // Unreachable
diff --git a/neuralnetworks/aidl/android/hardware/neuralnetworks/OperationType.aidl b/neuralnetworks/aidl/android/hardware/neuralnetworks/OperationType.aidl
index aebe8d9..0ad254d 100644
--- a/neuralnetworks/aidl/android/hardware/neuralnetworks/OperationType.aidl
+++ b/neuralnetworks/aidl/android/hardware/neuralnetworks/OperationType.aidl
@@ -5385,7 +5385,7 @@
      *      must be in the range [0, n).
      *
      * Outputs:
-     * * 0: The reversed tensor.
+     * * 0: The reversed tensor of the same shape as the input tensor.
      *      For {@link OperandType::TENSOR_QUANT8_ASYMM} and
      *      {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} tensors,
      *      the scales and zeroPoint must be the same as input0.
diff --git a/neuralnetworks/aidl/vts/functional/Android.bp b/neuralnetworks/aidl/vts/functional/Android.bp
index a102fe0..1ed15b8 100644
--- a/neuralnetworks/aidl/vts/functional/Android.bp
+++ b/neuralnetworks/aidl/vts/functional/Android.bp
@@ -60,6 +60,7 @@
         "libsync",
     ],
     whole_static_libs: [
+        "neuralnetworks_generated_AIDL_V3_example",
         "neuralnetworks_generated_AIDL_V2_example",
         "neuralnetworks_generated_V1_0_example",
         "neuralnetworks_generated_V1_1_example",
diff --git a/oemlock/aidl/default/service.cpp b/oemlock/aidl/default/service.cpp
index af828a0..9fa7d63 100644
--- a/oemlock/aidl/default/service.cpp
+++ b/oemlock/aidl/default/service.cpp
@@ -28,7 +28,7 @@
 
     const std::string instance = std::string() + OemLock::descriptor + "/default";
     binder_status_t status = AServiceManager_addService(oemlock->asBinder().get(), instance.c_str());
-    CHECK(status == STATUS_OK);
+    CHECK_EQ(status, STATUS_OK);
 
     ABinderProcess_joinThreadPool();
     return -1; // Should never be reached
diff --git a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/Mode.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/Mode.aidl
index 8920c01..ba444a7 100644
--- a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/Mode.aidl
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/Mode.aidl
@@ -49,4 +49,5 @@
   CAMERA_STREAMING_LOW = 12,
   CAMERA_STREAMING_MID = 13,
   CAMERA_STREAMING_HIGH = 14,
+  GAME_LOADING = 15,
 }
diff --git a/power/aidl/android/hardware/power/Mode.aidl b/power/aidl/android/hardware/power/Mode.aidl
index ae113e3..2ebace1 100644
--- a/power/aidl/android/hardware/power/Mode.aidl
+++ b/power/aidl/android/hardware/power/Mode.aidl
@@ -162,4 +162,9 @@
      * This hint indicates that camera high resolution stream is being started.
      */
     CAMERA_STREAMING_HIGH,
+
+    /**
+     * This mode indicates that the user is waiting for loading in a game.
+     */
+    GAME_LOADING,
 }
diff --git a/power/aidl/default/Android.bp b/power/aidl/default/Android.bp
index 9acb9e0..223b9d5 100644
--- a/power/aidl/default/Android.bp
+++ b/power/aidl/default/Android.bp
@@ -30,7 +30,7 @@
     shared_libs: [
         "libbase",
         "libbinder_ndk",
-        "android.hardware.power-V2-ndk",
+        "android.hardware.power-V3-ndk",
     ],
     srcs: [
         "main.cpp",
diff --git a/power/aidl/default/main.cpp b/power/aidl/default/main.cpp
index 964bd96..306b91b 100644
--- a/power/aidl/default/main.cpp
+++ b/power/aidl/default/main.cpp
@@ -28,7 +28,7 @@
 
     const std::string instance = std::string() + Power::descriptor + "/default";
     binder_status_t status = AServiceManager_addService(vib->asBinder().get(), instance.c_str());
-    CHECK(status == STATUS_OK);
+    CHECK_EQ(status, STATUS_OK);
 
     ABinderProcess_joinThreadPool();
     return EXIT_FAILURE;  // should not reach
diff --git a/power/aidl/default/power-default.xml b/power/aidl/default/power-default.xml
index 9f56deb..927ba22 100644
--- a/power/aidl/default/power-default.xml
+++ b/power/aidl/default/power-default.xml
@@ -1,7 +1,7 @@
 <manifest version="1.0" type="device">
     <hal format="aidl">
         <name>android.hardware.power</name>
-        <version>2</version>
+        <version>3</version>
         <fqname>IPower/default</fqname>
     </hal>
 </manifest>
diff --git a/power/stats/aidl/default/main.cpp b/power/stats/aidl/default/main.cpp
index 2fe3d2e..9e78247 100644
--- a/power/stats/aidl/default/main.cpp
+++ b/power/stats/aidl/default/main.cpp
@@ -73,7 +73,7 @@
 
     const std::string instance = std::string() + PowerStats::descriptor + "/default";
     binder_status_t status = AServiceManager_addService(p->asBinder().get(), instance.c_str());
-    CHECK(status == STATUS_OK);
+    CHECK_EQ(status, STATUS_OK);
 
     ABinderProcess_joinThreadPool();
     return EXIT_FAILURE;  // should not reach
diff --git a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
index c167a6d..9f530b3 100644
--- a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
@@ -645,6 +645,10 @@
     if (!deviceSupportsFeature(FEATURE_VOICE_CALL)) {
         ALOGI("Skipping emergencyDial because voice call is not supported in device");
         return;
+    } else if (!deviceSupportsFeature(FEATURE_TELEPHONY_GSM) &&
+               !deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
+        ALOGI("Skipping emergencyDial because gsm/cdma radio is not supported in device");
+        return;
     } else {
         ALOGI("Running emergencyDial because voice call is supported in device");
     }
@@ -699,6 +703,10 @@
     if (!deviceSupportsFeature(FEATURE_VOICE_CALL)) {
         ALOGI("Skipping emergencyDial because voice call is not supported in device");
         return;
+    } else if (!deviceSupportsFeature(FEATURE_TELEPHONY_GSM) &&
+               !deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
+        ALOGI("Skipping emergencyDial because gsm/cdma radio is not supported in device");
+        return;
     } else {
         ALOGI("Running emergencyDial because voice call is supported in device");
     }
@@ -752,6 +760,10 @@
     if (!deviceSupportsFeature(FEATURE_VOICE_CALL)) {
         ALOGI("Skipping emergencyDial because voice call is not supported in device");
         return;
+    } else if (!deviceSupportsFeature(FEATURE_TELEPHONY_GSM) &&
+               !deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
+        ALOGI("Skipping emergencyDial because gsm/cdma radio is not supported in device");
+        return;
     } else {
         ALOGI("Running emergencyDial because voice call is supported in device");
     }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ActivityStatsInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ActivityStatsInfo.aidl
index 2da0167..93940fd 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ActivityStatsInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ActivityStatsInfo.aidl
@@ -36,6 +36,5 @@
 parcelable ActivityStatsInfo {
   int sleepModeTimeMs;
   int idleModeTimeMs;
-  int[] txmModetimeMs;
-  int rxModeTimeMs;
+  android.hardware.radio.modem.ActivityStatsTechSpecificInfo[] techSpecificInfo;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ActivityStatsTechSpecificInfo.aidl
similarity index 75%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
copy to radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ActivityStatsTechSpecificInfo.aidl
index a522d53..798ec36 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ActivityStatsTechSpecificInfo.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,11 +31,16 @@
 // 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.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum BlendMode {
-  INVALID = 0,
-  NONE = 1,
-  PREMULTIPLIED = 2,
-  COVERAGE = 3,
+package android.hardware.radio.modem;
+@VintfStability
+parcelable ActivityStatsTechSpecificInfo {
+  android.hardware.radio.AccessNetwork rat;
+  int frequencyRange;
+  int[] txmModetimeMs;
+  int rxModeTimeMs;
+  const int FREQUENCY_RANGE_UNKNOWN = 0;
+  const int FREQUENCY_RANGE_LOW = 1;
+  const int FREQUENCY_RANGE_MID = 2;
+  const int FREQUENCY_RANGE_HIGH = 3;
+  const int FREQUENCY_RANGE_MMWAVE = 4;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetwork.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetwork.aidl
index 16433be..c618791 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetwork.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetwork.aidl
@@ -68,4 +68,6 @@
   oneway void startNetworkScan(in int serial, in android.hardware.radio.network.NetworkScanRequest request);
   oneway void stopNetworkScan(in int serial);
   oneway void supplyNetworkDepersonalization(in int serial, in String netPin);
+  oneway void setUsageSetting(in int serial, in android.hardware.radio.network.UsageSetting usageSetting);
+  oneway void getUsageSetting(in int serial);
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkResponse.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkResponse.aidl
index ff95396..8cf4c31 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkResponse.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkResponse.aidl
@@ -67,4 +67,6 @@
   oneway void startNetworkScanResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void stopNetworkScanResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void supplyNetworkDepersonalizationResponse(in android.hardware.radio.RadioResponseInfo info, in int remainingRetries);
+  oneway void setUsageSettingResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void getUsageSettingResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.network.UsageSetting usageSetting);
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/UsageSetting.aidl
similarity index 87%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
copy to radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/UsageSetting.aidl
index cfafc50..7fdf831 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/UsageSetting.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,8 +31,9 @@
 // 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.graphics.composer3;
+package android.hardware.radio.network;
 @Backing(type="int") @VintfStability
-enum LayerRequest {
-  CLEAR_CLIENT_TARGET = 1,
+enum UsageSetting {
+  VOICE_CENTRIC = 1,
+  DATA_CENTRIC = 2,
 }
diff --git a/radio/aidl/android/hardware/radio/modem/ActivityStatsInfo.aidl b/radio/aidl/android/hardware/radio/modem/ActivityStatsInfo.aidl
index 764a86d..d0aa695 100644
--- a/radio/aidl/android/hardware/radio/modem/ActivityStatsInfo.aidl
+++ b/radio/aidl/android/hardware/radio/modem/ActivityStatsInfo.aidl
@@ -16,6 +16,8 @@
 
 package android.hardware.radio.modem;
 
+import android.hardware.radio.modem.ActivityStatsTechSpecificInfo;
+
 @VintfStability
 parcelable ActivityStatsInfo {
     /**
@@ -28,17 +30,10 @@
      */
     int idleModeTimeMs;
     /**
-     * Each index represent total time (in ms) during which the transmitter is active/awake for a
-     * particular power range as shown below.
-     * index 0 = tx_power < 0dBm
-     * index 1 = 0dBm < tx_power < 5dBm
-     * index 2 = 5dBm < tx_power < 15dBm
-     * index 3 = 15dBm < tx_power < 20dBm
-     * index 4 = tx_power > 20dBm
+     * Technology specific activity stats info.
+     * List of the activity stats for each RATs (2G, 3G, 4G and 5G) and frequency ranges (HIGH for
+     * sub6 and MMWAVE) in case of 5G. In case implementation doesn't have RAT specific activity
+     * stats then send only one activity stats info with RAT unknown.
      */
-    int[] txmModetimeMs;
-    /**
-     * Total time (in ms) for which receiver is active/awake and the transmitter is inactive
-     */
-    int rxModeTimeMs;
+    ActivityStatsTechSpecificInfo[] techSpecificInfo;
 }
diff --git a/radio/aidl/android/hardware/radio/modem/ActivityStatsTechSpecificInfo.aidl b/radio/aidl/android/hardware/radio/modem/ActivityStatsTechSpecificInfo.aidl
new file mode 100644
index 0000000..fb14223
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/modem/ActivityStatsTechSpecificInfo.aidl
@@ -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.
+ */
+
+package android.hardware.radio.modem;
+
+import android.hardware.radio.AccessNetwork;
+
+@VintfStability
+parcelable ActivityStatsTechSpecificInfo {
+    /** Indicates the frequency range is unknown. */
+    const int FREQUENCY_RANGE_UNKNOWN = 0;
+    /** Indicates the frequency range is below 1GHz. */
+    const int FREQUENCY_RANGE_LOW = 1;
+    /** Indicates the frequency range is between 1GHz and 3GHz. */
+    const int FREQUENCY_RANGE_MID = 2;
+    /** Indicates the frequency range is between 3GHz and 6GHz. */
+    const int FREQUENCY_RANGE_HIGH = 3;
+    /** Indicates the frequency range is above 6GHz (millimeter wave frequency). */
+    const int FREQUENCY_RANGE_MMWAVE = 4;
+    /**
+     * Radio access technology. Set UNKNOWN if the Activity statistics
+     * is RAT independent.
+     */
+    AccessNetwork rat;
+    /**
+     * Frequency range. Values are FREQUENCY_RANGE_
+     * Set FREQUENCY_RANGE_UNKNOWN if the Activity statistics when frequency range
+     * is not applicable.
+     */
+    int frequencyRange;
+    /**
+     * Each index represent total time (in ms) during which the transmitter is active/awake for a
+     * particular power range as shown below.
+     * index 0 = tx_power <= 0dBm
+     * index 1 = 0dBm < tx_power <= 5dBm
+     * index 2 = 5dBm < tx_power <= 15dBm
+     * index 3 = 15dBm < tx_power <= 20dBm
+     * index 4 = tx_power > 20dBm
+     */
+    int[] txmModetimeMs;
+    /**
+     * Total time (in ms) for which receiver is active/awake and the transmitter is inactive
+     */
+    int rxModeTimeMs;
+}
diff --git a/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl b/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl
index 1081a75..aaf432a 100644
--- a/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl
+++ b/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl
@@ -27,6 +27,7 @@
 import android.hardware.radio.network.RadioAccessSpecifier;
 import android.hardware.radio.network.RadioBandMode;
 import android.hardware.radio.network.SignalThresholdInfo;
+import android.hardware.radio.network.UsageSetting;
 
 /**
  * This interface is used by telephony and telecom to talk to cellular radio for network APIs.
@@ -416,4 +417,25 @@
      * Response function is IRadioNetworkResponse.supplyNetworkDepersonalizationResponse()
      */
     void supplyNetworkDepersonalization(in int serial, in String netPin);
+
+    /**
+     * Set the UE usage setting for data/voice centric usage.
+     *
+     * <p>Sets the usage setting in accordance with 3gpp 24.301 sec 4.3 and 3gpp 24.501 sec 4.3.
+     * <p>This value must be independently preserved for each SIM; (setting the value is not a
+     * "global" override).
+     *
+     * @param serial Serial number of request.
+     * @param usageSetting the usage setting for the current SIM.
+     */
+    oneway void setUsageSetting(in int serial, in UsageSetting usageSetting);
+
+    /**
+     * Get the UE usage setting for data/voice centric usage.
+     *
+     * <p>Gets the usage setting in accordance with 3gpp 24.301 sec 4.3 and 3gpp 24.501 sec 4.3.
+     *
+     * @param serial Serial number of request.
+     */
+    oneway void getUsageSetting(in int serial);
 }
diff --git a/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl b/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl
index 429b5a8..30f4221 100644
--- a/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl
+++ b/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl
@@ -31,6 +31,7 @@
 import android.hardware.radio.network.RadioBandMode;
 import android.hardware.radio.network.RegStateResult;
 import android.hardware.radio.network.SignalStrength;
+import android.hardware.radio.network.UsageSetting;
 
 /**
  * Interface declaring response functions to solicited radio requests for network APIs.
@@ -549,4 +550,30 @@
      *   RadioError:SIM_ABSENT
      */
     void supplyNetworkDepersonalizationResponse(in RadioResponseInfo info, in int remainingRetries);
+
+    /**
+     * @param info Response info struct containing response type, serial no. and error.
+     *
+     * Valid errors returned:
+     *   RadioError:NONE
+     *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INVALID_STATE
+     *   RadioError:INVALID_ARGUMENTS
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:SIM_ABSENT
+     */
+    oneway void setUsageSettingResponse(in RadioResponseInfo info);
+
+    /**
+     * @param info Response info struct containing response type, serial no. and error.
+     * @param usageSetting the usage setting for the current SIM.
+     *
+     * Valid errors returned:
+     *   RadioError:NONE
+     *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INVALID_STATE
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:SIM_ABSENT
+     */
+    oneway void getUsageSettingResponse(in RadioResponseInfo info, in UsageSetting usageSetting);
 }
diff --git a/radio/aidl/android/hardware/radio/network/UsageSetting.aidl b/radio/aidl/android/hardware/radio/network/UsageSetting.aidl
new file mode 100644
index 0000000..ba8fe93
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/network/UsageSetting.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.
+ */
+
+package android.hardware.radio.network;
+
+/**
+ * Cellular usage setting with values according to 3gpp 24.301 sec 4.3 and 3gpp 24.501 sec 4.3.
+ *
+ * <p>Also refer to "UE's usage setting" as defined in 3gpp 24.301 section 3.1 and 3gpp 23.221
+ * Annex A.
+ */
+@VintfStability
+@Backing(type="int")
+enum UsageSetting {
+    /**
+     * UE operates in voice-centric mode. Generally speaking, in this mode of operation, the UE
+     * will not remain camped on a cell or attached to a network unless that cell/network provides
+     * voice service.
+     */
+    VOICE_CENTRIC = 1,
+
+    /**
+     * UE operates in data-centric mode. Generally speaking, in this mode of operation, the UE
+     * will not reselect away from a cell/network that only provides data services.
+     */
+    DATA_CENTRIC = 2,
+}
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioNetwork.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioNetwork.h
index c776fd1..09ae240 100644
--- a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioNetwork.h
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioNetwork.h
@@ -88,6 +88,10 @@
     ::ndk::ScopedAStatus stopNetworkScan(int32_t serial) override;
     ::ndk::ScopedAStatus supplyNetworkDepersonalization(int32_t serial,
                                                         const std::string& netPin) override;
+    ::ndk::ScopedAStatus setUsageSetting(
+            int32_t serial,
+            ::aidl::android::hardware::radio::network::UsageSetting usageSetting) override;
+    ::ndk::ScopedAStatus getUsageSetting(int32_t serial) override;
 
   public:
     using RadioCompatBase::RadioCompatBase;
diff --git a/radio/aidl/compat/libradiocompat/modem/structs.cpp b/radio/aidl/compat/libradiocompat/modem/structs.cpp
index c1cd64c..53d5753 100644
--- a/radio/aidl/compat/libradiocompat/modem/structs.cpp
+++ b/radio/aidl/compat/libradiocompat/modem/structs.cpp
@@ -24,6 +24,7 @@
 
 namespace android::hardware::radio::compat {
 
+using ::aidl::android::hardware::radio::AccessNetwork;
 using ::aidl::android::hardware::radio::RadioAccessFamily;
 using ::aidl::android::hardware::radio::RadioTechnology;
 namespace aidl = ::aidl::android::hardware::radio::modem;
@@ -82,11 +83,18 @@
 }
 
 aidl::ActivityStatsInfo toAidl(const V1_0::ActivityStatsInfo& info) {
+    const aidl::ActivityStatsTechSpecificInfo techSpecificInfo = {
+            .rat = AccessNetwork(AccessNetwork::UNKNOWN),
+            .frequencyRange = static_cast<int32_t>(
+                    aidl::ActivityStatsTechSpecificInfo::FREQUENCY_RANGE_UNKNOWN),
+            .txmModetimeMs = toAidl(info.txmModetimeMs),
+            .rxModeTimeMs = static_cast<int32_t>(info.rxModeTimeMs),
+    };
+
     return {
             .sleepModeTimeMs = static_cast<int32_t>(info.sleepModeTimeMs),
             .idleModeTimeMs = static_cast<int32_t>(info.idleModeTimeMs),
-            .txmModetimeMs = toAidl(info.txmModetimeMs),
-            .rxModeTimeMs = static_cast<int32_t>(info.rxModeTimeMs),
+            .techSpecificInfo = {techSpecificInfo},
     };
 }
 
diff --git a/radio/aidl/compat/libradiocompat/modem/structs.h b/radio/aidl/compat/libradiocompat/modem/structs.h
index 3ac1edb..af714c7 100644
--- a/radio/aidl/compat/libradiocompat/modem/structs.h
+++ b/radio/aidl/compat/libradiocompat/modem/structs.h
@@ -16,6 +16,7 @@
 #pragma once
 
 #include <aidl/android/hardware/radio/modem/ActivityStatsInfo.h>
+#include <aidl/android/hardware/radio/modem/ActivityStatsTechSpecificInfo.h>
 #include <aidl/android/hardware/radio/modem/HardwareConfig.h>
 #include <aidl/android/hardware/radio/modem/HardwareConfigModem.h>
 #include <aidl/android/hardware/radio/modem/HardwareConfigSim.h>
diff --git a/radio/aidl/compat/libradiocompat/network/RadioNetwork.cpp b/radio/aidl/compat/libradiocompat/network/RadioNetwork.cpp
index af0bc46..5fa1cf5 100644
--- a/radio/aidl/compat/libradiocompat/network/RadioNetwork.cpp
+++ b/radio/aidl/compat/libradiocompat/network/RadioNetwork.cpp
@@ -278,4 +278,19 @@
     return ok();
 }
 
+// TODO(b/210498497): is there a cleaner way to send a response back to Android, even though these
+// methods must never be called?
+ScopedAStatus RadioNetwork::setUsageSetting(
+        int32_t ser, ::aidl::android::hardware::radio::network::UsageSetting) {
+    LOG_CALL << ser;
+    LOG(ERROR) << "setUsageSetting is unsupported by HIDL HALs";
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::getUsageSetting(int32_t ser) {
+    LOG_CALL << ser;
+    LOG(ERROR) << "getUsageSetting is unsupported by HIDL HALs";
+    return ok();
+}
+
 }  // namespace android::hardware::radio::compat
diff --git a/rebootescrow/aidl/default/service.cpp b/rebootescrow/aidl/default/service.cpp
index 8a8086b..dc06c71 100644
--- a/rebootescrow/aidl/default/service.cpp
+++ b/rebootescrow/aidl/default/service.cpp
@@ -34,7 +34,7 @@
     auto re = ndk::SharedRefBase::make<RebootEscrow>(rebootEscrowDevicePath);
     const std::string instance = std::string() + RebootEscrow::descriptor + "/default";
     binder_status_t status = AServiceManager_addService(re->asBinder().get(), instance.c_str());
-    CHECK(status == STATUS_OK);
+    CHECK_EQ(status, STATUS_OK);
 
     ABinderProcess_joinThreadPool();
     return EXIT_FAILURE;
diff --git a/security/keymint/aidl/Android.bp b/security/keymint/aidl/Android.bp
index 3cf6ff2..dcbe9c1 100644
--- a/security/keymint/aidl/Android.bp
+++ b/security/keymint/aidl/Android.bp
@@ -45,14 +45,14 @@
 cc_defaults {
     name: "keymint_use_latest_hal_aidl_ndk_static",
     static_libs: [
-        "android.hardware.security.keymint-V1-ndk",
+        "android.hardware.security.keymint-V2-ndk",
     ],
 }
 
 cc_defaults {
     name: "keymint_use_latest_hal_aidl_ndk_shared",
     shared_libs: [
-        "android.hardware.security.keymint-V1-ndk",
+        "android.hardware.security.keymint-V2-ndk",
     ],
 }
 
@@ -62,6 +62,6 @@
 rust_defaults {
     name: "keymint_use_latest_hal_aidl_rust",
     rustlibs: [
-        "android.hardware.security.keymint-V1-rust",
+        "android.hardware.security.keymint-V2-rust",
     ],
 }
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/EcCurve.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/EcCurve.aidl
index 6b4a9ae..ffc7efe 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/EcCurve.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/EcCurve.aidl
@@ -39,4 +39,5 @@
   P_256 = 1,
   P_384 = 2,
   P_521 = 3,
+  CURVE_25519 = 4,
 }
diff --git a/security/keymint/aidl/android/hardware/security/keymint/EcCurve.aidl b/security/keymint/aidl/android/hardware/security/keymint/EcCurve.aidl
index 5b1c10c..e9f81d8 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/EcCurve.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/EcCurve.aidl
@@ -27,4 +27,5 @@
     P_256 = 1,
     P_384 = 2,
     P_521 = 3,
+    CURVE_25519 = 4,
 }
diff --git a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
index cd8cfc5..9846ee9 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
@@ -93,6 +93,11 @@
  *        P-521.  STRONGBOX IKeyMintDevices must support NIST curve P-256.
  *      - TRUSTED_ENVIRONMENT IKeyMintDevices must support SHA1, SHA-2 224, SHA-2 256, SHA-2
  *        384 and SHA-2 512 digest modes.  STRONGBOX IKeyMintDevices must support SHA-2 256.
+ *      - TRUSTED_ENVRIONMENT IKeyMintDevices must support curve 25519 for Purpose::SIGN (Ed25519,
+ *        as specified in RFC 8032), Purpose::ATTEST_KEY (Ed25519) or for KeyPurpose::AGREE_KEY
+ *        (X25519, as specified in RFC 7748).  However, a key must have exactly one of these
+ *        purpose values; the same key cannot be used for multiple purposes.
+ *        STRONGBOX IKeyMintDevices do not support curve 25519.
  *
  * o   AES
  *
@@ -287,7 +292,7 @@
      *   except AGREE_KEY must be supported for RSA keys.
      *
      * o Tag::DIGEST specifies digest algorithms that may be used with the new key.  TEE
-     *   IKeyMintDevice implementations must support all Digest values (see digest.aidl) for RSA
+     *   IKeyMintDevice implementations must support all Digest values (see Digest.aidl) for RSA
      *   keys.  StrongBox IKeyMintDevice implementations must support SHA_2_256.
      *
      * o Tag::PADDING specifies the padding modes that may be used with the new
@@ -298,13 +303,24 @@
      * == ECDSA Keys ==
      *
      * Tag::EC_CURVE must be provided to generate an ECDSA key.  If it is not provided, generateKey
-     * must return ErrorCode::UNSUPPORTED_KEY_SIZE. TEE IKeyMintDevice implementations must support
-     * all curves.  StrongBox implementations must support P_256.
-
+     * must return ErrorCode::UNSUPPORTED_KEY_SIZE or ErrorCode::UNSUPPORTED_EC_CURVE. TEE
+     * IKeyMintDevice implementations must support all required curves.  StrongBox implementations
+     * must support P_256 and no other curves.
+     *
      * Tag::CERTIFICATE_NOT_BEFORE and Tag::CERTIFICATE_NOT_AFTER must be provided to specify the
      * valid date range for the returned X.509 certificate holding the public key. If omitted,
      * generateKey must return ErrorCode::MISSING_NOT_BEFORE or ErrorCode::MISSING_NOT_AFTER.
      *
+     * Keys with EC_CURVE of EcCurve::CURVE_25519 must have exactly one purpose in the set
+     * {KeyPurpose::SIGN, KeyPurpose::ATTEST_KEY, KeyPurpose::AGREE_KEY}.  Key generation with more
+     * than one purpose should be rejected with ErrorCode::INCOMPATIBLE_PURPOSE.
+     * StrongBox implementation do not support CURVE_25519.
+     *
+     * Tag::DIGEST specifies digest algorithms that may be used with the new key.  TEE
+     * IKeyMintDevice implementations must support all Digest values (see Digest.aidl) for ECDSA
+     * keys; Ed25519 keys only support Digest::NONE. StrongBox IKeyMintDevice implementations must
+     * support SHA_2_256.
+     *
      * == AES Keys ==
      *
      * Only Tag::KEY_SIZE is required to generate an AES key.  If omitted, generateKey must return
diff --git a/security/keymint/aidl/android/hardware/security/keymint/KeyFormat.aidl b/security/keymint/aidl/android/hardware/security/keymint/KeyFormat.aidl
index da3d521..3faef38 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/KeyFormat.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/KeyFormat.aidl
@@ -25,8 +25,10 @@
 enum KeyFormat {
     /** X.509 certificate format, for public key export. */
     X509 = 0,
-    /** PCKS#8 format, asymmetric key pair import. */
+    /** PKCS#8 format, asymmetric key pair import. */
     PKCS8 = 1,
-    /** Raw bytes, for symmetric key import. */
+    /**
+     * Raw bytes, for symmetric key import, and for import of raw asymmetric keys for curve 25519.
+     */
     RAW = 3,
 }
diff --git a/security/keymint/aidl/android/hardware/security/keymint/KeyPurpose.aidl b/security/keymint/aidl/android/hardware/security/keymint/KeyPurpose.aidl
index e141e55..fd103ef 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/KeyPurpose.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/KeyPurpose.aidl
@@ -44,6 +44,10 @@
     AGREE_KEY = 6,
 
     /* Usable as an attestation signing key.  Keys with this purpose must not have any other
-     * purpose. */
+     * purpose; if they do, key generation/import must be rejected with
+     * ErrorCode::INCOMPATIBLE_PURPOSE. (Rationale: If key also included KeyPurpose::SIGN, then
+     * it could be used to sign arbitrary data, including any tbsCertificate, and so an
+     * attestation produced by the key would have no security properties.)
+     */
     ATTEST_KEY = 7,
 }
diff --git a/security/keymint/aidl/default/service.cpp b/security/keymint/aidl/default/service.cpp
index 8092e34..dc0c618 100644
--- a/security/keymint/aidl/default/service.cpp
+++ b/security/keymint/aidl/default/service.cpp
@@ -39,7 +39,7 @@
     LOG(INFO) << "adding keymint service instance: " << instanceName;
     binder_status_t status =
             AServiceManager_addService(ser->asBinder().get(), instanceName.c_str());
-    CHECK(status == STATUS_OK);
+    CHECK_EQ(status, STATUS_OK);
     return ser;
 }
 
diff --git a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
index 64550ef..0fdf48d 100644
--- a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
+++ b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
@@ -175,6 +175,24 @@
 }
 
 /*
+ * AttestKeyTest.RsaAttestKeyMultiPurposeFail
+ *
+ * This test attempts to create an RSA attestation key that also allows signing.
+ */
+TEST_P(AttestKeyTest, RsaAttestKeyMultiPurposeFail) {
+    vector<uint8_t> attest_key_blob;
+    vector<KeyCharacteristics> attest_key_characteristics;
+    vector<Certificate> attest_key_cert_chain;
+    ASSERT_EQ(ErrorCode::INCOMPATIBLE_PURPOSE,
+              GenerateKey(AuthorizationSetBuilder()
+                                  .RsaSigningKey(2048, 65537)
+                                  .AttestKey()
+                                  .SetDefaultValidity(),
+                          {} /* attestation signing key */, &attest_key_blob,
+                          &attest_key_characteristics, &attest_key_cert_chain));
+}
+
+/*
  * AttestKeyTest.RsaAttestedAttestKeys
  *
  * This test creates an RSA attestation key signed by factory keys, and varifies it can be
@@ -412,6 +430,24 @@
 }
 
 /*
+ * AttestKeyTest.EcAttestKeyMultiPurposeFail
+ *
+ * This test attempts to create an EC attestation key that also allows signing.
+ */
+TEST_P(AttestKeyTest, EcAttestKeyMultiPurposeFail) {
+    vector<uint8_t> attest_key_blob;
+    vector<KeyCharacteristics> attest_key_characteristics;
+    vector<Certificate> attest_key_cert_chain;
+    ASSERT_EQ(ErrorCode::INCOMPATIBLE_PURPOSE,
+              GenerateKey(AuthorizationSetBuilder()
+                                  .EcdsaSigningKey(EcCurve::P_256)
+                                  .AttestKey()
+                                  .SetDefaultValidity(),
+                          {} /* attestation signing key */, &attest_key_blob,
+                          &attest_key_characteristics, &attest_key_cert_chain));
+}
+
+/*
  * AttestKeyTest.AlternateAttestKeyChaining
  *
  * This test creates a chain of multiple attest keys, in the order Ec - RSA - Ec - RSA ....
@@ -583,6 +619,7 @@
                               attest_key, &attested_key_blob, &attested_key_characteristics,
                               &attested_key_cert_chain));
 
+        ASSERT_GT(attested_key_cert_chain.size(), 0);
         CheckedDeleteKey(&attested_key_blob);
 
         AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
@@ -612,6 +649,7 @@
                               attest_key, &attested_key_blob, &attested_key_characteristics,
                               &attested_key_cert_chain));
 
+        ASSERT_GT(attested_key_cert_chain.size(), 0);
         CheckedDeleteKey(&attested_key_blob);
         CheckedDeleteKey(&attest_key.keyBlob);
 
diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
index c99e1d0..3f33686 100644
--- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
@@ -3151,6 +3151,58 @@
     CheckedDeleteKey(&verification_key);
 }
 
+/*
+ * VerificationOperationsTest.HmacVerificationFailsForCorruptSignature
+ *
+ * Verifies HMAC signature verification should fails if message or signature is corrupted.
+ */
+TEST_P(VerificationOperationsTest, HmacVerificationFailsForCorruptSignature) {
+    string key_material = "HelloThisIsAKey";
+
+    vector<uint8_t> signing_key, verification_key;
+    vector<KeyCharacteristics> signing_key_chars, verification_key_chars;
+    EXPECT_EQ(ErrorCode::OK,
+              ImportKey(AuthorizationSetBuilder()
+                                .Authorization(TAG_NO_AUTH_REQUIRED)
+                                .Authorization(TAG_ALGORITHM, Algorithm::HMAC)
+                                .Authorization(TAG_PURPOSE, KeyPurpose::SIGN)
+                                .Digest(Digest::SHA_2_256)
+                                .Authorization(TAG_MIN_MAC_LENGTH, 160),
+                        KeyFormat::RAW, key_material, &signing_key, &signing_key_chars));
+    EXPECT_EQ(ErrorCode::OK,
+              ImportKey(AuthorizationSetBuilder()
+                                .Authorization(TAG_NO_AUTH_REQUIRED)
+                                .Authorization(TAG_ALGORITHM, Algorithm::HMAC)
+                                .Authorization(TAG_PURPOSE, KeyPurpose::VERIFY)
+                                .Digest(Digest::SHA_2_256)
+                                .Authorization(TAG_MIN_MAC_LENGTH, 160),
+                        KeyFormat::RAW, key_material, &verification_key, &verification_key_chars));
+
+    string message = "This is a message.";
+    string signature = SignMessage(
+            signing_key, message,
+            AuthorizationSetBuilder().Digest(Digest::SHA_2_256).Authorization(TAG_MAC_LENGTH, 160));
+
+    AuthorizationSet begin_out_params;
+    ASSERT_EQ(ErrorCode::OK,
+              Begin(KeyPurpose::VERIFY, verification_key,
+                    AuthorizationSetBuilder().Digest(Digest::SHA_2_256), &begin_out_params));
+
+    string corruptMessage = "This is b message.";  // Corrupted message
+    string output;
+    EXPECT_EQ(ErrorCode::VERIFICATION_FAILED, Finish(corruptMessage, signature, &output));
+
+    ASSERT_EQ(ErrorCode::OK,
+              Begin(KeyPurpose::VERIFY, verification_key,
+                    AuthorizationSetBuilder().Digest(Digest::SHA_2_256), &begin_out_params));
+
+    signature[0] += 1;  // Corrupt a signature
+    EXPECT_EQ(ErrorCode::VERIFICATION_FAILED, Finish(message, signature, &output));
+
+    CheckedDeleteKey(&signing_key);
+    CheckedDeleteKey(&verification_key);
+}
+
 INSTANTIATE_KEYMINT_AIDL_TEST(VerificationOperationsTest);
 
 typedef KeyMintAidlTestBase ExportKeyTest;
@@ -3300,6 +3352,26 @@
 }
 
 /*
+ * ImportKeyTest.RsaAttestMultiPurposeFail
+ *
+ * Verifies that importing an RSA key pair with purpose ATTEST_KEY+SIGN fails.
+ */
+TEST_P(ImportKeyTest, RsaAttestMultiPurposeFail) {
+    uint32_t key_size = 2048;
+    string key = rsa_2048_key;
+
+    ASSERT_EQ(ErrorCode::INCOMPATIBLE_PURPOSE,
+              ImportKey(AuthorizationSetBuilder()
+                                .Authorization(TAG_NO_AUTH_REQUIRED)
+                                .RsaSigningKey(key_size, 65537)
+                                .AttestKey()
+                                .Digest(Digest::SHA_2_256)
+                                .Padding(PaddingMode::RSA_PSS)
+                                .SetDefaultValidity(),
+                        KeyFormat::PKCS8, key));
+}
+
+/*
  * ImportKeyTest.EcdsaSuccess
  *
  * Verifies that importing and using an ECDSA P-256 key pair works correctly.
@@ -3418,6 +3490,22 @@
 }
 
 /*
+ * ImportKeyTest.EcdsaAttestMultiPurposeFail
+ *
+ * Verifies that importing and using an ECDSA P-256 key pair with purpose ATTEST_KEY+SIGN fails.
+ */
+TEST_P(ImportKeyTest, EcdsaAttestMultiPurposeFail) {
+    ASSERT_EQ(ErrorCode::INCOMPATIBLE_PURPOSE,
+              ImportKey(AuthorizationSetBuilder()
+                                .Authorization(TAG_NO_AUTH_REQUIRED)
+                                .EcdsaSigningKey(EcCurve::P_256)
+                                .AttestKey()
+                                .Digest(Digest::SHA_2_256)
+                                .SetDefaultValidity(),
+                        KeyFormat::PKCS8, ec_256_key));
+}
+
+/*
  * ImportKeyTest.AesSuccess
  *
  * Verifies that importing and using an AES key works.
@@ -6609,7 +6697,7 @@
 
 typedef KeyMintAidlTestBase KeyAgreementTest;
 
-int CurveToOpenSslCurveName(EcCurve curve) {
+static int EcdhCurveToOpenSslCurveName(EcCurve curve) {
     switch (curve) {
         case EcCurve::P_224:
             return NID_secp224r1;
@@ -6619,6 +6707,8 @@
             return NID_secp384r1;
         case EcCurve::P_521:
             return NID_secp521r1;
+        case EcCurve::CURVE_25519:
+            return NID_X25519;
     }
 }
 
@@ -6640,7 +6730,7 @@
         for (auto localCurve : ValidCurves()) {
             // Generate EC key locally (with access to private key material)
             auto ecKey = EC_KEY_Ptr(EC_KEY_new());
-            int curveName = CurveToOpenSslCurveName(localCurve);
+            int curveName = EcdhCurveToOpenSslCurveName(localCurve);
             auto group = EC_GROUP_Ptr(EC_GROUP_new_by_curve_name(curveName));
             ASSERT_NE(group, nullptr);
             ASSERT_EQ(EC_KEY_set_group(ecKey.get(), group.get()), 1);
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterDownloadEvent.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterDownloadEvent.aidl
index b51e633..8a05dbd 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterDownloadEvent.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterDownloadEvent.aidl
@@ -36,6 +36,7 @@
 @VintfStability
 parcelable DemuxFilterDownloadEvent {
   int itemId;
+  int downloadId;
   int mpuSequenceNumber;
   int itemFragmentIndex;
   int lastItemFragmentIndex;
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterDownloadSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterDownloadSettings.aidl
index ff06888..86ce646 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterDownloadSettings.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterDownloadSettings.aidl
@@ -35,5 +35,6 @@
 /* @hide */
 @VintfStability
 parcelable DemuxFilterDownloadSettings {
+  boolean useDownloadId;
   int downloadId;
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterMediaEvent.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterMediaEvent.aidl
index a463d68..993c639 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterMediaEvent.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterMediaEvent.aidl
@@ -38,6 +38,8 @@
   int streamId;
   boolean isPtsPresent;
   long pts;
+  boolean isDtsPresent;
+  long dts;
   long dataLength;
   long offset;
   android.hardware.common.NativeHandle avMemory;
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterSectionEvent.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterSectionEvent.aidl
index 01b8a77..199a09c 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterSectionEvent.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterSectionEvent.aidl
@@ -38,5 +38,5 @@
   int tableId;
   int version;
   int sectionNum;
-  int dataLength;
+  long dataLength;
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatus.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatus.aidl
index 7677221..c79b751 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatus.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatus.aidl
@@ -74,4 +74,5 @@
   boolean isShortFrames;
   android.hardware.tv.tuner.FrontendIsdbtMode isdbtMode;
   android.hardware.tv.tuner.FrontendIsdbtPartialReceptionFlag partialReceptionFlag;
+  int[] streamIdList;
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatusType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatusType.aidl
index 6342479..9ea3200 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatusType.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatusType.aidl
@@ -74,4 +74,5 @@
   IS_SHORT_FRAMES = 36,
   ISDBT_MODE = 37,
   ISDBT_PARTIAL_RECEPTION_FLAG = 38,
+  STREAM_ID_LIST = 39,
 }
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterDownloadEvent.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterDownloadEvent.aidl
index cf88928..b9df5a0 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterDownloadEvent.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterDownloadEvent.aidl
@@ -28,6 +28,11 @@
     int itemId;
 
     /**
+     * Uniquely identify data content within the same Package ID (PID).
+     */
+    int downloadId;
+
+    /**
      * MPU sequence number of filtered data (only for MMTP)
      */
     int mpuSequenceNumber;
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterDownloadSettings.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterDownloadSettings.aidl
index bd79bd5..1188b03 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterDownloadSettings.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterDownloadSettings.aidl
@@ -23,6 +23,11 @@
 @VintfStability
 parcelable DemuxFilterDownloadSettings {
     /**
+     * Whether download ID should be used.
+     */
+    boolean useDownloadId;
+
+    /**
      * Download ID (also known as the carousel ID) is carried in the PMT in
      * ISO/IEC 13818-1 for the service containing the object carousel.
      */
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterMediaEvent.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterMediaEvent.aidl
index ec7bbf1..e92b711 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterMediaEvent.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterMediaEvent.aidl
@@ -40,6 +40,16 @@
     long pts;
 
     /**
+     * true if DTS is present in the PES header.
+     */
+    boolean isDtsPresent;
+
+    /**
+     * Decode TimeStamp for audio or video frame.
+     */
+    long dts;
+
+    /**
      * Data size in bytes of audio or video frame
      */
     long dataLength;
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterSectionEvent.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterSectionEvent.aidl
index d666316..a5f9ca7 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterSectionEvent.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterSectionEvent.aidl
@@ -40,5 +40,5 @@
     /**
      * Data size in bytes of filtered data
      */
-    int dataLength;
+    long dataLength;
 }
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterStatus.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterStatus.aidl
index f07c26f..e6f3b63 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterStatus.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterStatus.aidl
@@ -24,7 +24,8 @@
 @Backing(type="byte")
 enum DemuxFilterStatus {
     /**
-     * The data in the filter buffer is ready to be read.
+     * The data in the filter buffer is ready to be read. It can also be used to know the STC
+     * (System Time Clock) ready status if it's PCR filter.
      */
     DATA_READY = 1 << 0,
 
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendEventType.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendEventType.aidl
index 40b5161..501dc1f 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendEventType.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendEventType.aidl
@@ -24,7 +24,9 @@
 @Backing(type="int")
 enum FrontendEventType {
     /**
-     * The frontend has locked to the signal specified by the tune method.
+     * The frontend has locked to the signal specified by the tune method. It can also be notified
+     * after signal is locked if the signal attributes transmission parameter of the signal is
+     * changed (e.g., Modulation).
      */
     LOCKED,
 
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatus.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatus.aidl
index 9302b76..6e6f315 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatus.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatus.aidl
@@ -91,11 +91,19 @@
 
     /**
      * AGC value is normalized from 0 to 255.
+     * Larger AGC values indicate it is applying more gain.
      */
     int agc;
 
     boolean isLnaOn;
 
+    /**
+     * Layer Error status.
+     *
+     * The order of the vectors is in ascending order of the required CNR (Contrast-to-noise ratio).
+     * The most robust layer is the first. For example, in ISDB-T, isLayerError[0] is the
+     * information of layer A. isLayerError[1] is the information of layer B.
+     */
     boolean[] isLayerError;
 
     /**
@@ -119,16 +127,28 @@
 
     /**
      * Modulation status.
+     *
+     * The order of the vectors is in ascending order of the required CNR (Contrast-to-noise ratio).
+     * The most robust layer is the first. For example, in ISDB-T, modulations[0] is the information
+     * of layer A. modulations[1] is the information of layer B.
      */
     FrontendModulation[] modulations;
 
     /**
      * Bit error ratio status.
+     *
+     * The order of the vectors is in ascending order of the required CNR (Contrast-to-noise ratio).
+     * The most robust layer is the first. For example, in ISDB-T, bers[0] is the information of
+     * layer A. bers[1] is the information of layer B.
      */
     int[] bers;
 
     /**
      * Code rate status.
+     *
+     * The order of the vectors is in ascending order of the required CN. The most robust layer is
+     * the first. For example, in ISDB-T, codeRates[0] is the information of layer A. codeRates[1]
+     * is the information of layer B.
      */
     FrontendInnerFec[] codeRates;
 
@@ -160,11 +180,19 @@
 
     /**
      * Frontend Interleaving Modes.
+     *
+     * The order of the vectors is in ascending order of the required CNR (Contrast-to-noise ratio).
+     * The most robust layer is the first. For example, in ISDB-T, interleaving[0] is the
+     * information of layer A. interleaving[1] is the information of layer B.
      */
     FrontendInterleaveMode[] interleaving;
 
     /**
      * Segments in ISDB-T Specification of all the channels.
+     *
+     * The order of the vectors is in ascending order of the required CNR (Contrast-to-noise ratio).
+     * The most robust layer is the first. For example, in ISDB-T, isdbtSegment[0] is the
+     * information of layer A. isdbtSegment[1] is the information of layer B.
      */
     int[] isdbtSegment;
 
@@ -202,4 +230,10 @@
      * ISDB-T Partial Reception Flag.
      */
     FrontendIsdbtPartialReceptionFlag partialReceptionFlag;
+
+    /**
+     * Stream ID list included in a transponder.
+     */
+    int[] streamIdList;
+
 }
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatusType.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatusType.aidl
index 103a4ab..7feb72d 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatusType.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatusType.aidl
@@ -218,4 +218,9 @@
      * ISDB-T Partial Reception Flag.
      */
     ISDBT_PARTIAL_RECEPTION_FLAG,
+
+    /**
+     * Stream ID list included in a transponder.
+     */
+   STREAM_ID_LIST,
 }
diff --git a/tv/tuner/aidl/default/Demux.cpp b/tv/tuner/aidl/default/Demux.cpp
index 4385461..a94b4ad 100644
--- a/tv/tuner/aidl/default/Demux.cpp
+++ b/tv/tuner/aidl/default/Demux.cpp
@@ -410,6 +410,37 @@
     return mIsRecording;
 }
 
+binder_status_t Demux::dump(int fd, const char** args, uint32_t numArgs) {
+    dprintf(fd, " Demux %d:\n", mDemuxId);
+    dprintf(fd, "  mIsRecording %d\n", mIsRecording);
+    {
+        dprintf(fd, "  Filters:\n");
+        map<int64_t, std::shared_ptr<Filter>>::iterator it;
+        for (it = mFilters.begin(); it != mFilters.end(); it++) {
+            it->second->dump(fd, args, numArgs);
+        }
+    }
+    {
+        dprintf(fd, "  TimeFilter:\n");
+        if (mTimeFilter != nullptr) {
+            mTimeFilter->dump(fd, args, numArgs);
+        }
+    }
+    {
+        dprintf(fd, "  DvrPlayback:\n");
+        if (mDvrPlayback != nullptr) {
+            mDvrPlayback->dump(fd, args, numArgs);
+        }
+    }
+    {
+        dprintf(fd, "  DvrRecord:\n");
+        if (mDvrRecord != nullptr) {
+            mDvrRecord->dump(fd, args, numArgs);
+        }
+    }
+    return STATUS_OK;
+}
+
 bool Demux::attachRecordFilter(int64_t filterId) {
     if (mFilters[filterId] == nullptr || mDvrRecord == nullptr ||
         !mFilters[filterId]->isRecordFilter()) {
diff --git a/tv/tuner/aidl/default/Demux.h b/tv/tuner/aidl/default/Demux.h
index 1b789bd..7f0b0a7 100644
--- a/tv/tuner/aidl/default/Demux.h
+++ b/tv/tuner/aidl/default/Demux.h
@@ -71,6 +71,8 @@
     ::ndk::ScopedAStatus connectCiCam(int32_t in_ciCamId) override;
     ::ndk::ScopedAStatus disconnectCiCam() override;
 
+    binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
+
     // Functions interacts with Tuner Service
     void stopFrontendInput();
     ::ndk::ScopedAStatus removeFilter(int64_t filterId);
diff --git a/tv/tuner/aidl/default/Dvr.cpp b/tv/tuner/aidl/default/Dvr.cpp
index 4f34b8e..c591d07 100644
--- a/tv/tuner/aidl/default/Dvr.cpp
+++ b/tv/tuner/aidl/default/Dvr.cpp
@@ -177,6 +177,13 @@
     return mDvrEventFlag;
 }
 
+binder_status_t Dvr::dump(int fd, const char** /* args */, uint32_t /* numArgs */) {
+    dprintf(fd, "    Dvr:\n");
+    dprintf(fd, "      mType: %hhd\n", mType);
+    dprintf(fd, "      mDvrThreadRunning: %d\n", (bool)mDvrThreadRunning);
+    return STATUS_OK;
+}
+
 void Dvr::playbackThreadLoop() {
     ALOGD("[Dvr] playback threadLoop start.");
 
diff --git a/tv/tuner/aidl/default/Dvr.h b/tv/tuner/aidl/default/Dvr.h
index ad8728e..6ff71cd 100644
--- a/tv/tuner/aidl/default/Dvr.h
+++ b/tv/tuner/aidl/default/Dvr.h
@@ -71,6 +71,8 @@
     ::ndk::ScopedAStatus flush() override;
     ::ndk::ScopedAStatus close() override;
 
+    binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
+
     /**
      * To create a DvrMQ and its Event Flag.
      *
diff --git a/tv/tuner/aidl/default/Filter.cpp b/tv/tuner/aidl/default/Filter.cpp
index 54037be..769ebe2 100644
--- a/tv/tuner/aidl/default/Filter.cpp
+++ b/tv/tuner/aidl/default/Filter.cpp
@@ -22,6 +22,7 @@
 #include <aidl/android/hardware/tv/tuner/DemuxQueueNotifyBits.h>
 #include <aidl/android/hardware/tv/tuner/Result.h>
 #include <aidlcommonsupport/NativeHandle.h>
+#include <inttypes.h>
 #include <utils/Log.h>
 
 #include "Filter.h"
@@ -655,6 +656,17 @@
     mSharedAvMemHandle = nullptr;
 }
 
+binder_status_t Filter::dump(int fd, const char** /* args */, uint32_t /* numArgs */) {
+    dprintf(fd, "    Filter %" PRIu64 ":\n", mFilterId);
+    dprintf(fd, "      Main type: %d\n", mType.mainType);
+    dprintf(fd, "      mIsMediaFilter: %d\n", mIsMediaFilter);
+    dprintf(fd, "      mIsPcrFilter: %d\n", mIsPcrFilter);
+    dprintf(fd, "      mIsRecordFilter: %d\n", mIsRecordFilter);
+    dprintf(fd, "      mIsUsingFMQ: %d\n", mIsUsingFMQ);
+    dprintf(fd, "      mFilterThreadRunning: %d\n", (bool)mFilterThreadRunning);
+    return STATUS_OK;
+}
+
 void Filter::maySendFilterStatusCallback() {
     if (!mIsUsingFMQ) {
         return;
@@ -1148,6 +1160,7 @@
     DemuxFilterMediaEvent mediaEvent;
     mediaEvent.streamId = 1;
     mediaEvent.isPtsPresent = true;
+    mediaEvent.isDtsPresent = false;
     mediaEvent.dataLength = 3;
     mediaEvent.offset = 4;
     mediaEvent.isSecureMemory = true;
@@ -1238,6 +1251,7 @@
 void Filter::createDownloadEvent(vector<DemuxFilterEvent>& events) {
     DemuxFilterDownloadEvent download;
     download.itemId = 1;
+    download.downloadId = 1;
     download.mpuSequenceNumber = 2;
     download.itemFragmentIndex = 3;
     download.lastItemFragmentIndex = 4;
diff --git a/tv/tuner/aidl/default/Filter.h b/tv/tuner/aidl/default/Filter.h
index 8388c98..e301249 100644
--- a/tv/tuner/aidl/default/Filter.h
+++ b/tv/tuner/aidl/default/Filter.h
@@ -126,6 +126,8 @@
     ::ndk::ScopedAStatus setDataSource(const std::shared_ptr<IFilter>& in_filter) override;
     ::ndk::ScopedAStatus setDelayHint(const FilterDelayHint& in_hint) override;
 
+    binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
+
     /**
      * To create a FilterMQ and its Event Flag.
      *
diff --git a/tv/tuner/aidl/default/Frontend.cpp b/tv/tuner/aidl/default/Frontend.cpp
index 77d20e2..a4dde2a 100644
--- a/tv/tuner/aidl/default/Frontend.cpp
+++ b/tv/tuner/aidl/default/Frontend.cpp
@@ -676,6 +676,11 @@
                         FrontendIsdbtPartialReceptionFlag::AUTO);
                 break;
             }
+            case FrontendStatusType::STREAM_ID_LIST: {
+                vector<int32_t> streamIds = {0, 1};
+                status.set<FrontendStatus::streamIdList>(streamIds);
+                break;
+            }
             default: {
                 continue;
             }
@@ -718,6 +723,14 @@
     return ::ndk::ScopedAStatus::ok();
 }
 
+binder_status_t Frontend::dump(int fd, const char** /* args */, uint32_t /* numArgs */) {
+    dprintf(fd, "  Frontend %d\n", mId);
+    dprintf(fd, "    mType: %d\n", mType);
+    dprintf(fd, "    mIsLocked: %d\n", mIsLocked);
+    dprintf(fd, "    mCiCamId: %d\n", mCiCamId);
+    return STATUS_OK;
+}
+
 FrontendType Frontend::getFrontendType() {
     return mType;
 }
diff --git a/tv/tuner/aidl/default/Frontend.h b/tv/tuner/aidl/default/Frontend.h
index 3c602cf..5e7b10c 100644
--- a/tv/tuner/aidl/default/Frontend.h
+++ b/tv/tuner/aidl/default/Frontend.h
@@ -50,6 +50,8 @@
     ::ndk::ScopedAStatus linkCiCam(int32_t in_ciCamId, int32_t* _aidl_return) override;
     ::ndk::ScopedAStatus unlinkCiCam(int32_t in_ciCamId) override;
 
+    binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
+
     FrontendType getFrontendType();
     int32_t getFrontendId();
     string getSourceFile();
diff --git a/tv/tuner/aidl/default/TimeFilter.cpp b/tv/tuner/aidl/default/TimeFilter.cpp
index dde7be3..9611ed9 100644
--- a/tv/tuner/aidl/default/TimeFilter.cpp
+++ b/tv/tuner/aidl/default/TimeFilter.cpp
@@ -83,6 +83,12 @@
     return ::ndk::ScopedAStatus::ok();
 }
 
+binder_status_t TimeFilter::dump(int fd, const char** /* args */, uint32_t /* numArgs */) {
+    dprintf(fd, "    TimeFilter:\n");
+    dprintf(fd, "      mTimeStamp: %" PRIu64 "\n", mTimeStamp);
+    return STATUS_OK;
+}
+
 }  // namespace tuner
 }  // namespace tv
 }  // namespace hardware
diff --git a/tv/tuner/aidl/default/TimeFilter.h b/tv/tuner/aidl/default/TimeFilter.h
index ff35c47..5f4c2d4 100644
--- a/tv/tuner/aidl/default/TimeFilter.h
+++ b/tv/tuner/aidl/default/TimeFilter.h
@@ -44,8 +44,10 @@
     ::ndk::ScopedAStatus getSourceTime(int64_t* _aidl_return) override;
     ::ndk::ScopedAStatus close() override;
 
+    binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
+
   private:
-    std::shared_ptr<Demux> mDemux;
+    ::std::shared_ptr<Demux> mDemux;
     uint64_t mTimeStamp = INVALID_TIME_STAMP;
     time_t mBeginTime;
 };
diff --git a/tv/tuner/aidl/default/Tuner.cpp b/tv/tuner/aidl/default/Tuner.cpp
index badb08f..96e83bb 100644
--- a/tv/tuner/aidl/default/Tuner.cpp
+++ b/tv/tuner/aidl/default/Tuner.cpp
@@ -55,9 +55,13 @@
     capsIsdbs.set<FrontendCapabilities::Tag::isdbsCaps>(FrontendIsdbsCapabilities());
     mFrontendCaps[0] = capsIsdbs;
     statusCaps = {
-            FrontendStatusType::DEMOD_LOCK,  FrontendStatusType::SNR,
-            FrontendStatusType::FEC,         FrontendStatusType::MODULATION,
-            FrontendStatusType::MODULATIONS, FrontendStatusType::ROLL_OFF,
+            FrontendStatusType::DEMOD_LOCK,
+            FrontendStatusType::SNR,
+            FrontendStatusType::FEC,
+            FrontendStatusType::MODULATION,
+            FrontendStatusType::MODULATIONS,
+            FrontendStatusType::ROLL_OFF,
+            FrontendStatusType::STREAM_ID_LIST,
     };
     mFrontendStatusCaps[0] = statusCaps;
 
@@ -169,7 +173,7 @@
     statusCaps = {
             FrontendStatusType::DEMOD_LOCK,      FrontendStatusType::MODULATION,
             FrontendStatusType::MODULATIONS,     FrontendStatusType::ROLL_OFF,
-            FrontendStatusType::IS_SHORT_FRAMES,
+            FrontendStatusType::IS_SHORT_FRAMES, FrontendStatusType::STREAM_ID_LIST,
     };
     mFrontendStatusCaps[8] = statusCaps;
 
@@ -313,6 +317,33 @@
     return ::ndk::ScopedAStatus::ok();
 }
 
+binder_status_t Tuner::dump(int fd, const char** args, uint32_t numArgs) {
+    ALOGV("%s", __FUNCTION__);
+    {
+        dprintf(fd, "Frontends:\n");
+        for (int i = 0; i < mFrontendSize; i++) {
+            mFrontends[i]->dump(fd, args, numArgs);
+            for (int j = 0; j < mFrontendStatusCaps[i].size(); j++) {
+                dprintf(fd, "    statusCap: %d\n", mFrontendStatusCaps[i][j]);
+            }
+        }
+    }
+    {
+        dprintf(fd, "Demuxs:\n");
+        map<int32_t, std::shared_ptr<Demux>>::iterator it;
+        for (it = mDemuxes.begin(); it != mDemuxes.end(); it++) {
+            it->second->dump(fd, args, numArgs);
+        }
+    }
+    {
+        dprintf(fd, "Lnbs:\n");
+        for (int i = 0; i < mLnbs.size(); i++) {
+            mLnbs[i]->dump(fd, args, numArgs);
+        }
+    }
+    return STATUS_OK;
+}
+
 void Tuner::setFrontendAsDemuxSource(int32_t frontendId, int32_t demuxId) {
     mFrontendToDemux[frontendId] = demuxId;
     if (mFrontends[frontendId] != nullptr && mFrontends[frontendId]->isLocked()) {
@@ -332,6 +363,10 @@
 }
 
 void Tuner::removeFrontend(int32_t frontendId) {
+    map<int32_t, int32_t>::iterator it = mFrontendToDemux.find(frontendId);
+    if (it != mFrontendToDemux.end()) {
+        mDemuxes.erase(it->second);
+    }
     mFrontendToDemux.erase(frontendId);
 }
 
diff --git a/tv/tuner/aidl/default/Tuner.h b/tv/tuner/aidl/default/Tuner.h
index 7af7ab8..682496c 100644
--- a/tv/tuner/aidl/default/Tuner.h
+++ b/tv/tuner/aidl/default/Tuner.h
@@ -57,6 +57,8 @@
                                        std::vector<int32_t>* out_lnbId,
                                        std::shared_ptr<ILnb>* _aidl_return) override;
 
+    binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
+
     std::shared_ptr<Frontend> getFrontendById(int32_t frontendId);
     void setFrontendAsDemuxSource(int32_t frontendId, int32_t demuxId);
     void frontendStartTune(int32_t frontendId);
diff --git a/tv/tuner/aidl/vts/functional/FilterTests.cpp b/tv/tuner/aidl/vts/functional/FilterTests.cpp
index a5acdc1..53afef7 100644
--- a/tv/tuner/aidl/vts/functional/FilterTests.cpp
+++ b/tv/tuner/aidl/vts/functional/FilterTests.cpp
@@ -17,6 +17,7 @@
 #include "FilterTests.h"
 
 #include <inttypes.h>
+#include <algorithm>
 
 #include <aidl/android/hardware/tv/tuner/DemuxFilterMonitorEventType.h>
 #include <aidlcommonsupport/NativeHandle.h>
@@ -31,23 +32,24 @@
     mPidFilterOutputCount++;
     mMsgCondition.signal();
 
-    // HACK: we need to cast the const away as DemuxFilterEvent contains a ScopedFileDescriptor
-    // that cannot be copied.
-    for (auto&& e : const_cast<std::vector<DemuxFilterEvent>&>(events)) {
-        auto it = mFilterEventPromises.find(e.getTag());
-        if (it != mFilterEventPromises.cend()) {
-            it->second.set_value(std::move(e));
-            mFilterEventPromises.erase(it);
+    for (auto it = mFilterCallbackVerifiers.begin(); it != mFilterCallbackVerifiers.end();) {
+        auto& [verifier, promise] = *it;
+        if (verifier(events)) {
+            promise.set_value();
+            it = mFilterCallbackVerifiers.erase(it);
+        } else {
+            ++it;
         }
-    }
+    };
 
     return ::ndk::ScopedAStatus::ok();
 }
 
-std::future<DemuxFilterEvent> FilterCallback::getNextFilterEventWithTag(DemuxFilterEvent::Tag tag) {
-    // Note: this currently only supports one future per DemuxFilterEvent::Tag.
-    mFilterEventPromises[tag] = std::promise<DemuxFilterEvent>();
-    return mFilterEventPromises[tag].get_future();
+std::future<void> FilterCallback::verifyFilterCallback(FilterCallbackVerifier&& verifier) {
+    std::promise<void> promise;
+    auto future = promise.get_future();
+    mFilterCallbackVerifiers.emplace_back(std::move(verifier), std::move(promise));
+    return future;
 }
 
 void FilterCallback::testFilterDataOutput() {
diff --git a/tv/tuner/aidl/vts/functional/FilterTests.h b/tv/tuner/aidl/vts/functional/FilterTests.h
index 6258bac..f579441 100644
--- a/tv/tuner/aidl/vts/functional/FilterTests.h
+++ b/tv/tuner/aidl/vts/functional/FilterTests.h
@@ -60,9 +60,18 @@
 
 class FilterCallback : public BnFilterCallback {
   public:
+    /**
+     * A FilterCallbackVerifier is used to test and verify filter callbacks.
+     * The function should return true when a callback has been handled by this
+     * filter verifier. This will cause the associated future to be unblocked.
+     * If the function returns false, we continue to wait for future callbacks
+     * (the future remains blocked).
+     */
+    using FilterCallbackVerifier = std::function<bool(const std::vector<DemuxFilterEvent>&)>;
+
     virtual ::ndk::ScopedAStatus onFilterEvent(const vector<DemuxFilterEvent>& events) override;
 
-    std::future<DemuxFilterEvent> getNextFilterEventWithTag(DemuxFilterEvent::Tag tag);
+    std::future<void> verifyFilterCallback(FilterCallbackVerifier&& verifier);
 
     virtual ::ndk::ScopedAStatus onFilterStatus(const DemuxFilterStatus /*status*/) override {
         return ::ndk::ScopedAStatus::ok();
@@ -85,7 +94,7 @@
     int32_t mFilterId;
     std::shared_ptr<IFilter> mFilter;
 
-    std::unordered_map<DemuxFilterEvent::Tag, std::promise<DemuxFilterEvent>> mFilterEventPromises;
+    std::vector<std::pair<FilterCallbackVerifier, std::promise<void>>> mFilterCallbackVerifiers;
     native_handle_t* mAvSharedHandle = nullptr;
     uint64_t mAvSharedMemSize = -1;
 
diff --git a/tv/tuner/aidl/vts/functional/FrontendTests.cpp b/tv/tuner/aidl/vts/functional/FrontendTests.cpp
index 6204803..12b1f33 100644
--- a/tv/tuner/aidl/vts/functional/FrontendTests.cpp
+++ b/tv/tuner/aidl/vts/functional/FrontendTests.cpp
@@ -398,6 +398,13 @@
                             expectStatuses[i].get<FrontendStatus::Tag::partialReceptionFlag>());
                 break;
             }
+            case FrontendStatusType::STREAM_ID_LIST: {
+                ASSERT_TRUE(std::equal(
+                        realStatuses[i].get<FrontendStatus::Tag::streamIdList>().begin(),
+                        realStatuses[i].get<FrontendStatus::Tag::streamIdList>().end(),
+                        expectStatuses[i].get<FrontendStatus::Tag::streamIdList>().begin()));
+                break;
+            }
             default: {
                 continue;
             }
diff --git a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp
index 88890e4..89e42df 100644
--- a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp
+++ b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp
@@ -640,10 +640,51 @@
     testTimeFilter(timeFilterMap[timeFilter.timeFilterId]);
 }
 
-// TODO: move boilerplate into text fixture
-TEST_P(TunerFilterAidlTest, FilterTimeDelayHintTest) {
-    description("Test filter delay hint.");
+static bool isMediaFilter(const FilterConfig& filterConfig) {
+    switch (filterConfig.type.mainType) {
+        case DemuxFilterMainType::TS: {
+            // TS Audio and Video filters are media filters
+            auto tsFilterType =
+                    filterConfig.type.subType.get<DemuxFilterSubType::Tag::tsFilterType>();
+            return (tsFilterType == DemuxTsFilterType::AUDIO ||
+                    tsFilterType == DemuxTsFilterType::VIDEO);
+        }
+        case DemuxFilterMainType::MMTP: {
+            // MMTP Audio and Video filters are media filters
+            auto mmtpFilterType =
+                    filterConfig.type.subType.get<DemuxFilterSubType::Tag::mmtpFilterType>();
+            return (mmtpFilterType == DemuxMmtpFilterType::AUDIO ||
+                    mmtpFilterType == DemuxMmtpFilterType::VIDEO);
+        }
+        default:
+            return false;
+    }
+}
 
+static int getDemuxFilterEventDataLength(const DemuxFilterEvent& event) {
+    switch (event.getTag()) {
+        case DemuxFilterEvent::Tag::section:
+            return event.get<DemuxFilterEvent::Tag::section>().dataLength;
+        case DemuxFilterEvent::Tag::media:
+            return event.get<DemuxFilterEvent::Tag::media>().dataLength;
+        case DemuxFilterEvent::Tag::pes:
+            return event.get<DemuxFilterEvent::Tag::pes>().dataLength;
+        case DemuxFilterEvent::Tag::download:
+            return event.get<DemuxFilterEvent::Tag::download>().dataLength;
+        case DemuxFilterEvent::Tag::ipPayload:
+            return event.get<DemuxFilterEvent::Tag::ipPayload>().dataLength;
+
+        case DemuxFilterEvent::Tag::tsRecord:
+        case DemuxFilterEvent::Tag::mmtpRecord:
+        case DemuxFilterEvent::Tag::temi:
+        case DemuxFilterEvent::Tag::monitorEvent:
+        case DemuxFilterEvent::Tag::startId:
+            return 0;
+    }
+}
+
+// TODO: move boilerplate into text fixture
+void TunerFilterAidlTest::testDelayHint(const FilterConfig& filterConf) {
     int32_t feId;
     int32_t demuxId;
     std::shared_ptr<IDemux> demux;
@@ -657,40 +698,87 @@
     ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
     mFilterTests.setDemux(demux);
 
-    const auto& filterConf = filterMap[live.ipFilterId];
     ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize));
     ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(filterId));
-    ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId));
-    ASSERT_TRUE(mFilterTests.configIpFilterCid(filterConf.ipCid, filterId));
 
+    bool mediaFilter = isMediaFilter(filterConf);
     auto filter = mFilterTests.getFilterById(filterId);
 
-    auto delayValue = std::chrono::milliseconds(5000);
-    FilterDelayHint delayHint;
-    delayHint.hintType = FilterDelayHintType::TIME_DELAY_IN_MS;
-    delayHint.hintValue = delayValue.count();
+    auto timeDelayInMs = std::chrono::milliseconds(filterConf.timeDelayInMs);
+    if (timeDelayInMs.count() > 0) {
+        FilterDelayHint delayHint;
+        delayHint.hintType = FilterDelayHintType::TIME_DELAY_IN_MS;
+        delayHint.hintValue = timeDelayInMs.count();
 
-    auto status = filter->setDelayHint(delayHint);
-    ASSERT_TRUE(status.isOk());
+        // setDelayHint should fail for media filters.
+        ASSERT_EQ(filter->setDelayHint(delayHint).isOk(), !mediaFilter);
+    }
 
-    auto startTime = std::chrono::steady_clock::now();
-    ASSERT_TRUE(mFilterTests.startFilter(filterId));
+    int dataDelayInBytes = filterConf.dataDelayInBytes;
+    if (dataDelayInBytes > 0) {
+        FilterDelayHint delayHint;
+        delayHint.hintType = FilterDelayHintType::DATA_SIZE_DELAY_IN_BYTES;
+        delayHint.hintValue = dataDelayInBytes;
 
-    auto cb = mFilterTests.getFilterCallbacks().at(filterId);
-    auto future = cb->getNextFilterEventWithTag(DemuxFilterEvent::Tag::ipPayload);
+        // setDelayHint should fail for media filters.
+        ASSERT_EQ(filter->setDelayHint(delayHint).isOk(), !mediaFilter);
+    }
 
-    // block and wait for callback to be received.
-    ASSERT_EQ(future.wait_for(std::chrono::seconds(10)), std::future_status::ready);
-    auto duration = std::chrono::steady_clock::now() - startTime;
-    ASSERT_GE(duration, delayValue);
+    // start and stop filter in order to circumvent callback scheduler race
+    // conditions after adjusting filter delays.
+    mFilterTests.startFilter(filterId);
+    mFilterTests.stopFilter(filterId);
 
-    // cleanup
-    ASSERT_TRUE(mFilterTests.stopFilter(filterId));
+    if (!mediaFilter) {
+        auto cb = mFilterTests.getFilterCallbacks().at(filterId);
+        int callbackSize = 0;
+        auto future = cb->verifyFilterCallback(
+                [&callbackSize](const std::vector<DemuxFilterEvent>& events) {
+                    for (const auto& event : events) {
+                        callbackSize += getDemuxFilterEventDataLength(event);
+                    }
+                    return true;
+                });
+
+        // The configure stage can also produce events, so we should set the delay
+        // hint beforehand.
+        ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId));
+
+        auto startTime = std::chrono::steady_clock::now();
+        ASSERT_TRUE(mFilterTests.startFilter(filterId));
+
+        // block and wait for callback to be received.
+        auto timeout = std::chrono::seconds(30);
+        ASSERT_EQ(future.wait_for(timeout), std::future_status::ready);
+        auto duration = std::chrono::steady_clock::now() - startTime;
+
+        bool delayHintTest = duration >= timeDelayInMs;
+        bool dataSizeTest = callbackSize >= dataDelayInBytes;
+
+        if (timeDelayInMs.count() > 0 && dataDelayInBytes > 0) {
+            ASSERT_TRUE(delayHintTest || dataSizeTest);
+        } else {
+            // if only one of time delay / data delay is configured, one of them
+            // holds true by default, so we want both assertions to be true.
+            ASSERT_TRUE(delayHintTest && dataSizeTest);
+        }
+
+        ASSERT_TRUE(mFilterTests.stopFilter(filterId));
+    }
+
     ASSERT_TRUE(mFilterTests.closeFilter(filterId));
     ASSERT_TRUE(mDemuxTests.closeDemux());
     ASSERT_TRUE(mFrontendTests.closeFrontend());
 }
 
+TEST_P(TunerFilterAidlTest, FilterDelayHintTest) {
+    description("Test filter time delay hint.");
+
+    for (const auto& obj : filterMap) {
+        testDelayHint(obj.second);
+    }
+}
+
 TEST_P(TunerPlaybackAidlTest, PlaybackDataFlowWithTsSectionFilterTest) {
     description("Feed ts data from playback and configure Ts section filter to get output");
     if (!playback.support || playback.sectionFilterId.compare(emptyHardwareId) == 0) {
diff --git a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.h b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.h
index 13c5a80..7f80d90 100644
--- a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.h
+++ b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.h
@@ -140,6 +140,7 @@
     void reconfigSingleFilterInDemuxTest(FilterConfig filterConf, FilterConfig filterReconf,
                                          FrontendConfig frontendConf);
     void testTimeFilter(TimeFilterConfig filterConf);
+    void testDelayHint(const FilterConfig& filterConf);
 
     DemuxFilterType getLinkageFilterType(int bit) {
         DemuxFilterType type;
diff --git a/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h b/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h
index 7ccf31a..b6cc5f8 100644
--- a/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h
+++ b/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h
@@ -96,6 +96,8 @@
     AvStreamType streamType;
     int32_t ipCid;
     int32_t monitorEventTypes;
+    int timeDelayInMs = 0;
+    int dataDelayInBytes = 0;
 
     bool operator<(const FilterConfig& /*c*/) const { return false; }
 };
@@ -336,6 +338,12 @@
                 if (filterConfig.hasMonitorEventTypes()) {
                     filterMap[id].monitorEventTypes = (int32_t)filterConfig.getMonitorEventTypes();
                 }
+                if (filterConfig.hasTimeDelayInMs()) {
+                    filterMap[id].timeDelayInMs = filterConfig.getTimeDelayInMs();
+                }
+                if (filterConfig.hasDataDelayInBytes()) {
+                    filterMap[id].dataDelayInBytes = filterConfig.getDataDelayInBytes();
+                }
                 if (filterConfig.hasAvFilterSettings_optional()) {
                     auto av = filterConfig.getFirstAvFilterSettings_optional();
                     if (av->hasAudioStreamType_optional()) {
diff --git a/tv/tuner/config/api/current.txt b/tv/tuner/config/api/current.txt
index 6c637a4..db1d076 100644
--- a/tv/tuner/config/api/current.txt
+++ b/tv/tuner/config/api/current.txt
@@ -256,6 +256,7 @@
     ctor public Filter();
     method @Nullable public android.media.tuner.testing.configuration.V1_0.AvFilterSettings getAvFilterSettings_optional();
     method @Nullable public java.math.BigInteger getBufferSize();
+    method @Nullable public java.math.BigInteger getDataDelayInBytes();
     method @Nullable public String getId();
     method @Nullable public android.media.tuner.testing.configuration.V1_0.IpFilterConfig getIpFilterConfig_optional();
     method @Nullable public android.media.tuner.testing.configuration.V1_0.FilterMainTypeEnum getMainType();
@@ -264,9 +265,11 @@
     method @Nullable public android.media.tuner.testing.configuration.V1_0.RecordFilterSettings getRecordFilterSettings_optional();
     method @Nullable public android.media.tuner.testing.configuration.V1_0.SectionFilterSettings getSectionFilterSettings_optional();
     method @Nullable public android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum getSubType();
+    method @Nullable public java.math.BigInteger getTimeDelayInMs();
     method @Nullable public boolean getUseFMQ();
     method public void setAvFilterSettings_optional(@Nullable android.media.tuner.testing.configuration.V1_0.AvFilterSettings);
     method public void setBufferSize(@Nullable java.math.BigInteger);
+    method public void setDataDelayInBytes(@Nullable java.math.BigInteger);
     method public void setId(@Nullable String);
     method public void setIpFilterConfig_optional(@Nullable android.media.tuner.testing.configuration.V1_0.IpFilterConfig);
     method public void setMainType(@Nullable android.media.tuner.testing.configuration.V1_0.FilterMainTypeEnum);
@@ -275,6 +278,7 @@
     method public void setRecordFilterSettings_optional(@Nullable android.media.tuner.testing.configuration.V1_0.RecordFilterSettings);
     method public void setSectionFilterSettings_optional(@Nullable android.media.tuner.testing.configuration.V1_0.SectionFilterSettings);
     method public void setSubType(@Nullable android.media.tuner.testing.configuration.V1_0.FilterSubTypeEnum);
+    method public void setTimeDelayInMs(@Nullable java.math.BigInteger);
     method public void setUseFMQ(@Nullable boolean);
   }
 
diff --git a/tv/tuner/config/sample_tuner_vts_config_aidl_V1.xml b/tv/tuner/config/sample_tuner_vts_config_aidl_V1.xml
index 8a6229e..da77200 100644
--- a/tv/tuner/config/sample_tuner_vts_config_aidl_V1.xml
+++ b/tv/tuner/config/sample_tuner_vts_config_aidl_V1.xml
@@ -101,7 +101,7 @@
                     bufferSize="16777216" pid="257" useFMQ="false">
                 <recordFilterSettings tsIndexMask="1" scIndexType="NONE"/>
             </filter>
-            <filter id="FILTER_IP_IP_0" mainType="IP" subType="IP" bufferSize="16777216" useFMQ="false">
+            <filter id="FILTER_IP_IP_0" mainType="IP" subType="IP" bufferSize="16777216" useFMQ="false" timeDelayInMs="5000">
                 <ipFilterConfig ipCid="1">
                     <srcIpAddress isIpV4="true" ip="192 168 1 1"/>
                     <destIpAddress isIpV4="true" ip="192 168 1 1"/>
diff --git a/tv/tuner/config/tuner_testing_dynamic_configuration.xsd b/tv/tuner/config/tuner_testing_dynamic_configuration.xsd
index fc2827f..54cedfc 100644
--- a/tv/tuner/config/tuner_testing_dynamic_configuration.xsd
+++ b/tv/tuner/config/tuner_testing_dynamic_configuration.xsd
@@ -243,6 +243,10 @@
                     "bufferSize": the buffer size of the filter in hex.
                     "pid": the pid that would be used to configure the filter.
                     "useFMQ": if the filter uses FMQ.
+                    "timeDelayInMs": the filter's time delay hint. 0 by default.  Must not be
+                        longer than 30 seconds.
+                    "dataDelayInBytes": the filter's data delay hint. 0 by default. Configured data
+                        size must be received within 30 seconds.
 
                 Each filter element also contains at most one type-related "filterSettings".
                     - The settings type should match the filter "subType" attribute.
@@ -274,6 +278,8 @@
         <xs:attribute name="pid" type="xs:nonNegativeInteger" use="optional"/>
         <xs:attribute name="useFMQ" type="xs:boolean" use="required"/>
         <xs:attribute name="monitorEventTypes" type="monitoEvents" use="optional"/>
+        <xs:attribute name="timeDelayInMs" type="xs:nonNegativeInteger" use="optional"/>
+        <xs:attribute name="dataDelayInBytes" type="xs:nonNegativeInteger" use="optional"/>
     </xs:complexType>
 
     <!-- DVR SESSION -->
diff --git a/usb/1.0/default/Android.bp b/usb/1.0/default/Android.bp
index 5f56fe0..4bed2c7 100644
--- a/usb/1.0/default/Android.bp
+++ b/usb/1.0/default/Android.bp
@@ -21,11 +21,21 @@
     default_applicable_licenses: ["hardware_interfaces_license"],
 }
 
+filegroup {
+    name: "android.hardware.usb@1.0-service.xml",
+    srcs: ["android.hardware.usb@1.0-service.xml"],
+}
+
+filegroup {
+    name: "android.hardware.usb@1.0-service.rc",
+    srcs: ["android.hardware.usb@1.0-service.rc"],
+}
+
 cc_binary {
     name: "android.hardware.usb@1.0-service",
     defaults: ["hidl_defaults"],
-    init_rc: ["android.hardware.usb@1.0-service.rc"],
-    vintf_fragments: ["android.hardware.usb@1.0-service.xml"],
+    init_rc: [":android.hardware.usb@1.0-service.rc"],
+    vintf_fragments: [":android.hardware.usb@1.0-service.xml"],
     relative_install_path: "hw",
     vendor: true,
     srcs: [
diff --git a/usb/1.0/default/apex/Android.bp b/usb/1.0/default/apex/Android.bp
new file mode 100644
index 0000000..ee50fdf
--- /dev/null
+++ b/usb/1.0/default/apex/Android.bp
@@ -0,0 +1,59 @@
+// 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 {
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+apex_key {
+    name: "com.android.hardware.usb.key",
+    public_key: "com.android.hardware.usb.avbpubkey",
+    private_key: "com.android.hardware.usb.pem",
+}
+
+android_app_certificate {
+    name: "com.android.hardware.usb.certificate",
+    certificate: "com.android.hardware.usb",
+}
+
+genrule {
+    name: "com.android.hardware.usb.rc-gen",
+    srcs: [":android.hardware.usb@1.0-service.rc"],
+    out: ["com.android.hardware.usb.rc"],
+    cmd: "sed -E 's/\\/vendor/\\/apex\\/com.android.hardware.usb/' $(in) > $(out)",
+}
+
+prebuilt_etc {
+    name: "com.android.hardware.usb.rc",
+    src: ":com.android.hardware.usb.rc-gen",
+    installable: false,
+}
+
+apex {
+    name: "com.android.hardware.usb",
+    manifest: "manifest.json",
+    file_contexts: "file_contexts",
+    key: "com.android.hardware.usb.key",
+    certificate: ":com.android.hardware.usb.certificate",
+    updatable: false,
+    soc_specific: true,
+    use_vndk_as_stable: true,
+    binaries: ["android.hardware.usb@1.0-service"],
+    prebuilts: [
+        "com.android.hardware.usb.rc",
+        "android.hardware.usb.accessory.prebuilt.xml",
+        "android.hardware.usb.host.prebuilt.xml",
+    ],
+    vintf_fragments: [":android.hardware.usb@1.0-service.xml"],
+}
diff --git a/usb/1.0/default/apex/com.android.hardware.usb.avbpubkey b/usb/1.0/default/apex/com.android.hardware.usb.avbpubkey
new file mode 100644
index 0000000..0302d63
--- /dev/null
+++ b/usb/1.0/default/apex/com.android.hardware.usb.avbpubkey
Binary files differ
diff --git a/usb/1.0/default/apex/com.android.hardware.usb.pem b/usb/1.0/default/apex/com.android.hardware.usb.pem
new file mode 100644
index 0000000..e1e57da
--- /dev/null
+++ b/usb/1.0/default/apex/com.android.hardware.usb.pem
@@ -0,0 +1,51 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIJKQIBAAKCAgEAwdimmHgIZHrep3H3YfVaNYEAGg45LUEPIiwHV6aIC9V7zjBS
+SftD30Z21jGyk7hmtas6WMI2vRBDNGrZWDgPeiEQoxXQinuU4Ug5S5X2F8LpWs0y
+ZeNFwQkqZwqGdQlkmy8upfb6T7rDxqRv+C0AtGP1r4r36+Xh5ld5stVaMK0UNhZt
+VW0nQAxyeJL3tm0zfiEA9Zu7FF2IyHm+bo9+eJ7WXfjiJfkclLgqlX3ec2cvVqAf
+NHisj18PEd/qtC64b+FnkgbsdHzWbo8HW5x4STkGXNnH+O3dvkWBX60MOfywfZFw
++yaz5mt7K+ft/V4UA7zKiAEFM+J1lND9/UMJnd0XMYYtcRQF8lmu4dlcjfbbAm0k
+VgoUEsizIeMPLrMj837uVloKKzIXmPsVsfMarP/MrX6TJfzdUhdm01pVO1g0wtHJ
+J3eYQsEnOI7RjL+uZDQvPWAnr71pvacn66PAJC1UPulEEla5lhd30RDItbJkngXp
+3UggW32ZOQt3Oc8P0eo9SCnBlHtCVr8wfxAbxCoPR9qIdX3azkQRqcKqGbBbPnkc
+hSCzeIofUkYGibfbZg4k1yY82xEqZuN7J1zycoGP4wyhXeRLTRWxfPR5dxxmQZaS
+67A1LWrYvAzF8Rd44VMRlI/Qk6zuBsL01j2dfBqit+le+viQmTYb3BpV+1kCAwEA
+AQKCAgAmSfX2LddyiXaLWo6DsePkp5tuihqvHqevl0TIAmPi+oMe4hqO9GueoZt9
+iYl9djILdkvrFkmbpKexpd1SeJhOBlPz8q4jfG+W5B41GOToIp7XSarHx1GS5I2U
+ltaiLX3KzVIIhDVDJF/hT7+yJKl7+DaiOu/nj5vEVMj8EvpinP1eBaYI9quHEi5W
+NKlrRjyikEBRQzZ7ulH3T1zXF87iYnVzUGLTH1aO5aW7q4YSA3KtSKmBQsjK9PrU
+DAefGY9iwgIkLOvtwm7UnbnVVZ3I0NO56WZ/e/SNzcrVLCg7F/eAhgbsBOQKAnbs
+4D35CuknJ9ZVcOYnLncNMw7IRMKULKYLAuLLN1X33y22qaVxYA42rq13mZrijlua
+CMQ2Ur+GNcq8OI3mRDO38yKeJ5b4885LQdlrXXyoGnSjlkU5n8U9Jw6q2rZGiWlk
+4Q71g+KUl0rtXSnFSIJLNTK6Cd3ETStxswLvvCvfLTrRQcO8f2SdVxblmsc9eCDs
+JUxz6Sahkpb9hsY8fozu6laXC/5Ezy0TinRgGjQM/DQqbXtFXgse56mDxzSho5oh
+Spy3X7Q/v4VUtrSKsEZEIEVWCpplzVULpHenCDbU58rHyEcS7ew+kwlfHC73iEhX
+HPujSIKvStO7yCEeY6IdhON8iVX34uvQeAgEe4+rehQHLZUg0QKCAQEA9AS3imKF
+yEt0yNRLcdXSqYkak+OM2kfhBBcLndCT7Terr6yluv/SkPGYjUbmr2XiygMv8IwO
+8f+KbWsNwYCaB22HVYVGL0oUYAlCvWhnia3Iwn6ZZuXuJv5mmfqt/GMlaIfohNLy
+zI2OlcpcAuRfNlenjNyd+inxwdXL28Z86kbabnUlijgqpu4KFOYOlxbTRv93IlfM
+Ico1pZkLS1glDMFLetF+IWq4zqpXrdgNUk1KX3sofOCfZQnlWFrrHbXJPCgPAtlv
+xP4dmJQgtWkWwxUlelfz34LcCUVX2aTlgKjuvgvyCt2ZPWixXbDtjsCBTn3xBhoY
+kDp2OyMC+d543QKCAQEAy11GpYOQvTMKbV07EmN9jTRYg7gRrxsT3Kd4Xy+NpIY8
+v6J5Keeppk9t6WBrJi2cQU/EoHcd3fRkWMnWMNorZDiCu34VG5bfa4pTqnSLdLC4
+/e5UHdHqCy9deAwhlHYWbAx0KnxXWGxkq05dXvQsVuOtAs528NcujnLpwDONQt5P
+e3RIZmOOjr+7rqGp3vA9SuNOINOQpeKxQT6GRGw4mlYofdwOPaE1wCsO8vQCNmCJ
+DEfdm+hWjTLAV2IBCfi5BKRsIAXrABPzkzDeLGDmaQkJTDpK8UQcrFnqItGeo+yl
+fDjxA0zAPWYGcyXcXbtvayX+zCk/SKwQABqUtaumrQKCAQEA0mdizwsGqd8OMsCC
+0QP64j4a0Zvqbqh9yCYK2Sfo9SkEe7SVLnm5WUtIK8EP1fs3ItK+ul454MZj2Nbv
+BINbzL3PbJk/HDV2/hveFS154UgcjD/XC9eEktDXLTvuW2ot7kUJ48V0n5YLdPMI
+hWHfCx9nlFkCSptyHp23aqhqOyOe4pFWLikh9c/Yl46K1BJVWKmcUtt7Y0NVIJWn
+HG9Dew0MhTkv1aaM9X4Bnh9l1SpZz5yFG7AfIGL5A0dZ5cNCYgF0eBN+gVBPuqk2
+ztVvUATizOwblwThr4jAKCU70sVXHj10lZPftwiXrt6I54brt/92HLnRpkMSgQk+
+Xq9KbQKCAQAXxPM47UPBmXGijr8UyyQlmPSvkJggi12q8LgVCA3aKQZ4r5jR2Q3v
+LmF+YZKkh7g3ugcValbHVoVUC2NJmnZv5FsDZx04eE3s1+Inji+ul+lHZM/YHGzq
+mcKnAWP7YkIEpv/850OeRi0OCL7JFmkITtwt88vbIouCgtPnbx8XrbxEhbbgoMpM
+zQQ2yRZ9xD6lviOnmpLRkMl/ArvWy39iKqfY7huMAIezylSY+QQ5LtdV5CB21JUp
+M8FfdUkBzVxyunUY2Rg6jhpuHcwaC8lihXfcvQN9Z6SiUHAZWb7dEg/VkSI6bIIb
+qw0d8FLtcbb4IxzA6CFJcTL9kB3JjiKRAoIBAQC15t3mQHb9iCM4P4U9fpR4syvN
+46vDMhtj3vejerzOro2R7UUCJDvT59DrCQvtKO/ZCyhdTyuyResu6r1vbwq3KWiB
+i0RIeW87cKgJRr6w+KivB+a805WfI9zNRz778b7ajEpBkOs4vRPWu6S1306tdvgM
+Dhj7GT9UFh/k7pNuoSbiuaPUqgZRP55nzgj/FoIN985wnxo/ugckSqZ1bFGFXhYt
+zfIdFvPkf1BlLCnLTE8yESsJ3P37Gfj2XRv9h2I2/8qAGZniKtbVWHlu+5LDJf6V
+x9VpDAH2ZQAqRC3za3gfTjMsglYi7mUDeMYlB4osURNt7jDtElEmsto7AAkI
+-----END RSA PRIVATE KEY-----
diff --git a/usb/1.0/default/apex/com.android.hardware.usb.pk8 b/usb/1.0/default/apex/com.android.hardware.usb.pk8
new file mode 100644
index 0000000..9f3f39b
--- /dev/null
+++ b/usb/1.0/default/apex/com.android.hardware.usb.pk8
Binary files differ
diff --git a/usb/1.0/default/apex/com.android.hardware.usb.x509.pem b/usb/1.0/default/apex/com.android.hardware.usb.x509.pem
new file mode 100644
index 0000000..210c30d
--- /dev/null
+++ b/usb/1.0/default/apex/com.android.hardware.usb.x509.pem
@@ -0,0 +1,34 @@
+-----BEGIN CERTIFICATE-----
+MIIF1TCCA70CFFEdsyLGoTRk+VIzqb6aDl1tXeuZMA0GCSqGSIb3DQEBCwUAMIGl
+MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91
+bnRhaW4gVmlldzEQMA4GA1UECgwHQW5kcm9pZDEQMA4GA1UECwwHQW5kcm9pZDEi
+MCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTEhMB8GA1UEAwwYY29t
+LmFuZHJvaWQuaGFyZHdhcmUudXNiMCAXDTIxMTExNzIyMzAwM1oYDzQ3NTkxMDE0
+MjIzMDAzWjCBpTELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAU
+BgNVBAcMDU1vdW50YWluIFZpZXcxEDAOBgNVBAoMB0FuZHJvaWQxEDAOBgNVBAsM
+B0FuZHJvaWQxIjAgBgkqhkiG9w0BCQEWE2FuZHJvaWRAYW5kcm9pZC5jb20xITAf
+BgNVBAMMGGNvbS5hbmRyb2lkLmhhcmR3YXJlLnVzYjCCAiIwDQYJKoZIhvcNAQEB
+BQADggIPADCCAgoCggIBAM2E0E9ubNU/or7r9UIcFrC4l7CeM0HwtwSjTUKV1Z9K
+7rPFoUPE3cQ+cResnWQay8IGnomLYptAIMe8sLCC83LwU1ucTihxX87qq2W3V14w
+U4AkqDzNvYqKiD3yz9WofKxcu7ut8+1O4Pvp11X8UXuy5kNzf8WGpGB04k6U6KtA
+q8+U8+4h9h1Uvhaa0AeG9Yp22LzRLTb3J+eCoGHJnjoXYsd9T/gvedyXKkuf0lWB
+b3Aor3/CQrpdCW2/iJbuASdBdfilpQShaagxy2wmQsYxnT8ZWf+tIDYjg3xqqVPl
+GChFwCQBdaTuLI/k9gbaXkSxuzRkp5wc/ELhYbkhIS25yefAF2C6num++AHQBh1+
+qO0fHztsK80c5cVoDPWu17/nP7y3QloRyLFUrL3hVW1RQaFwE2Hmv4H0UwVAsleU
+ZIsz2ifTjiSl/tnkFTx0I6BVk7T87QhO3WXN4v6VDYZKeD4gQYS0NfwplahejrFw
+s3EcwKgt6f0KlIpzoEQBmNQBXxsRgL31GWCwCszb7+VrTMzgUpO41R3PyewbeaZk
+S/SHyEOwyf0WIvnZhZ/5CNd9qirClu6jS8kdLvwC2qA25VqSPw126EX1e2xUqm02
+C/6c7JDVocuQhvsJOnnpZt68Iwgw9g/xLCLA9RszH9ccRctZqRnzHB1AjTrBOq0P
+AgMBAAEwDQYJKoZIhvcNAQELBQADggIBAELbSot2Io/JZIYLTxgeReI4lk1KUzf8
+fGlDNlRm+goxOHXWQgvXgiftwM9IOB+H+EtNHAA9Q6ojAmfRe6rZC4p0ZxWOamtR
+V+pQj0c6Zvx8HJPMQdyoHx538iNXM093s2wnf+QuACb3BnvkK7uuLGAlIzWdImtL
+DKKFN05nppViY04tGP5HgT57b7YGwdkEp6euCJcyWIKjlyEH/bwTWM8ws/Px6uhw
++5W2K7KrBsdRKPBF7qwXoS8Ak8pS5de9Xd7mbGBLaUtjsZ0pJbq0aFpuT0GbLWUm
+wiD5Ljq3ea/2GZxbHGiXQ2yNjFSd/jpuxDnnm99t7+HGw1v5Jld+hUVqXXfVNhWe
+hUKIv5TOk1nttNdsaLyDtxyt22JX7NnoPM0MqrkYwA8Xqrbv0VC8D/CVjiBC9Tce
+crhpCISNfQSkdEn/c+q/naFUvQy8oYqXkg1TjeGlcxwJOpGliYbbYT6VAwuI/ssI
+yX3Fkr8f5KhfN2aFnOpidknmLp9EyL2j5bxAtSD9xAHtczMn10uCUdLELjRB1L4f
+1qY+EjpIgK0NIFuEt9K5uZXirXq3K3eixKeJFNji3x/X8NgDALSdnT8JIlSg4DMg
+iWupLrQ9CSHMlgh5P43ALamiRIHQNqEwgj8OIGzsvQTSLbRjbPWYcDZa+Q1hosiA
+Fv7vjDI6oySM
+-----END CERTIFICATE-----
diff --git a/usb/1.0/default/apex/file_contexts b/usb/1.0/default/apex/file_contexts
new file mode 100644
index 0000000..bc84ac4
--- /dev/null
+++ b/usb/1.0/default/apex/file_contexts
@@ -0,0 +1,5 @@
+(/.*)?                                         u:object_r:vendor_file:s0
+# Permission XMLs
+/etc/permissions(/.*)?                         u:object_r:vendor_configs_file:s0
+# binary
+/bin/hw/android\.hardware\.usb@1\.0-service    u:object_r:hal_usb_default_exec:s0
\ No newline at end of file
diff --git a/usb/1.0/default/apex/manifest.json b/usb/1.0/default/apex/manifest.json
new file mode 100644
index 0000000..6a1095f
--- /dev/null
+++ b/usb/1.0/default/apex/manifest.json
@@ -0,0 +1,4 @@
+{
+  "name": "com.android.hardware.usb",
+  "version": 1
+}
diff --git a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbAndroidCapabilities.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbAndroidCapabilities.aidl
index 774133e..7e3be56 100644
--- a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbAndroidCapabilities.aidl
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbAndroidCapabilities.aidl
@@ -35,4 +35,5 @@
 @Backing(type="long") @VintfStability
 enum UwbAndroidCapabilities {
   POWER_STATS_QUERY = 1,
+  ANTENNAE_INTERLEAVING = 2,
 }
diff --git a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorSessionSetAppConfigCmdParams.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorSessionSetAppConfigCmdParams.aidl
index 37b7efb..f449c60 100644
--- a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorSessionSetAppConfigCmdParams.aidl
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorSessionSetAppConfigCmdParams.aidl
@@ -38,4 +38,7 @@
   CCC_UWB_CONFIG_ID = 164,
   CCC_PULSESHAPE_COMBO = 165,
   CCC_URSK_TTL = 166,
+  NB_OF_RANGE_MEASUREMENTS = 227,
+  NB_OF_AZIMUTH_MEASUREMENTS = 228,
+  NB_OF_ELEVATION_MEASUREMENTS = 229,
 }
diff --git a/uwb/aidl/aidl_api/android.hardware.uwb/current/android/hardware/uwb/IUwbChip.aidl b/uwb/aidl/aidl_api/android.hardware.uwb/current/android/hardware/uwb/IUwbChip.aidl
index c4cb47b..c7708f1 100644
--- a/uwb/aidl/aidl_api/android.hardware.uwb/current/android/hardware/uwb/IUwbChip.aidl
+++ b/uwb/aidl/aidl_api/android.hardware.uwb/current/android/hardware/uwb/IUwbChip.aidl
@@ -40,6 +40,7 @@
   void open(in android.hardware.uwb.IUwbClientCallback clientCallback);
   void close();
   void coreInit();
+  void sessionInit(int sessionId);
   int getSupportedAndroidUciVersion();
   long getSupportedAndroidCapabilities();
   int sendUciMessage(in byte[] data);
diff --git a/uwb/aidl/android/hardware/uwb/IUwbChip.aidl b/uwb/aidl/android/hardware/uwb/IUwbChip.aidl
index 0c98611..f2bb0f1 100644
--- a/uwb/aidl/android/hardware/uwb/IUwbChip.aidl
+++ b/uwb/aidl/android/hardware/uwb/IUwbChip.aidl
@@ -50,6 +50,14 @@
     void coreInit();
 
     /**
+     * Perform any necessary UWB session initializations.
+     * This must be invoked by the framework at the beginging of every new ranging session.
+     *
+     * @param sessionId Session identifier as defined in the UCI specification.
+     */
+    void sessionInit(int sessionId);
+
+    /**
      * Supported version of vendor UCI specification.
      *
      * @return Returns the version of the "android.hardware.uwb.fira_android" types-only
diff --git a/uwb/aidl/android/hardware/uwb/fira_android/UwbAndroidCapabilities.aidl b/uwb/aidl/android/hardware/uwb/fira_android/UwbAndroidCapabilities.aidl
index 3486d5a..0af99e0 100644
--- a/uwb/aidl/android/hardware/uwb/fira_android/UwbAndroidCapabilities.aidl
+++ b/uwb/aidl/android/hardware/uwb/fira_android/UwbAndroidCapabilities.aidl
@@ -26,6 +26,6 @@
 @VintfStability
 @Backing(type="long")
 enum UwbAndroidCapabilities {
-    /** TODO: Change the name if necessary when the corresponding vendor commands are added */
     POWER_STATS_QUERY = 0x1,
+    ANTENNAE_INTERLEAVING = 0x2,
 }
diff --git a/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorSessionSetAppConfigCmdParams.aidl b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorSessionSetAppConfigCmdParams.aidl
index 850e2da..f5e02c0 100644
--- a/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorSessionSetAppConfigCmdParams.aidl
+++ b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorSessionSetAppConfigCmdParams.aidl
@@ -29,9 +29,29 @@
 enum UwbVendorSessionSetAppConfigCmdParams {
     /** CCC params for ranging start */
 
-    /** Added in vendor version 0. */
+    /**
+     * Added in vendor version 0.
+     * Range 0xA0 - 0xDF reserved for CCC use.
+     */
     CCC_RANGING_PROTOCOL_VER = 0xA3,
     CCC_UWB_CONFIG_ID = 0xA4,
     CCC_PULSESHAPE_COMBO = 0xA5,
     CCC_URSK_TTL = 0xA6,
+
+    /**
+     * Range 0xE3 - 0xFF is reserved for proprietary use in the FIRA spec.
+     * In Android, this range is reserved by the Android platform for Android-specific
+     * app config cmd params.
+     * Vendors must not define additional app config cmd params in this range.
+     */
+
+    /**
+     * Added in vendor version 0.
+     * Interleaving ratio if AOA_RESULT_REQ is set to 0xF0.
+     * Supported only if the value returned by getSupportedAndroidCapabilities()
+     * has the bit of UwbAndroidCapabilities.ANTENNAE_INTERLEAVING set to 1.
+     */
+    NB_OF_RANGE_MEASUREMENTS = 0xE3,
+    NB_OF_AZIMUTH_MEASUREMENTS = 0xE4,
+    NB_OF_ELEVATION_MEASUREMENTS = 0xE5,
 }
diff --git a/uwb/aidl/default/uwb_chip.cpp b/uwb/aidl/default/uwb_chip.cpp
index 10dbdb6..a5a3f4a 100644
--- a/uwb/aidl/default/uwb_chip.cpp
+++ b/uwb/aidl/default/uwb_chip.cpp
@@ -51,6 +51,10 @@
     return ndk::ScopedAStatus::ok();
 }
 
+::ndk::ScopedAStatus UwbChip::sessionInit(int /* sessionId */) {
+    return ndk::ScopedAStatus::ok();
+}
+
 ::ndk::ScopedAStatus UwbChip::getSupportedAndroidUciVersion(int32_t* version) {
     *version = kAndroidUciVersion;
     return ndk::ScopedAStatus::ok();
diff --git a/uwb/aidl/default/uwb_chip.h b/uwb/aidl/default/uwb_chip.h
index ca97120..46cecd4 100644
--- a/uwb/aidl/default/uwb_chip.h
+++ b/uwb/aidl/default/uwb_chip.h
@@ -37,6 +37,7 @@
     ::ndk::ScopedAStatus open(const std::shared_ptr<IUwbClientCallback>& clientCallback) override;
     ::ndk::ScopedAStatus close() override;
     ::ndk::ScopedAStatus coreInit() override;
+    ::ndk::ScopedAStatus sessionInit(int sesionId) override;
     ::ndk::ScopedAStatus getSupportedAndroidUciVersion(int32_t* version) override;
     ::ndk::ScopedAStatus getSupportedAndroidCapabilities(int64_t* capabilities) override;
     ::ndk::ScopedAStatus sendUciMessage(const std::vector<uint8_t>& data,
diff --git a/uwb/aidl/vts/VtsHalUwbTargetTest.cpp b/uwb/aidl/vts/VtsHalUwbTargetTest.cpp
index 3820c0f..1da4432 100644
--- a/uwb/aidl/vts/VtsHalUwbTargetTest.cpp
+++ b/uwb/aidl/vts/VtsHalUwbTargetTest.cpp
@@ -166,6 +166,11 @@
     EXPECT_TRUE(iuwb_chip->coreInit().isOk());
 }
 
+TEST_P(UwbAidl, ChipSessionInit) {
+    const auto iuwb_chip = getAnyChipAndOpen();
+    EXPECT_TRUE(iuwb_chip->sessionInit(0).isOk());
+}
+
 TEST_P(UwbAidl, ChipGetSupportedAndroidUciVersion) {
     const auto iuwb_chip = getAnyChipAndOpen();
     EXPECT_TRUE(iuwb_chip->coreInit().isOk());
diff --git a/vibrator/aidl/default/main.cpp b/vibrator/aidl/default/main.cpp
index bd834d2..feba2c7 100644
--- a/vibrator/aidl/default/main.cpp
+++ b/vibrator/aidl/default/main.cpp
@@ -31,14 +31,14 @@
     auto vib = ndk::SharedRefBase::make<Vibrator>();
     const std::string vibName = std::string() + Vibrator::descriptor + "/default";
     binder_status_t status = AServiceManager_addService(vib->asBinder().get(), vibName.c_str());
-    CHECK(status == STATUS_OK);
+    CHECK_EQ(status, STATUS_OK);
 
     // make the vibrator manager service with a different vibrator
     auto managedVib = ndk::SharedRefBase::make<Vibrator>();
     auto vibManager = ndk::SharedRefBase::make<VibratorManager>(std::move(managedVib));
     const std::string vibManagerName = std::string() + VibratorManager::descriptor + "/default";
     status = AServiceManager_addService(vibManager->asBinder().get(), vibManagerName.c_str());
-    CHECK(status == STATUS_OK);
+    CHECK_EQ(status, STATUS_OK);
 
     ABinderProcess_joinThreadPool();
     return EXIT_FAILURE;  // should not reach
diff --git a/weaver/aidl/default/Weaver.cpp b/weaver/aidl/default/Weaver.cpp
index 56d9c4d..6b77924 100644
--- a/weaver/aidl/default/Weaver.cpp
+++ b/weaver/aidl/default/Weaver.cpp
@@ -15,30 +15,52 @@
  */
 
 #include "Weaver.h"
+#include <array>
 
 namespace aidl {
 namespace android {
 namespace hardware {
 namespace weaver {
 
+struct Slotinfo {
+    int slot_id;
+    std::vector<uint8_t> key;
+    std::vector<uint8_t> value;
+};
+
+std::array<struct Slotinfo, 16> slot_array;
 // Methods from ::android::hardware::weaver::IWeaver follow.
 
 ::ndk::ScopedAStatus Weaver::getConfig(WeaverConfig* out_config) {
-    (void)out_config;
+    *out_config = {16, 16, 16};
     return ::ndk::ScopedAStatus::ok();
 }
 
 ::ndk::ScopedAStatus Weaver::read(int32_t in_slotId, const std::vector<uint8_t>& in_key, WeaverReadResponse* out_response) {
-    (void)in_slotId;
-    (void)in_key;
-    (void)out_response;
+
+    if (in_slotId > 15 || in_key.size() > 16) {
+        *out_response = {0, {}};
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificError(Weaver::STATUS_FAILED));
+    }
+
+    if (slot_array[in_slotId].key != in_key) {
+        *out_response = {0, {}};
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificError(Weaver::STATUS_INCORRECT_KEY));
+    }
+
+    *out_response = {0, slot_array[in_slotId].value};
+
     return ::ndk::ScopedAStatus::ok();
 }
 
 ::ndk::ScopedAStatus Weaver::write(int32_t in_slotId, const std::vector<uint8_t>& in_key, const std::vector<uint8_t>& in_value) {
-    (void)in_slotId;
-    (void)in_key;
-    (void)in_value;
+
+    if (in_slotId > 15 || in_key.size() > 16 || in_value.size() > 16)
+        return ::ndk::ScopedAStatus::fromStatus(STATUS_FAILED_TRANSACTION);
+
+    slot_array[in_slotId].key = in_key;
+    slot_array[in_slotId].value = in_value;
+
     return ::ndk::ScopedAStatus::ok();
 }
 
diff --git a/weaver/aidl/default/service.cpp b/weaver/aidl/default/service.cpp
index 1495bc9..2099ffd 100644
--- a/weaver/aidl/default/service.cpp
+++ b/weaver/aidl/default/service.cpp
@@ -28,7 +28,7 @@
 
     const std::string instance = std::string() + Weaver::descriptor + "/default";
     binder_status_t status = AServiceManager_addService(weaver->asBinder().get(), instance.c_str());
-    CHECK(status == STATUS_OK);
+    CHECK_EQ(status, STATUS_OK);
 
     ABinderProcess_joinThreadPool();
     return -1; // Should never be reached
diff --git a/wifi/netlinkinterceptor/aidl/Android.bp b/wifi/netlinkinterceptor/aidl/Android.bp
new file mode 100644
index 0000000..924edee
--- /dev/null
+++ b/wifi/netlinkinterceptor/aidl/Android.bp
@@ -0,0 +1,36 @@
+//
+// 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.net.nlinterceptor",
+    vendor_available: true,
+    srcs: ["android/hardware/net/nlinterceptor/*.aidl"],
+    stability: "vintf",
+    backend: {
+        java: {
+            enabled: false,
+        },
+    },
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/wifi/netlinkinterceptor/aidl/aidl_api/NetlinkInterceptor/current/android/hardware/net/nlinterceptor/IInterceptor.aidl
similarity index 76%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
copy to wifi/netlinkinterceptor/aidl/aidl_api/NetlinkInterceptor/current/android/hardware/net/nlinterceptor/IInterceptor.aidl
index 41a1afe..249b343 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ b/wifi/netlinkinterceptor/aidl/aidl_api/NetlinkInterceptor/current/android/hardware/net/nlinterceptor/IInterceptor.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,10 +31,11 @@
 // 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.graphics.composer3;
+package android.hardware.net.nlinterceptor;
 @VintfStability
-parcelable ExecuteCommandsStatus {
-  boolean queueChanged;
-  int length;
-  android.hardware.common.NativeHandle[] handles;
+interface IInterceptor {
+  int createSocket(in int nlFamily, in int clientNlPid, in String clientName);
+  void closeSocket(in int nlFamily, in int interceptorNlPid);
+  void subscribeGroup(in int nlFamily, in int interceptorNlPid, in int nlGroup);
+  void unsubscribeGroup(in int nlFamily, in int interceptorNlPid, in int nlGroup);
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/wifi/netlinkinterceptor/aidl/aidl_api/android.hardware.net.nlinterceptor/current/android/hardware/net/nlinterceptor/IInterceptor.aidl
similarity index 72%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
copy to wifi/netlinkinterceptor/aidl/aidl_api/android.hardware.net.nlinterceptor/current/android/hardware/net/nlinterceptor/IInterceptor.aidl
index 41a1afe..3d0f955 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ b/wifi/netlinkinterceptor/aidl/aidl_api/android.hardware.net.nlinterceptor/current/android/hardware/net/nlinterceptor/IInterceptor.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,10 +31,11 @@
 // 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.graphics.composer3;
+package android.hardware.net.nlinterceptor;
 @VintfStability
-parcelable ExecuteCommandsStatus {
-  boolean queueChanged;
-  int length;
-  android.hardware.common.NativeHandle[] handles;
+interface IInterceptor {
+  android.hardware.net.nlinterceptor.InterceptedSocket createSocket(in int nlFamily, in int clientNlPid, in String clientName);
+  void closeSocket(in android.hardware.net.nlinterceptor.InterceptedSocket handle);
+  void subscribeGroup(in android.hardware.net.nlinterceptor.InterceptedSocket handle, in int nlGroup);
+  void unsubscribeGroup(in android.hardware.net.nlinterceptor.InterceptedSocket handle, in int nlGroup);
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl b/wifi/netlinkinterceptor/aidl/aidl_api/android.hardware.net.nlinterceptor/current/android/hardware/net/nlinterceptor/InterceptedSocket.aidl
similarity index 86%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
copy to wifi/netlinkinterceptor/aidl/aidl_api/android.hardware.net.nlinterceptor/current/android/hardware/net/nlinterceptor/InterceptedSocket.aidl
index cfafc50..b679be5 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/wifi/netlinkinterceptor/aidl/aidl_api/android.hardware.net.nlinterceptor/current/android/hardware/net/nlinterceptor/InterceptedSocket.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,8 +31,9 @@
 // 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.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum LayerRequest {
-  CLEAR_CLIENT_TARGET = 1,
+package android.hardware.net.nlinterceptor;
+@VintfStability
+parcelable InterceptedSocket {
+  int nlFamily;
+  int portId;
 }
diff --git a/wifi/netlinkinterceptor/aidl/android/hardware/net/nlinterceptor/IInterceptor.aidl b/wifi/netlinkinterceptor/aidl/android/hardware/net/nlinterceptor/IInterceptor.aidl
new file mode 100644
index 0000000..c222a1e
--- /dev/null
+++ b/wifi/netlinkinterceptor/aidl/android/hardware/net/nlinterceptor/IInterceptor.aidl
@@ -0,0 +1,78 @@
+/*
+ * 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.net.nlinterceptor;
+
+import android.hardware.net.nlinterceptor.InterceptedSocket;
+
+/**
+ * Netlink Interceptor
+ *
+ * This HAL provides a way for Android services to route their Netlink traffic to a location other
+ * than the Kernel. One might want to do this for a variety of reasons:
+ * -> Route Netlink traffic to a different host.
+ * -> Route Netlink traffic to a different VM.
+ * -> Convert Netlink commands into proprietary vendor hardware commands.
+ *
+ * Some important notes regarding Netlink Interceptor.
+ * -> All int values are treated as unsigned.
+ * -> Users of Netlink Interceptor must close their sockets with closeSocket manually.
+ * -> PID != process ID. In this case, it is "port ID", a unique number assigned by the kernel to a
+ *    given Netlink socket.
+ * -> Netlink PIDs are only unique per family. This means that for all NETLINK_GENERIC sockets,
+ *    there can only be one socket with PID "1234". HOWEVER, there can ALSO be a Netlink socket
+ *    using NETLINK_ROUTE which has a PID of "1234". Hence, in order to uniquely identify a Netlink
+ *    socket, both the PID and Netlink Family are required.
+ */
+@VintfStability
+interface IInterceptor {
+    /**
+     * Creates a Netlink socket on both the HU and TCU, and a bi-directional gRPC stream to carry
+     * data between them. This must be closed by the caller with closeSocket().
+     *
+     * @param nlFamily - Netlink Family. Support for families other than NETLINK_GENERIC is still
+     * experimental.
+     * @param clientNlPid - Port ID of the caller's Netlink socket.
+     * @param clientName - Human readable name of the caller. Used for debugging.
+     *
+     * @return InterceptedSocket identifying the socket on the HU allocated for the caller.
+     */
+    InterceptedSocket createSocket(in int nlFamily, in int clientNlPid, in String clientName);
+
+    /**
+     * Closes a socket and gRPC stream given the socket's identifier. This must be invoked manually
+     * by the caller of createSocket().
+     *
+     * @param handle - unique identifier for a socket returned by createSocket.
+     */
+    void closeSocket(in InterceptedSocket handle);
+
+    /**
+     * Subscribes a socket on the TCU to a Netlink multicast group.
+     *
+     * @param handle - unique identifier for a socket returned by createSocket.
+     * @param nlGroup - A single Netlink multicast group that the caller wants to subscribe to.
+     */
+    void subscribeGroup(in InterceptedSocket handle, in int nlGroup);
+
+    /**
+     * Unsubscribes a socket on the TCU from a Netlink multicast group.
+     *
+     * @param handle - unique identifier for a socket returned by createSocket.
+     * @param nlGroup - A single Netlink multicast group that the caller wants to unsubscribe from.
+     */
+    void unsubscribeGroup(in InterceptedSocket handle, in int nlGroup);
+}
diff --git a/wifi/netlinkinterceptor/aidl/android/hardware/net/nlinterceptor/InterceptedSocket.aidl b/wifi/netlinkinterceptor/aidl/android/hardware/net/nlinterceptor/InterceptedSocket.aidl
new file mode 100644
index 0000000..d74a556
--- /dev/null
+++ b/wifi/netlinkinterceptor/aidl/android/hardware/net/nlinterceptor/InterceptedSocket.aidl
@@ -0,0 +1,33 @@
+/*
+ * 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.net.nlinterceptor;
+
+/**
+ * Unique identifier for a Netlink socket.
+ */
+@VintfStability
+parcelable InterceptedSocket {
+    /**
+     * Netlink family of the identified socket
+     */
+    int nlFamily;
+
+    /**
+     * Netlink port ID of the identified socket.
+     */
+    int portId;
+}
diff --git a/wifi/netlinkinterceptor/aidl/default/Android.bp b/wifi/netlinkinterceptor/aidl/default/Android.bp
new file mode 100644
index 0000000..5227e51
--- /dev/null
+++ b/wifi/netlinkinterceptor/aidl/default/Android.bp
@@ -0,0 +1,48 @@
+//
+// 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.net.nlinterceptor-service.default",
+    init_rc: ["nlinterceptor-default.rc"],
+    vintf_fragments: ["nlinterceptor-default.xml"],
+    vendor: true,
+    relative_install_path: "hw",
+    defaults: ["nlinterceptor@defaults"],
+    shared_libs: [
+        "android.hardware.net.nlinterceptor-V1-ndk",
+        "libbase",
+        "libbinder_ndk",
+    ],
+    static_libs: [
+        "libnlinterceptor",
+        "libnl++",
+    ],
+    srcs: [
+        "InterceptorRelay.cpp",
+        "NetlinkInterceptor.cpp",
+        "service.cpp",
+        "util.cpp",
+    ],
+}
diff --git a/wifi/netlinkinterceptor/aidl/default/InterceptorRelay.cpp b/wifi/netlinkinterceptor/aidl/default/InterceptorRelay.cpp
new file mode 100644
index 0000000..ded9122
--- /dev/null
+++ b/wifi/netlinkinterceptor/aidl/default/InterceptorRelay.cpp
@@ -0,0 +1,129 @@
+/*
+ * 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 "InterceptorRelay.h"
+
+#include <android-base/logging.h>
+#include <libnl++/printer.h>
+#include <poll.h>
+
+#include <chrono>
+
+#include "util.h"
+
+namespace android::nlinterceptor {
+using namespace std::chrono_literals;
+
+static constexpr std::chrono::milliseconds kPollTimeout = 300ms;
+static constexpr bool kSuperVerbose = true;
+
+InterceptorRelay::InterceptorRelay(uint32_t nlFamily, uint32_t clientNlPid,
+                                   const std::string& clientName)
+    : mClientName(clientName),
+      mNlSocket(std::make_optional<nl::Socket>(nlFamily, 0, 0)),
+      mClientNlPid(clientNlPid) {}
+
+InterceptorRelay::~InterceptorRelay() {
+    mRunning = false;
+    if (mRelayThread.joinable()) mRelayThread.join();
+}
+
+uint32_t InterceptorRelay::getPid() {
+    auto pidMaybe = mNlSocket->getPid();
+    CHECK(pidMaybe.has_value()) << "Failed to get pid of nl::Socket!";
+    return *pidMaybe;
+}
+
+void InterceptorRelay::relayMessages() {
+    pollfd fds[] = {
+        mNlSocket->preparePoll(POLLIN),
+    };
+    while (mRunning) {
+        if (poll(fds, countof(fds), kPollTimeout.count()) < 0) {
+            PLOG(FATAL) << "poll failed";
+            return;
+        }
+        const auto nlsockEvents = fds[0].revents;
+
+        if (isSocketBad(nlsockEvents)) {
+            LOG(ERROR) << "Netlink socket is bad";
+            mRunning = false;
+            return;
+        }
+        if (!isSocketReadable(nlsockEvents)) continue;
+
+        const auto [msgMaybe, sa] = mNlSocket->receiveFrom();
+        if (!msgMaybe.has_value()) {
+            LOG(ERROR) << "Failed to receive Netlink data!";
+            mRunning = false;
+            return;
+        }
+        const auto msg = *msgMaybe;
+        if (!msg.firstOk()) {
+            LOG(ERROR) << "Netlink packet is malformed!";
+            // Test messages might be empty, this isn't fatal.
+            continue;
+        }
+        if constexpr (kSuperVerbose) {
+            LOG(VERBOSE) << "[" << mClientName
+                         << "] nlMsg: " << nl::toString(msg, NETLINK_GENERIC);
+        }
+
+        uint32_t destinationPid = 0;
+        if (sa.nl_pid == 0) {
+            destinationPid = mClientNlPid;
+        }
+
+        if (!mNlSocket->send(msg, destinationPid)) {
+            LOG(ERROR) << "Failed to send Netlink message!";
+            mRunning = false;
+            return;
+        }
+    }
+    LOG(VERBOSE) << "[" << mClientName << "] Exiting relay thread!";
+}
+
+bool InterceptorRelay::start() {
+    if (mRunning) {
+        LOG(ERROR)
+            << "Can't relay messages: InterceptorRelay is already running!";
+        return false;
+    }
+    if (mRelayThread.joinable()) {
+        LOG(ERROR) << "relay thread is already running!";
+        return false;
+    }
+    if (!mNlSocket.has_value()) {
+        LOG(ERROR) << "Netlink socket not initialized!";
+        return false;
+    }
+
+    mRunning = true;
+    mRelayThread = std::thread(&InterceptorRelay::relayMessages, this);
+
+    LOG(VERBOSE) << "Relay threads initialized";
+    return true;
+}
+
+bool InterceptorRelay::subscribeGroup(uint32_t nlGroup) {
+    return mNlSocket->addMembership(nlGroup);
+}
+
+bool InterceptorRelay::unsubscribeGroup(uint32_t nlGroup) {
+    return mNlSocket->dropMembership(nlGroup);
+}
+
+}  // namespace android::nlinterceptor
diff --git a/wifi/netlinkinterceptor/aidl/default/InterceptorRelay.h b/wifi/netlinkinterceptor/aidl/default/InterceptorRelay.h
new file mode 100644
index 0000000..0178c90
--- /dev/null
+++ b/wifi/netlinkinterceptor/aidl/default/InterceptorRelay.h
@@ -0,0 +1,93 @@
+/*
+ * 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 <libnl++/Socket.h>
+
+#include <mutex>
+#include <thread>
+
+namespace android::nlinterceptor {
+
+class InterceptorRelay {
+   public:
+    /**
+     * Wrapper around the netlink socket and thread which relays messages.
+     *
+     * \param nlFamily - netlink family to use for the netlink socket.
+     * \param clientNlPid - pid of the client netlink socket.
+     * \param clientName - name of the client to be used for debugging.
+     */
+    InterceptorRelay(uint32_t nlFamily, uint32_t clientNlPid,
+                     const std::string& clientName);
+
+    /**
+     * Stops the relay thread if running and destroys itself.
+     */
+    ~InterceptorRelay();
+
+    /**
+     * Returns the PID of the internal Netlink socket.
+     *
+     * \return value of PID,
+     */
+    uint32_t getPid();
+
+    /**
+     * Spawns relay thread.
+     */
+    bool start();
+
+    /**
+     * Subscribes the internal socket to a single Netlink multicast group.
+     *
+     * \param nlGroup - Netlink group to subscribe to.
+     * \returns - true for success, false for failure.
+     */
+    bool subscribeGroup(uint32_t nlGroup);
+
+    /**
+     * Unsubscribes the internal socket from a single Netlink multicast group.
+     *
+     * \param nlGroup - Netlink group to unsubscribe from.
+     * \returns - true for success, false for failure.
+     */
+    bool unsubscribeGroup(uint32_t nlGroup);
+
+   private:
+    std::string mClientName;  ///< Name of client (Wificond, for example).
+    std::optional<nl::Socket> mNlSocket;
+    const uint32_t mClientNlPid = 0;  ///< pid of client NL socket.
+
+    /**
+     * If set to true, the relay thread should be running. Setting this to false
+     * stops the relay thread.
+     */
+    std::atomic_bool mRunning = false;
+
+    /**
+     * Reads incoming Netlink messages destined for mNlSocket. If from the
+     * kernel, the message is relayed to the client specified in the
+     * constructor. Otherwise, the message is relayed to the kernel. This will
+     * run as long as mRunning is set to true.
+     */
+    void relayMessages();
+
+    std::thread mRelayThread;
+};
+
+}  // namespace android::nlinterceptor
diff --git a/wifi/netlinkinterceptor/aidl/default/NetlinkInterceptor.cpp b/wifi/netlinkinterceptor/aidl/default/NetlinkInterceptor.cpp
new file mode 100644
index 0000000..908ecf2
--- /dev/null
+++ b/wifi/netlinkinterceptor/aidl/default/NetlinkInterceptor.cpp
@@ -0,0 +1,121 @@
+/*
+ * 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 "NetlinkInterceptor.h"
+
+#include <android-base/logging.h>
+#include <libnl++/Socket.h>
+
+namespace android::nlinterceptor {
+
+ndk::ScopedAStatus NetlinkInterceptor::createSocket(
+    int32_t nlFamilyAidl, int32_t clientNlPidAidl,
+    const std::string& clientName, AidlInterceptedSocket* interceptedSocket) {
+    auto nlFamily = static_cast<uint32_t>(nlFamilyAidl);
+    auto clientNlPid = static_cast<uint32_t>(clientNlPidAidl);
+    uint32_t interceptorNlPid = 0;
+
+    std::unique_ptr<InterceptorRelay> interceptor =
+        std::make_unique<InterceptorRelay>(nlFamily, clientNlPid, clientName);
+
+    interceptorNlPid = interceptor->getPid();
+
+    if (interceptorNlPid == 0) {
+        LOG(ERROR) << "Failed to create a Netlink socket for " << clientName
+                   << ", " << nlFamily << ":" << clientNlPid;
+        return ndk::ScopedAStatus(AStatus_fromStatus(::android::UNKNOWN_ERROR));
+    }
+
+    if (mClientMap.find({nlFamily, interceptorNlPid}) != mClientMap.end()) {
+        LOG(ERROR) << "A socket with pid " << interceptorNlPid
+                   << " already exists!";
+        return ndk::ScopedAStatus(AStatus_fromStatus(::android::UNKNOWN_ERROR));
+    }
+
+    if (!interceptor->start()) {
+        LOG(ERROR) << "Failed to start interceptor thread!";
+        return ndk::ScopedAStatus(AStatus_fromStatus(::android::UNKNOWN_ERROR));
+    }
+
+    if (!mClientMap
+             .emplace(InterceptedSocket(nlFamily, interceptorNlPid),
+                      std::move(interceptor))
+             .second) {
+        // If this happens, it is very bad.
+        LOG(FATAL) << "Failed to insert interceptor instance with pid "
+                   << interceptorNlPid << " into map!";
+        return ndk::ScopedAStatus(AStatus_fromStatus(::android::UNKNOWN_ERROR));
+    }
+
+    interceptedSocket->nlFamily = nlFamily;
+    interceptedSocket->portId = interceptorNlPid;
+
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus NetlinkInterceptor::closeSocket(
+    const AidlInterceptedSocket& interceptedSocket) {
+    InterceptedSocket sock(interceptedSocket);
+
+    auto interceptorIt = mClientMap.find(sock);
+    if (interceptorIt == mClientMap.end()) {
+        LOG(ERROR) << "closeSocket Failed! No such socket " << sock;
+        return ndk::ScopedAStatus(AStatus_fromStatus(::android::UNKNOWN_ERROR));
+    }
+    mClientMap.erase(interceptorIt);
+
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus NetlinkInterceptor::subscribeGroup(
+    const AidlInterceptedSocket& interceptedSocket, int32_t nlGroupAidl) {
+    InterceptedSocket sock(interceptedSocket);
+    auto nlGroup = static_cast<uint32_t>(nlGroupAidl);
+
+    auto interceptorIt = mClientMap.find(sock);
+    if (interceptorIt == mClientMap.end()) {
+        LOG(ERROR) << "subscribeGroup failed! No such socket " << sock;
+        return ndk::ScopedAStatus(AStatus_fromStatus(::android::UNKNOWN_ERROR));
+    }
+
+    auto& interceptor = interceptorIt->second;
+    if (!interceptor->subscribeGroup(nlGroup)) {
+        LOG(ERROR) << "Failed to subscribe " << sock << " to " << nlGroup;
+        return ndk::ScopedAStatus(AStatus_fromStatus(::android::UNKNOWN_ERROR));
+    }
+
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus NetlinkInterceptor::unsubscribeGroup(
+    const AidlInterceptedSocket& interceptedSocket, int32_t nlGroupAidl) {
+    InterceptedSocket sock(interceptedSocket);
+    auto nlGroup = static_cast<uint32_t>(nlGroupAidl);
+
+    auto interceptorIt = mClientMap.find(sock);
+    if (interceptorIt == mClientMap.end()) {
+        LOG(ERROR) << "unsubscribeGroup failed! No such socket " << sock;
+        return ndk::ScopedAStatus(AStatus_fromStatus(::android::UNKNOWN_ERROR));
+    }
+
+    auto& interceptor = interceptorIt->second;
+    if (!interceptor->unsubscribeGroup(nlGroup)) {
+        LOG(ERROR) << "Failed to unsubscribe " << sock << " from " << nlGroup;
+        return ndk::ScopedAStatus(AStatus_fromStatus(::android::UNKNOWN_ERROR));
+    }
+    return ndk::ScopedAStatus::ok();
+}
+}  // namespace android::nlinterceptor
diff --git a/wifi/netlinkinterceptor/aidl/default/NetlinkInterceptor.h b/wifi/netlinkinterceptor/aidl/default/NetlinkInterceptor.h
new file mode 100644
index 0000000..8345654
--- /dev/null
+++ b/wifi/netlinkinterceptor/aidl/default/NetlinkInterceptor.h
@@ -0,0 +1,57 @@
+/*
+ * 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 <aidl/android/hardware/net/nlinterceptor/BnInterceptor.h>
+#include <libnlinterceptor/libnlinterceptor.h>
+
+#include <map>
+
+#include "InterceptorRelay.h"
+
+namespace android::nlinterceptor {
+
+class NetlinkInterceptor
+    : public ::aidl::android::hardware::net::nlinterceptor::BnInterceptor {
+    using ClientMap =
+        std::map<::android::nlinterceptor::InterceptedSocket,
+                 std::unique_ptr<::android::nlinterceptor::InterceptorRelay>>;
+
+    using AidlInterceptedSocket =
+        ::aidl::android::hardware::net::nlinterceptor::InterceptedSocket;
+
+   public:
+    ndk::ScopedAStatus createSocket(
+        int32_t nlFamily, int32_t clientNlPid, const std::string& clientName,
+        AidlInterceptedSocket* interceptedSocket) override;
+
+    ndk::ScopedAStatus closeSocket(
+        const AidlInterceptedSocket& interceptedSocket) override;
+
+    ndk::ScopedAStatus subscribeGroup(
+        const AidlInterceptedSocket& interceptedSocket,
+        int32_t nlGroup) override;
+
+    ndk::ScopedAStatus unsubscribeGroup(
+        const AidlInterceptedSocket& interceptedSocket,
+        int32_t nlGroup) override;
+
+   private:
+    ClientMap mClientMap;
+};
+
+}  // namespace android::nlinterceptor
diff --git a/wifi/netlinkinterceptor/aidl/default/OWNERS b/wifi/netlinkinterceptor/aidl/default/OWNERS
new file mode 100644
index 0000000..b738dac
--- /dev/null
+++ b/wifi/netlinkinterceptor/aidl/default/OWNERS
@@ -0,0 +1,2 @@
+chrisweir@google.com
+twasilczyk@google.com
diff --git a/wifi/netlinkinterceptor/aidl/default/nlinterceptor-default.rc b/wifi/netlinkinterceptor/aidl/default/nlinterceptor-default.rc
new file mode 100644
index 0000000..353cb27
--- /dev/null
+++ b/wifi/netlinkinterceptor/aidl/default/nlinterceptor-default.rc
@@ -0,0 +1,4 @@
+service nlinterceptor /vendor/bin/hw/android.hardware.net.nlinterceptor-service.default
+    class hal
+    user root
+    group system inet
diff --git a/wifi/netlinkinterceptor/aidl/default/nlinterceptor-default.xml b/wifi/netlinkinterceptor/aidl/default/nlinterceptor-default.xml
new file mode 100644
index 0000000..d7d257e
--- /dev/null
+++ b/wifi/netlinkinterceptor/aidl/default/nlinterceptor-default.xml
@@ -0,0 +1,9 @@
+<manifest version="1.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.net.nlinterceptor</name>
+        <interface>
+            <name>IInterceptor</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+</manifest>
diff --git a/wifi/netlinkinterceptor/aidl/default/service.cpp b/wifi/netlinkinterceptor/aidl/default/service.cpp
new file mode 100644
index 0000000..2aec3a5
--- /dev/null
+++ b/wifi/netlinkinterceptor/aidl/default/service.cpp
@@ -0,0 +1,47 @@
+/*
+ * 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 "NetlinkInterceptor.h"
+
+namespace android::nlinterceptor {
+using namespace std::string_literals;
+
+static void service() {
+    base::SetDefaultTag("nlinterceptor");
+    base::SetMinimumLogSeverity(base::VERBOSE);
+    LOG(DEBUG) << "Netlink Interceptor service starting...";
+
+    // TODO(202549296): Sometimes this causes an Address Sanitizer error.
+    auto interceptor = ndk::SharedRefBase::make<NetlinkInterceptor>();
+    const auto instance = NetlinkInterceptor::descriptor + "/default"s;
+    const auto status = AServiceManager_addService(
+        interceptor->asBinder().get(), instance.c_str());
+    CHECK(status == STATUS_OK);
+
+    ABinderProcess_joinThreadPool();
+    LOG(FATAL) << "Netlink Interceptor has stopped";
+}
+
+}  // namespace android::nlinterceptor
+
+int main() {
+    ::android::nlinterceptor::service();
+    return 0;
+}
diff --git a/wifi/netlinkinterceptor/aidl/default/util.cpp b/wifi/netlinkinterceptor/aidl/default/util.cpp
new file mode 100644
index 0000000..c734747
--- /dev/null
+++ b/wifi/netlinkinterceptor/aidl/default/util.cpp
@@ -0,0 +1,29 @@
+/*
+ * 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 "util.h"
+
+#include <poll.h>
+
+namespace android::nlinterceptor {
+
+bool isSocketReadable(const short revents) { return 0 != (revents & POLLIN); }
+
+bool isSocketBad(const short revents) {
+    return 0 != (revents & (POLLERR | POLLHUP | POLLNVAL));
+}
+
+}  // namespace android::nlinterceptor
diff --git a/wifi/netlinkinterceptor/aidl/default/util.h b/wifi/netlinkinterceptor/aidl/default/util.h
new file mode 100644
index 0000000..9b8ec63
--- /dev/null
+++ b/wifi/netlinkinterceptor/aidl/default/util.h
@@ -0,0 +1,52 @@
+/*
+ * 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/macros.h>
+
+#include <functional>
+
+namespace android::nlinterceptor {
+
+/**
+ * Handy-dandy helper to get the size of a statically initialized array.
+ *
+ * \param N the array to get the size of.
+ * \return the size of the array.
+ */
+template <typename T, size_t N>
+size_t countof(T (&)[N]) {
+    return N;
+}
+
+/**
+ * Helper to check if socket is readable (POLLIN is set).
+ *
+ * \param revents pollfd.revents value to check.
+ * \return true if socket is ready to read.
+ */
+bool isSocketReadable(short revents);
+
+/**
+ * Helper to check if socket is bad (POLLERR, POLLHUP or POLLNVAL is set).
+ *
+ * \param revents pollfd.revents value to check.
+ * \return true if socket is bad.
+ */
+bool isSocketBad(short revents);
+
+}  // namespace android::nlinterceptor
diff --git a/wifi/netlinkinterceptor/libnlinterceptor/Android.bp b/wifi/netlinkinterceptor/libnlinterceptor/Android.bp
new file mode 100644
index 0000000..00cae32
--- /dev/null
+++ b/wifi/netlinkinterceptor/libnlinterceptor/Android.bp
@@ -0,0 +1,65 @@
+//
+// 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_defaults {
+    name: "nlinterceptor@defaults",
+    cpp_std: "experimental",
+    cflags: [
+        "-Wall",
+        "-Wextra",
+        "-Wsuggest-override",
+        "-Werror",
+    ],
+    shared_libs: [
+        "libbase",
+        "libutils",
+    ],
+    sanitize: {
+        address: true,
+        undefined: true,
+        all_undefined: true,
+        fuzzer: true,
+        cfi: true,
+        integer_overflow: true,
+        scs: true,
+    },
+    strip: {
+        keep_symbols_and_debug_frame: true,
+    },
+}
+
+cc_library_static {
+    name: "libnlinterceptor",
+    defaults: ["nlinterceptor@defaults"],
+    vendor_available: true,
+    shared_libs: [
+        "android.hardware.net.nlinterceptor-V1-ndk",
+        "libbinder_ndk",
+    ],
+    srcs: [
+        "libnlinterceptor.cpp",
+    ],
+    export_include_dirs: ["include"],
+}
diff --git a/wifi/netlinkinterceptor/libnlinterceptor/include/libnlinterceptor/libnlinterceptor.h b/wifi/netlinkinterceptor/libnlinterceptor/include/libnlinterceptor/libnlinterceptor.h
new file mode 100644
index 0000000..ac8653e
--- /dev/null
+++ b/wifi/netlinkinterceptor/libnlinterceptor/include/libnlinterceptor/libnlinterceptor.h
@@ -0,0 +1,131 @@
+/*
+ * 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
+
+#ifdef __cplusplus
+
+#include <aidl/android/hardware/net/nlinterceptor/InterceptedSocket.h>
+#include <android-base/unique_fd.h>
+#include <linux/netlink.h>
+
+#include <optional>
+#include <string>
+
+namespace android::nlinterceptor {
+
+/**
+ * Wrapper structure to uniquely identifies a socket that Netlink Interceptor
+ * has allocated for us.
+ */
+struct InterceptedSocket {
+    uint32_t nlFamily;
+    uint32_t portId;
+
+    InterceptedSocket(
+        ::aidl::android::hardware::net::nlinterceptor::InterceptedSocket sock);
+    InterceptedSocket(uint32_t nlFamily, uint32_t portId);
+
+    bool operator<(const InterceptedSocket& other) const;
+    operator sockaddr_nl() const;
+    operator ::aidl::android::hardware::net::nlinterceptor::InterceptedSocket()
+        const;
+};
+
+/**
+ * Output stream operator for InterceptedSocket
+ */
+std::ostream& operator<<(std::ostream& os, const InterceptedSocket& sock);
+
+/**
+ * Checks if an instance Netlink Interceptor exists.
+ *
+ * \return true if supported, false if not.
+ */
+bool isEnabled();
+
+/**
+ * Asks Netlink Interceptor to allocate a socket to which we can send Netlink
+ * traffic.
+ *
+ * \param clientSocket - File descriptor for the client's Netlink socket.
+ * \param clientName - Human readable name of the client application.
+ * \return Identifier for the socket created by Netlink Interceptor, nullopt on
+ * error.
+ */
+std::optional<InterceptedSocket> createSocket(base::borrowed_fd clientSocket,
+                                              const std::string& clientName);
+
+/**
+ * Asks Netlink Interceptor to close a socket that it created for us previously,
+ * if it exists.
+ *
+ * \param sock - Identifier for the socket created by Netlink Interceptor.
+ */
+void closeSocket(const InterceptedSocket& sock);
+
+/**
+ * Asks Netlink Interceptor to subscribe a socket that it created for us
+ * previously to a specified multicast group.
+ *
+ * \param sock - Identifier for the socket created by Netlink Interceptor.
+ * \param group - A single Netlink multicast group for which we would like to
+ * receive events.
+ * \return true for success, false if something went wrong.
+ */
+bool subscribe(const InterceptedSocket& sock, uint32_t group);
+
+/**
+ * Asks Netlink Interceptor to unsubscribe a socket that it created for us
+ * previously from a specified multicast group.
+ *
+ * \param sock - Identifier for the socket created by Netlink Interceptor.
+ * \param group - A single Netlink multicast group for which we no longer wish
+ * to receive events.
+ * \return true for success, false if something went wrong.
+ */
+bool unsubscribe(const InterceptedSocket& sock, uint32_t group);
+}  // namespace android::nlinterceptor
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// C wrappers for libnlinterceptor
+struct android_nlinterceptor_InterceptedSocket {
+    uint32_t nlFamily;
+    uint32_t portId;
+};
+
+bool android_nlinterceptor_isEnabled();
+
+bool android_nlinterceptor_createSocket(
+    int clientSocketFd, const char* clientName,
+    struct android_nlinterceptor_InterceptedSocket* interceptedSocket);
+
+void android_nlinterceptor_closeSocket(
+    const struct android_nlinterceptor_InterceptedSocket* sock);
+
+bool android_nlinterceptor_subscribe(
+    const struct android_nlinterceptor_InterceptedSocket* sock, uint32_t group);
+
+bool android_nlinterceptor_unsubscribe(
+    const struct android_nlinterceptor_InterceptedSocket* sock, uint32_t group);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/wifi/netlinkinterceptor/libnlinterceptor/libnlinterceptor.cpp b/wifi/netlinkinterceptor/libnlinterceptor/libnlinterceptor.cpp
new file mode 100644
index 0000000..575f900
--- /dev/null
+++ b/wifi/netlinkinterceptor/libnlinterceptor/libnlinterceptor.cpp
@@ -0,0 +1,174 @@
+/*
+ * 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 <aidl/android/hardware/net/nlinterceptor/IInterceptor.h>
+#include <android-base/logging.h>
+#include <android-base/macros.h>
+#include <android/binder_manager.h>
+#include <libnlinterceptor/libnlinterceptor.h>
+#include <linux/netlink.h>
+
+#include <mutex>
+
+namespace android::nlinterceptor {
+using namespace std::string_literals;
+using namespace ::aidl::android::hardware::net::nlinterceptor;
+using base::borrowed_fd;
+using AidlInterceptedSocket =
+    ::aidl::android::hardware::net::nlinterceptor::InterceptedSocket;
+
+static const auto kServiceName = IInterceptor::descriptor + "/default"s;
+
+InterceptedSocket::InterceptedSocket(
+    ::aidl::android::hardware::net::nlinterceptor::InterceptedSocket sock)
+    : nlFamily(sock.nlFamily), portId(sock.portId) {}
+
+InterceptedSocket::InterceptedSocket(uint32_t nlFamily, uint32_t portId)
+    : nlFamily(nlFamily), portId(portId) {}
+
+std::ostream& operator<<(std::ostream& os, const InterceptedSocket& sock) {
+    return os << "family: " << sock.nlFamily << ", portId: " << sock.portId;
+}
+
+bool InterceptedSocket::operator<(const InterceptedSocket& other) const {
+    if (nlFamily != other.nlFamily) {
+        return nlFamily < other.nlFamily;
+    }
+    return portId < other.portId;
+}
+
+InterceptedSocket::operator sockaddr_nl() const {
+    return {
+        .nl_family = AF_NETLINK,
+        .nl_pad = 0,
+        .nl_pid = portId,
+        .nl_groups = 0,
+    };
+}
+
+InterceptedSocket::operator AidlInterceptedSocket() const {
+    return {
+        .nlFamily = static_cast<int32_t>(nlFamily),
+        .portId = static_cast<int32_t>(portId),
+    };
+}
+
+bool isEnabled() {
+    static std::mutex supportedMutex;
+    static std::optional<bool> interceptorSupported;
+    // Avoid querying service manager when we can cache the result.
+    if (interceptorSupported.has_value()) return *interceptorSupported;
+    std::lock_guard lock(supportedMutex);
+    if (interceptorSupported.has_value()) return *interceptorSupported;
+
+    if (!AServiceManager_isDeclared(kServiceName.c_str())) {
+        interceptorSupported = false;
+        return false;
+    }
+    interceptorSupported = true;
+    return true;
+}
+
+static IInterceptor& getInstance() {
+    static std::mutex instanceMutex;
+    static std::shared_ptr<IInterceptor> interceptorInstance;
+    CHECK(isEnabled()) << "Can't getInstance! Interceptor not supported!";
+    // Don't overwrite the pointer once we've acquired it.
+    if (interceptorInstance != nullptr) return *interceptorInstance;
+    std::lock_guard lock(instanceMutex);
+    if (interceptorInstance != nullptr) return *interceptorInstance;
+    interceptorInstance = IInterceptor::fromBinder(
+        ndk::SpAIBinder(AServiceManager_waitForService(kServiceName.c_str())));
+    CHECK(interceptorInstance != nullptr)
+        << "Failed to get Netlink Interceptor service!";
+    return *interceptorInstance;
+}
+
+std::optional<InterceptedSocket> createSocket(borrowed_fd clientSocket,
+                                              const std::string& clientName) {
+    sockaddr_nl nladdr = {};
+    socklen_t nlsize = sizeof(nladdr);
+    if (getsockname(clientSocket.get(), reinterpret_cast<sockaddr*>(&nladdr),
+                    &nlsize) < 0) {
+        PLOG(ERROR) << "Failed to get pid of fd passed by " << clientName;
+        return std::nullopt;
+    }
+
+    ::aidl::android::hardware::net::nlinterceptor::InterceptedSocket
+        interceptedSocket;
+    auto aidlStatus = getInstance().createSocket(
+        nladdr.nl_family, nladdr.nl_pid, clientName, &interceptedSocket);
+    if (!aidlStatus.isOk()) {
+        return std::nullopt;
+    }
+
+    return InterceptedSocket{nladdr.nl_family,
+                             uint32_t(interceptedSocket.portId)};
+}
+
+void closeSocket(const InterceptedSocket& sock) {
+    auto aidlStatus = getInstance().closeSocket(sock);
+    if (!aidlStatus.isOk()) {
+        LOG(ERROR) << "Failed to close socket with pid = " << sock.portId;
+    }
+}
+
+bool subscribe(const InterceptedSocket& sock, uint32_t group) {
+    auto aidlStatus = getInstance().subscribeGroup(sock, group);
+    return aidlStatus.isOk();
+}
+
+bool unsubscribe(const InterceptedSocket& sock, uint32_t group) {
+    auto aidlStatus = getInstance().unsubscribeGroup(sock, group);
+    return aidlStatus.isOk();
+}
+
+extern "C" bool android_nlinterceptor_isEnabled() { return isEnabled(); }
+
+extern "C" bool android_nlinterceptor_createSocket(
+    int clientSocketFd, const char* clientName,
+    android_nlinterceptor_InterceptedSocket* interceptedSocket) {
+    if (!clientName || clientSocketFd <= 0) return false;
+    const auto maybeSocket =
+        createSocket(borrowed_fd(clientSocketFd), clientName);
+    if (!maybeSocket) return false;
+    *interceptedSocket = {.nlFamily = maybeSocket->nlFamily,
+                          .portId = maybeSocket->portId};
+    return true;
+}
+
+extern "C" void android_nlinterceptor_closeSocket(
+    const android_nlinterceptor_InterceptedSocket* sock) {
+    if (!sock) {
+        LOG(ERROR) << "Can't close socket identified by a null pointer!";
+        return;
+    }
+    closeSocket({sock->nlFamily, sock->portId});
+}
+
+extern "C" bool android_nlinterceptor_subscribe(
+    const android_nlinterceptor_InterceptedSocket* sock, uint32_t group) {
+    if (!sock) return false;
+    return subscribe({sock->nlFamily, sock->portId}, group);
+}
+
+extern "C" bool android_nlinterceptor_unsubscribe(
+    const android_nlinterceptor_InterceptedSocket* sock, uint32_t group) {
+    if (!sock) return false;
+    return unsubscribe({sock->nlFamily, sock->portId}, group);
+}
+
+}  // namespace android::nlinterceptor
diff --git a/wifi/netlinkinterceptor/vts/OWNERS b/wifi/netlinkinterceptor/vts/OWNERS
new file mode 100644
index 0000000..b738dac
--- /dev/null
+++ b/wifi/netlinkinterceptor/vts/OWNERS
@@ -0,0 +1,2 @@
+chrisweir@google.com
+twasilczyk@google.com
diff --git a/wifi/netlinkinterceptor/vts/functional/Android.bp b/wifi/netlinkinterceptor/vts/functional/Android.bp
new file mode 100644
index 0000000..33284e8
--- /dev/null
+++ b/wifi/netlinkinterceptor/vts/functional/Android.bp
@@ -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 {
+    // 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: "VtsHalNetlinkInterceptorV1_0Test",
+    defaults: [
+        "VtsHalTargetTestDefaults",
+        "use_libaidlvintf_gtest_helper_static",
+    ],
+    cpp_std: "experimental",
+    srcs: [
+        "interceptor_aidl_test.cpp",
+    ],
+    shared_libs: [
+        "android.hardware.net.nlinterceptor-V1-ndk",
+        "libbase",
+        "libbinder_ndk",
+    ],
+    static_libs: [
+        "libgmock",
+        "android.hardware.automotive.can@libnetdevice",
+        "libnl++",
+    ],
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
+    disable_framework: true,
+}
diff --git a/wifi/netlinkinterceptor/vts/functional/interceptor_aidl_test.cpp b/wifi/netlinkinterceptor/vts/functional/interceptor_aidl_test.cpp
new file mode 100644
index 0000000..b26d8ec
--- /dev/null
+++ b/wifi/netlinkinterceptor/vts/functional/interceptor_aidl_test.cpp
@@ -0,0 +1,195 @@
+/*
+ * 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 <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/net/nlinterceptor/IInterceptor.h>
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <gtest/gtest.h>
+#include <libnetdevice/libnetdevice.h>
+#include <libnl++/MessageFactory.h>
+#include <libnl++/Socket.h>
+#include <libnl++/printer.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+
+#include <chrono>
+#include <thread>
+
+using aidl::android::hardware::net::nlinterceptor::IInterceptor;
+using AidlInterceptedSocket =
+    ::aidl::android::hardware::net::nlinterceptor::InterceptedSocket;
+using namespace std::chrono_literals;
+using namespace std::string_literals;
+
+class InterceptorAidlTest : public ::testing::TestWithParam<std::string> {
+   public:
+    virtual void SetUp() override {
+        android::base::SetDefaultTag("InterceptorAidlTest");
+        android::base::SetMinimumLogSeverity(android::base::VERBOSE);
+        const auto instance = IInterceptor::descriptor + "/default"s;
+        mNlInterceptorService = IInterceptor::fromBinder(
+            ndk::SpAIBinder(AServiceManager_getService(instance.c_str())));
+
+        ASSERT_NE(mNlInterceptorService, nullptr);
+        mSocket = std::make_unique<android::nl::Socket>(NETLINK_ROUTE);
+        ASSERT_TRUE(mSocket->getPid().has_value());
+
+        // If the test broke last run, clean up our mess, don't worry about "no
+        // such device".
+        if (android::netdevice::del(mTestIfaceName)) {
+            LOG(WARNING) << "Test interface wasn't cleaned up on previous run!";
+        }
+    }
+
+    void multicastReceiver();
+
+    std::shared_ptr<IInterceptor> mNlInterceptorService;
+    std::unique_ptr<android::nl::Socket> mSocket;
+    bool mRunning;
+    bool mGotMulticast;
+    const std::string mTestIfaceName = "interceptorvts0";
+};
+
+TEST_P(InterceptorAidlTest, createSocketTest) {
+    // Ask IInterceptor for a socket.
+    AidlInterceptedSocket interceptedSocket;
+    auto aidlStatus = mNlInterceptorService->createSocket(
+        NETLINK_ROUTE, *(mSocket->getPid()), "createSocketTest",
+        &interceptedSocket);
+    ASSERT_TRUE(aidlStatus.isOk());
+    ASSERT_NE(interceptedSocket.portId, 0);
+    uint32_t interceptorPid = interceptedSocket.portId;
+
+    // Ask the kernel to tell us what interfaces are available.
+    android::nl::MessageFactory<rtgenmsg> req(RTM_GETLINK,
+                                              NLM_F_REQUEST | NLM_F_DUMP);
+    req->rtgen_family = AF_PACKET;
+    sockaddr_nl sa = {.nl_family = AF_NETLINK,
+                      .nl_pad = 0,
+                      .nl_pid = interceptorPid,
+                      .nl_groups = 0};
+    EXPECT_TRUE(mSocket->send(req, sa));
+
+    // We'll likely get back several messages, as indicated by the MULTI flag.
+    unsigned received = 0;
+    for (const auto msg : *mSocket) {
+        ASSERT_NE(msg->nlmsg_type, NLMSG_ERROR);
+        ++received;
+        break;
+        if (msg->nlmsg_type == NLMSG_DONE) {
+            // TODO(202548749): NLMSG_DONE on NETLINK_ROUTE doesn't work?
+            break;
+        }
+    }
+    ASSERT_GE(received, 1);
+
+    // Close the socket and make sure it's stopped working.
+    aidlStatus = mNlInterceptorService->closeSocket(interceptedSocket);
+    EXPECT_TRUE(aidlStatus.isOk());
+    EXPECT_FALSE(mSocket->send(req, sa));
+}
+
+static bool isSocketReadable(const short revents) {
+    return 0 != (revents & POLLIN);
+}
+
+static bool isSocketBad(const short revents) {
+    return 0 != (revents & (POLLERR | POLLHUP | POLLNVAL));
+}
+
+void InterceptorAidlTest::multicastReceiver() {
+    pollfd fds[] = {
+        mSocket->preparePoll(POLLIN),
+    };
+    while (mRunning) {
+        if (poll(fds, 1, 300) < 0) {
+            PLOG(FATAL) << "poll failed";
+            return;
+        }
+        const auto nlsockEvents = fds[0].revents;
+        ASSERT_FALSE(isSocketBad(nlsockEvents));
+        if (!isSocketReadable(nlsockEvents)) continue;
+
+        const auto [msgMaybe, sa] = mSocket->receiveFrom();
+        ASSERT_TRUE(msgMaybe.has_value());
+        auto msg = *msgMaybe;
+
+        // Multicast messages have 0 for their pid and sequence number.
+        if (msg->nlmsg_pid == 0 && msg->nlmsg_seq == 0) {
+            mGotMulticast = true;
+        }
+    }
+}
+
+TEST_P(InterceptorAidlTest, subscribeGroupTest) {
+    // Ask IInterceptor for a socket.
+    AidlInterceptedSocket interceptedSocket;
+    auto aidlStatus = mNlInterceptorService->createSocket(
+        NETLINK_ROUTE, *(mSocket->getPid()), "subscribeGroupTest",
+        &interceptedSocket);
+    ASSERT_TRUE(aidlStatus.isOk());
+    ASSERT_TRUE(interceptedSocket.portId != 0);
+
+    // Listen for interface up/down events.
+    aidlStatus =
+        mNlInterceptorService->subscribeGroup(interceptedSocket, RTNLGRP_LINK);
+    ASSERT_TRUE(aidlStatus.isOk());
+
+    // Start a thread to receive a multicast
+    mRunning = true;
+    mGotMulticast = false;
+    std::thread successfulReceiver(&InterceptorAidlTest::multicastReceiver,
+                                   this);
+
+    // TODO(201695162): use futures with wait_for instead of a sleep_for().
+    std::this_thread::sleep_for(50ms);
+    // create a network interface and bring it up to trigger a multicast event.
+    ASSERT_TRUE(android::netdevice::add(mTestIfaceName, /*type=*/"dummy"));
+    ASSERT_TRUE(android::netdevice::up(mTestIfaceName));
+    std::this_thread::sleep_for(50ms);
+    EXPECT_TRUE(mGotMulticast);
+    mRunning = false;
+    successfulReceiver.join();
+
+    // Stop listening to interface up/down events.
+    aidlStatus = mNlInterceptorService->unsubscribeGroup(interceptedSocket,
+                                                         RTNLGRP_LINK);
+    ASSERT_TRUE(aidlStatus.isOk());
+
+    // This time, we should hear nothing.
+    mGotMulticast = false;
+    mRunning = true;
+    std::thread unsuccessfulReceiver(&InterceptorAidlTest::multicastReceiver,
+                                     this);
+    std::this_thread::sleep_for(50ms);
+    ASSERT_TRUE(android::netdevice::down(mTestIfaceName));
+    ASSERT_TRUE(android::netdevice::del(mTestIfaceName));
+    std::this_thread::sleep_for(50ms);
+    EXPECT_FALSE(mGotMulticast);
+    mRunning = false;
+    unsuccessfulReceiver.join();
+
+    aidlStatus = mNlInterceptorService->closeSocket(interceptedSocket);
+    EXPECT_TRUE(aidlStatus.isOk());
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(InterceptorAidlTest);
+INSTANTIATE_TEST_SUITE_P(PerInstance, InterceptorAidlTest,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(
+                             IInterceptor::descriptor)),
+                         android::PrintInstanceNameToString);
diff --git a/wifi/supplicant/1.3/vts/OWNERS b/wifi/supplicant/OWNERS
similarity index 64%
rename from wifi/supplicant/1.3/vts/OWNERS
rename to wifi/supplicant/OWNERS
index 287152d..7febd60 100644
--- a/wifi/supplicant/1.3/vts/OWNERS
+++ b/wifi/supplicant/OWNERS
@@ -1,3 +1,5 @@
 # Bug component: 33618
 arabawy@google.com
 etancohen@google.com
+gbiren@google.com
+lzye@google.com
diff --git a/wifi/supplicant/aidl/Android.bp b/wifi/supplicant/aidl/Android.bp
new file mode 100644
index 0000000..c97a6f9
--- /dev/null
+++ b/wifi/supplicant/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.
+
+aidl_interface {
+    name: "android.hardware.wifi.supplicant",
+    vendor_available: true,
+    srcs: [
+        "android/hardware/wifi/supplicant/*.aidl",
+    ],
+    stability: "vintf",
+    backend: {
+        java: {
+            sdk_version: "module_current",
+            apex_available: [
+                "//apex_available:platform",
+                "com.android.wifi",
+            ],
+            min_sdk_version: "30",
+        },
+        ndk: {
+            vndk: {
+                enabled: true,
+            },
+        },
+    },
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/AnqpData.aidl
similarity index 81%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/AnqpData.aidl
index 41a1afe..d8e49d7 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/AnqpData.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,10 +31,14 @@
 // 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.graphics.composer3;
+package android.hardware.wifi.supplicant;
 @VintfStability
-parcelable ExecuteCommandsStatus {
-  boolean queueChanged;
-  int length;
-  android.hardware.common.NativeHandle[] handles;
+parcelable AnqpData {
+  byte[] venueName;
+  byte[] roamingConsortium;
+  byte[] ipAddrTypeAvailability;
+  byte[] naiRealm;
+  byte[] anqp3gppCellularNetwork;
+  byte[] domainName;
+  byte[] venueUrl;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/AnqpInfoId.aidl
similarity index 82%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/AnqpInfoId.aidl
index a522d53..cc32360 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/AnqpInfoId.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,11 +31,13 @@
 // 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.graphics.composer3;
+package android.hardware.wifi.supplicant;
 @Backing(type="int") @VintfStability
-enum BlendMode {
-  INVALID = 0,
-  NONE = 1,
-  PREMULTIPLIED = 2,
-  COVERAGE = 3,
+enum AnqpInfoId {
+  VENUE_NAME = 258,
+  ROAMING_CONSORTIUM = 261,
+  IP_ADDR_TYPE_AVAILABILITY = 262,
+  NAI_REALM = 263,
+  ANQP_3GPP_CELLULAR_NETWORK = 264,
+  DOMAIN_NAME = 268,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/AssociationRejectionData.aidl
similarity index 72%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/AssociationRejectionData.aidl
index a522d53..f6830dc 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/AssociationRejectionData.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,11 +31,15 @@
 // 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.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum BlendMode {
-  INVALID = 0,
-  NONE = 1,
-  PREMULTIPLIED = 2,
-  COVERAGE = 3,
+package android.hardware.wifi.supplicant;
+@VintfStability
+parcelable AssociationRejectionData {
+  byte[] ssid;
+  byte[] bssid;
+  android.hardware.wifi.supplicant.StaIfaceStatusCode statusCode;
+  boolean timedOut;
+  boolean isMboAssocDisallowedReasonCodePresent;
+  android.hardware.wifi.supplicant.MboAssocDisallowedReasonCode mboAssocDisallowedReason;
+  boolean isOceRssiBasedAssocRejectAttrPresent;
+  android.hardware.wifi.supplicant.OceRssiBasedAssocRejectAttr oceRssiBasedAssocRejectData;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/AuthAlgMask.aidl
similarity index 87%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/AuthAlgMask.aidl
index cfafc50..9cd178d 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/AuthAlgMask.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,8 +31,11 @@
 // 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.graphics.composer3;
+package android.hardware.wifi.supplicant;
 @Backing(type="int") @VintfStability
-enum LayerRequest {
-  CLEAR_CLIENT_TARGET = 1,
+enum AuthAlgMask {
+  OPEN = 1,
+  SHARED = 2,
+  LEAP = 4,
+  SAE = 16,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/BssTmData.aidl
similarity index 76%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/BssTmData.aidl
index 41a1afe..34d894d 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/BssTmData.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,10 +31,12 @@
 // 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.graphics.composer3;
+package android.hardware.wifi.supplicant;
 @VintfStability
-parcelable ExecuteCommandsStatus {
-  boolean queueChanged;
-  int length;
-  android.hardware.common.NativeHandle[] handles;
+parcelable BssTmData {
+  android.hardware.wifi.supplicant.BssTmStatusCode status;
+  android.hardware.wifi.supplicant.BssTmDataFlagsMask flags;
+  int assocRetryDelayMs;
+  android.hardware.wifi.supplicant.MboTransitionReasonCode mboTransitionReason;
+  android.hardware.wifi.supplicant.MboCellularDataConnectionPrefValue mboCellPreference;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/BssTmDataFlagsMask.aidl
similarity index 75%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/BssTmDataFlagsMask.aidl
index a522d53..f215f05 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/BssTmDataFlagsMask.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,11 +31,15 @@
 // 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.graphics.composer3;
+package android.hardware.wifi.supplicant;
 @Backing(type="int") @VintfStability
-enum BlendMode {
-  INVALID = 0,
-  NONE = 1,
-  PREMULTIPLIED = 2,
-  COVERAGE = 3,
+enum BssTmDataFlagsMask {
+  WNM_MODE_PREFERRED_CANDIDATE_LIST_INCLUDED = 1,
+  WNM_MODE_ABRIDGED = 2,
+  WNM_MODE_DISASSOCIATION_IMMINENT = 4,
+  WNM_MODE_BSS_TERMINATION_INCLUDED = 8,
+  WNM_MODE_ESS_DISASSOCIATION_IMMINENT = 16,
+  MBO_TRANSITION_REASON_CODE_INCLUDED = 32,
+  MBO_ASSOC_RETRY_DELAY_INCLUDED = 64,
+  MBO_CELLULAR_DATA_CONNECTION_PREFERENCE_INCLUDED = 128,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/BssTmStatusCode.aidl
similarity index 75%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/BssTmStatusCode.aidl
index a522d53..c95825f 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/BssTmStatusCode.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,11 +31,16 @@
 // 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.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum BlendMode {
-  INVALID = 0,
-  NONE = 1,
-  PREMULTIPLIED = 2,
-  COVERAGE = 3,
+package android.hardware.wifi.supplicant;
+@Backing(type="byte") @VintfStability
+enum BssTmStatusCode {
+  ACCEPT = 0,
+  REJECT_UNSPECIFIED = 1,
+  REJECT_INSUFFICIENT_BEACON = 2,
+  REJECT_INSUFFICIENT_CAPABITY = 3,
+  REJECT_BSS_TERMINATION_UNDESIRED = 4,
+  REJECT_BSS_TERMINATION_DELAY_REQUEST = 5,
+  REJECT_STA_CANDIDATE_LIST_PROVIDED = 6,
+  REJECT_NO_SUITABLE_CANDIDATES = 7,
+  REJECT_LEAVING_ESS = 8,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/BssidChangeReason.aidl
similarity index 84%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/BssidChangeReason.aidl
index a522d53..1d24579 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/BssidChangeReason.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,11 +31,10 @@
 // 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.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum BlendMode {
-  INVALID = 0,
-  NONE = 1,
-  PREMULTIPLIED = 2,
-  COVERAGE = 3,
+package android.hardware.wifi.supplicant;
+@Backing(type="byte") @VintfStability
+enum BssidChangeReason {
+  ASSOC_START = 0,
+  ASSOC_COMPLETE = 1,
+  DISASSOC = 2,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/BtCoexistenceMode.aidl
similarity index 85%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/BtCoexistenceMode.aidl
index cfafc50..bdc1b4a 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/BtCoexistenceMode.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,8 +31,10 @@
 // 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.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum LayerRequest {
-  CLEAR_CLIENT_TARGET = 1,
+package android.hardware.wifi.supplicant;
+@Backing(type="byte") @VintfStability
+enum BtCoexistenceMode {
+  ENABLED = 0,
+  DISABLED = 1,
+  SENSE = 2,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ConnectionCapabilities.aidl
similarity index 79%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ConnectionCapabilities.aidl
index 41a1afe..433b3d80 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ConnectionCapabilities.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,10 +31,12 @@
 // 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.graphics.composer3;
+package android.hardware.wifi.supplicant;
 @VintfStability
-parcelable ExecuteCommandsStatus {
-  boolean queueChanged;
-  int length;
-  android.hardware.common.NativeHandle[] handles;
+parcelable ConnectionCapabilities {
+  android.hardware.wifi.supplicant.WifiTechnology technology;
+  int channelBandwidth;
+  int maxNumberTxSpatialStreams;
+  int maxNumberRxSpatialStreams;
+  android.hardware.wifi.supplicant.LegacyMode legacyMode;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/DebugLevel.aidl
similarity index 85%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/DebugLevel.aidl
index a522d53..fbfb5b3 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/DebugLevel.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,11 +31,13 @@
 // 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.graphics.composer3;
+package android.hardware.wifi.supplicant;
 @Backing(type="int") @VintfStability
-enum BlendMode {
-  INVALID = 0,
-  NONE = 1,
-  PREMULTIPLIED = 2,
-  COVERAGE = 3,
+enum DebugLevel {
+  EXCESSIVE = 0,
+  MSGDUMP = 1,
+  DEBUG = 2,
+  INFO = 3,
+  WARNING = 4,
+  ERROR = 5,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/DppAkm.aidl
similarity index 87%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/DppAkm.aidl
index cfafc50..df2aef8 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/DppAkm.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,8 +31,11 @@
 // 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.graphics.composer3;
+package android.hardware.wifi.supplicant;
 @Backing(type="int") @VintfStability
-enum LayerRequest {
-  CLEAR_CLIENT_TARGET = 1,
+enum DppAkm {
+  PSK = 0,
+  PSK_SAE = 1,
+  SAE = 2,
+  DPP = 3,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/DppCurve.aidl
similarity index 84%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/DppCurve.aidl
index a522d53..e69da44 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/DppCurve.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,11 +31,13 @@
 // 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.graphics.composer3;
+package android.hardware.wifi.supplicant;
 @Backing(type="int") @VintfStability
-enum BlendMode {
-  INVALID = 0,
-  NONE = 1,
-  PREMULTIPLIED = 2,
-  COVERAGE = 3,
+enum DppCurve {
+  PRIME256V1 = 0,
+  SECP384R1 = 1,
+  SECP521R1 = 2,
+  BRAINPOOLP256R1 = 3,
+  BRAINPOOLP384R1 = 4,
+  BRAINPOOLP512R1 = 5,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/DppEventType.aidl
similarity index 87%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/DppEventType.aidl
index cfafc50..9e394fc 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/DppEventType.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,8 +31,9 @@
 // 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.graphics.composer3;
+package android.hardware.wifi.supplicant;
 @Backing(type="int") @VintfStability
-enum LayerRequest {
-  CLEAR_CLIENT_TARGET = 1,
+enum DppEventType {
+  CONFIGURATION_SENT = 0,
+  CONFIGURATION_APPLIED = 1,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/DppFailureCode.aidl
similarity index 78%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/DppFailureCode.aidl
index a522d53..7e7c806 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/DppFailureCode.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,11 +31,19 @@
 // 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.graphics.composer3;
+package android.hardware.wifi.supplicant;
 @Backing(type="int") @VintfStability
-enum BlendMode {
-  INVALID = 0,
-  NONE = 1,
-  PREMULTIPLIED = 2,
-  COVERAGE = 3,
+enum DppFailureCode {
+  INVALID_URI = 0,
+  AUTHENTICATION = 1,
+  NOT_COMPATIBLE = 2,
+  CONFIGURATION = 3,
+  BUSY = 4,
+  TIMEOUT = 5,
+  FAILURE = 6,
+  NOT_SUPPORTED = 7,
+  CONFIGURATION_REJECTED = 8,
+  CANNOT_FIND_NETWORK = 9,
+  ENROLLEE_AUTHENTICATION = 10,
+  URI_GENERATION = 11,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/DppNetRole.aidl
similarity index 88%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/DppNetRole.aidl
index cfafc50..c6d3522 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/DppNetRole.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,8 +31,9 @@
 // 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.graphics.composer3;
+package android.hardware.wifi.supplicant;
 @Backing(type="int") @VintfStability
-enum LayerRequest {
-  CLEAR_CLIENT_TARGET = 1,
+enum DppNetRole {
+  STA = 0,
+  AP = 1,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/DppProgressCode.aidl
similarity index 83%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/DppProgressCode.aidl
index a522d53..f0618a5 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/DppProgressCode.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,11 +31,11 @@
 // 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.graphics.composer3;
+package android.hardware.wifi.supplicant;
 @Backing(type="int") @VintfStability
-enum BlendMode {
-  INVALID = 0,
-  NONE = 1,
-  PREMULTIPLIED = 2,
-  COVERAGE = 3,
+enum DppProgressCode {
+  AUTHENTICATION_SUCCESS = 0,
+  RESPONSE_PENDING = 1,
+  CONFIGURATION_SENT_WAITING_RESPONSE = 2,
+  CONFIGURATION_ACCEPTED = 3,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/DppResponderBootstrapInfo.aidl
similarity index 85%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/DppResponderBootstrapInfo.aidl
index cfafc50..8b6492b 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/DppResponderBootstrapInfo.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,8 +31,10 @@
 // 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.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum LayerRequest {
-  CLEAR_CLIENT_TARGET = 1,
+package android.hardware.wifi.supplicant;
+@VintfStability
+parcelable DppResponderBootstrapInfo {
+  int bootstrapId;
+  int listenChannel;
+  String uri;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/EapErrorCode.aidl
similarity index 81%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/EapErrorCode.aidl
index a522d53..2cf81d9 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/EapErrorCode.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,11 +31,12 @@
 // 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.graphics.composer3;
+package android.hardware.wifi.supplicant;
 @Backing(type="int") @VintfStability
-enum BlendMode {
-  INVALID = 0,
-  NONE = 1,
-  PREMULTIPLIED = 2,
-  COVERAGE = 3,
+enum EapErrorCode {
+  SIM_GENERAL_FAILURE_AFTER_AUTH = 0,
+  SIM_TEMPORARILY_DENIED = 1026,
+  SIM_NOT_SUBSCRIBED = 1031,
+  SIM_GENERAL_FAILURE_BEFORE_AUTH = 16384,
+  SIM_VENDOR_SPECIFIC_EXPIRED_CERT = 16385,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/EapMethod.aidl
similarity index 84%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/EapMethod.aidl
index a522d53..4ab23af 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/EapMethod.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,11 +31,15 @@
 // 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.graphics.composer3;
+package android.hardware.wifi.supplicant;
 @Backing(type="int") @VintfStability
-enum BlendMode {
-  INVALID = 0,
-  NONE = 1,
-  PREMULTIPLIED = 2,
-  COVERAGE = 3,
+enum EapMethod {
+  PEAP = 0,
+  TLS = 1,
+  TTLS = 2,
+  PWD = 3,
+  SIM = 4,
+  AKA = 5,
+  AKA_PRIME = 6,
+  WFA_UNAUTH_TLS = 7,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/EapPhase2Method.aidl
similarity index 84%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/EapPhase2Method.aidl
index a522d53..4bd93a0 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/EapPhase2Method.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,11 +31,15 @@
 // 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.graphics.composer3;
+package android.hardware.wifi.supplicant;
 @Backing(type="int") @VintfStability
-enum BlendMode {
-  INVALID = 0,
-  NONE = 1,
-  PREMULTIPLIED = 2,
-  COVERAGE = 3,
+enum EapPhase2Method {
+  NONE = 0,
+  PAP = 1,
+  MSPAP = 2,
+  MSPAPV2 = 3,
+  GTC = 4,
+  SIM = 5,
+  AKA = 6,
+  AKA_PRIME = 7,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ExtRadioWorkDefaults.aidl
similarity index 88%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ExtRadioWorkDefaults.aidl
index cfafc50..cbf1a3e 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ExtRadioWorkDefaults.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,8 +31,8 @@
 // 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.graphics.composer3;
+package android.hardware.wifi.supplicant;
 @Backing(type="int") @VintfStability
-enum LayerRequest {
-  CLEAR_CLIENT_TARGET = 1,
+enum ExtRadioWorkDefaults {
+  TIMEOUT_IN_SECS = 10,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/FreqRange.aidl
similarity index 86%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/FreqRange.aidl
index cfafc50..0971d51 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/FreqRange.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,8 +31,9 @@
 // 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.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum LayerRequest {
-  CLEAR_CLIENT_TARGET = 1,
+package android.hardware.wifi.supplicant;
+@VintfStability
+parcelable FreqRange {
+  int min;
+  int max;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/GroupCipherMask.aidl
similarity index 83%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/GroupCipherMask.aidl
index a522d53..f2da925 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/GroupCipherMask.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,11 +31,15 @@
 // 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.graphics.composer3;
+package android.hardware.wifi.supplicant;
 @Backing(type="int") @VintfStability
-enum BlendMode {
-  INVALID = 0,
-  NONE = 1,
-  PREMULTIPLIED = 2,
-  COVERAGE = 3,
+enum GroupCipherMask {
+  WEP40 = 2,
+  WEP104 = 4,
+  TKIP = 8,
+  CCMP = 16,
+  GTK_NOT_USED = 16384,
+  GCMP_256 = 256,
+  SMS4 = 128,
+  GCMP_128 = 64,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/GroupMgmtCipherMask.aidl
similarity index 86%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/GroupMgmtCipherMask.aidl
index a522d53..c24d6cc 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/GroupMgmtCipherMask.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,11 +31,10 @@
 // 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.graphics.composer3;
+package android.hardware.wifi.supplicant;
 @Backing(type="int") @VintfStability
-enum BlendMode {
-  INVALID = 0,
-  NONE = 1,
-  PREMULTIPLIED = 2,
-  COVERAGE = 3,
+enum GroupMgmtCipherMask {
+  BIP_GMAC_128 = 2048,
+  BIP_GMAC_256 = 4096,
+  BIP_CMAC_256 = 8192,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/GsmRand.aidl
similarity index 86%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/GsmRand.aidl
index cfafc50..599a683 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/GsmRand.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,8 +31,8 @@
 // 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.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum LayerRequest {
-  CLEAR_CLIENT_TARGET = 1,
+package android.hardware.wifi.supplicant;
+@VintfStability
+parcelable GsmRand {
+  byte[] data;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/Hs20AnqpData.aidl
similarity index 84%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/Hs20AnqpData.aidl
index 41a1afe..43b182a 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/Hs20AnqpData.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,10 +31,11 @@
 // 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.graphics.composer3;
+package android.hardware.wifi.supplicant;
 @VintfStability
-parcelable ExecuteCommandsStatus {
-  boolean queueChanged;
-  int length;
-  android.hardware.common.NativeHandle[] handles;
+parcelable Hs20AnqpData {
+  byte[] operatorFriendlyName;
+  byte[] wanMetrics;
+  byte[] connectionCapability;
+  byte[] osuProvidersList;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/Hs20AnqpSubtypes.aidl
similarity index 84%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/Hs20AnqpSubtypes.aidl
index a522d53..270d43b 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/Hs20AnqpSubtypes.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,11 +31,11 @@
 // 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.graphics.composer3;
+package android.hardware.wifi.supplicant;
 @Backing(type="int") @VintfStability
-enum BlendMode {
-  INVALID = 0,
-  NONE = 1,
-  PREMULTIPLIED = 2,
-  COVERAGE = 3,
+enum Hs20AnqpSubtypes {
+  OPERATOR_FRIENDLY_NAME = 3,
+  WAN_METRICS = 4,
+  CONNECTION_CAPABILITY = 5,
+  OSU_PROVIDERS_LIST = 8,
 }
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicant.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicant.aidl
new file mode 100644
index 0000000..b4371fd
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicant.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.wifi.supplicant;
+@VintfStability
+interface ISupplicant {
+  android.hardware.wifi.supplicant.ISupplicantP2pIface addP2pInterface(in String ifName);
+  android.hardware.wifi.supplicant.ISupplicantStaIface addStaInterface(in String ifName);
+  android.hardware.wifi.supplicant.DebugLevel getDebugLevel();
+  android.hardware.wifi.supplicant.ISupplicantP2pIface getP2pInterface(in String ifName);
+  android.hardware.wifi.supplicant.ISupplicantStaIface getStaInterface(in String ifName);
+  boolean isDebugShowKeysEnabled();
+  boolean isDebugShowTimestampEnabled();
+  android.hardware.wifi.supplicant.IfaceInfo[] listInterfaces();
+  void registerCallback(in android.hardware.wifi.supplicant.ISupplicantCallback callback);
+  void removeInterface(in android.hardware.wifi.supplicant.IfaceInfo ifaceInfo);
+  void setConcurrencyPriority(in android.hardware.wifi.supplicant.IfaceType type);
+  void setDebugParams(in android.hardware.wifi.supplicant.DebugLevel level, in boolean showTimestamp, in boolean showKeys);
+  oneway void terminate();
+  const int EXT_RADIO_WORK_TIMEOUT_IN_SECS = 10;
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantCallback.aidl
similarity index 82%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantCallback.aidl
index 41a1afe..72ab3b9 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantCallback.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,10 +31,10 @@
 // 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.graphics.composer3;
+package android.hardware.wifi.supplicant;
 @VintfStability
-parcelable ExecuteCommandsStatus {
-  boolean queueChanged;
-  int length;
-  android.hardware.common.NativeHandle[] handles;
+interface ISupplicantCallback {
+  oneway void onInterfaceCreated(in String ifaceName);
+  oneway void onInterfaceRemoved(in String ifaceName);
+  oneway void onTerminating();
 }
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl
new file mode 100644
index 0000000..ca7be73
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl
@@ -0,0 +1,95 @@
+/*
+ * 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.wifi.supplicant;
+@VintfStability
+interface ISupplicantP2pIface {
+  void addBonjourService(in byte[] query, in byte[] response);
+  void addGroup(in boolean persistent, in int persistentNetworkId);
+  void addGroupWithConfig(in byte[] ssid, in String pskPassphrase, in boolean persistent, in int freq, in byte[] peerAddress, in boolean joinExistingGroup);
+  android.hardware.wifi.supplicant.ISupplicantP2pNetwork addNetwork();
+  void addUpnpService(in int version, in String serviceName);
+  void cancelConnect();
+  void cancelServiceDiscovery(in long identifier);
+  void cancelWps(in String groupIfName);
+  void configureExtListen(in int periodInMillis, in int intervalInMillis);
+  String connect(in byte[] peerAddress, in android.hardware.wifi.supplicant.WpsProvisionMethod provisionMethod, in String preSelectedPin, in boolean joinExistingGroup, in boolean persistent, in int goIntent);
+  byte[] createNfcHandoverRequestMessage();
+  byte[] createNfcHandoverSelectMessage();
+  void enableWfd(in boolean enable);
+  void find(in int timeoutInSec);
+  void flush();
+  void flushServices();
+  byte[] getDeviceAddress();
+  boolean getEdmg();
+  android.hardware.wifi.supplicant.P2pGroupCapabilityMask getGroupCapability(in byte[] peerAddress);
+  String getName();
+  android.hardware.wifi.supplicant.ISupplicantP2pNetwork getNetwork(in int id);
+  byte[] getSsid(in byte[] peerAddress);
+  android.hardware.wifi.supplicant.IfaceType getType();
+  void invite(in String groupIfName, in byte[] goDeviceAddress, in byte[] peerAddress);
+  int[] listNetworks();
+  void provisionDiscovery(in byte[] peerAddress, in android.hardware.wifi.supplicant.WpsProvisionMethod provisionMethod);
+  void registerCallback(in android.hardware.wifi.supplicant.ISupplicantP2pIfaceCallback callback);
+  void reinvoke(in int persistentNetworkId, in byte[] peerAddress);
+  void reject(in byte[] peerAddress);
+  void removeBonjourService(in byte[] query);
+  void removeGroup(in String groupIfName);
+  void removeNetwork(in int id);
+  void removeUpnpService(in int version, in String serviceName);
+  void reportNfcHandoverInitiation(in byte[] select);
+  void reportNfcHandoverResponse(in byte[] request);
+  long requestServiceDiscovery(in byte[] peerAddress, in byte[] query);
+  void saveConfig();
+  void setDisallowedFrequencies(in android.hardware.wifi.supplicant.FreqRange[] ranges);
+  void setEdmg(in boolean enable);
+  void setGroupIdle(in String groupIfName, in int timeoutInSec);
+  void setListenChannel(in int channel, in int operatingClass);
+  void setMacRandomization(in boolean enable);
+  void setMiracastMode(in android.hardware.wifi.supplicant.MiracastMode mode);
+  void setPowerSave(in String groupIfName, in boolean enable);
+  void setSsidPostfix(in byte[] postfix);
+  void setWfdDeviceInfo(in byte[] info);
+  void setWfdR2DeviceInfo(in byte[] info);
+  void setWpsConfigMethods(in android.hardware.wifi.supplicant.WpsConfigMethods configMethods);
+  void setWpsDeviceName(in String name);
+  void setWpsDeviceType(in byte[] type);
+  void setWpsManufacturer(in String manufacturer);
+  void setWpsModelName(in String modelName);
+  void setWpsModelNumber(in String modelNumber);
+  void setWpsSerialNumber(in String serialNumber);
+  void startWpsPbc(in String groupIfName, in byte[] bssid);
+  String startWpsPinDisplay(in String groupIfName, in byte[] bssid);
+  void startWpsPinKeypad(in String groupIfName, in String pin);
+  void stopFind();
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl
new file mode 100644
index 0000000..ed435e2
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl
@@ -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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.supplicant;
+@VintfStability
+interface ISupplicantP2pIfaceCallback {
+  oneway void onDeviceFound(in byte[] srcAddress, in byte[] p2pDeviceAddress, in byte[] primaryDeviceType, in String deviceName, in android.hardware.wifi.supplicant.WpsConfigMethods configMethods, in byte deviceCapabilities, in android.hardware.wifi.supplicant.P2pGroupCapabilityMask groupCapabilities, in byte[] wfdDeviceInfo);
+  oneway void onDeviceLost(in byte[] p2pDeviceAddress);
+  oneway void onFindStopped();
+  oneway void onGoNegotiationCompleted(in android.hardware.wifi.supplicant.P2pStatusCode status);
+  oneway void onGoNegotiationRequest(in byte[] srcAddress, in android.hardware.wifi.supplicant.WpsDevPasswordId passwordId);
+  oneway void onGroupFormationFailure(in String failureReason);
+  oneway void onGroupFormationSuccess();
+  oneway void onGroupRemoved(in String groupIfname, in boolean isGroupOwner);
+  oneway void onGroupStarted(in String groupIfname, in boolean isGroupOwner, in byte[] ssid, in int frequency, in byte[] psk, in String passphrase, in byte[] goDeviceAddress, in boolean isPersistent);
+  oneway void onInvitationReceived(in byte[] srcAddress, in byte[] goDeviceAddress, in byte[] bssid, in int persistentNetworkId, in int operatingFrequency);
+  oneway void onInvitationResult(in byte[] bssid, in android.hardware.wifi.supplicant.P2pStatusCode status);
+  oneway void onProvisionDiscoveryCompleted(in byte[] p2pDeviceAddress, in boolean isRequest, in android.hardware.wifi.supplicant.P2pProvDiscStatusCode status, in android.hardware.wifi.supplicant.WpsConfigMethods configMethods, in String generatedPin);
+  oneway void onR2DeviceFound(in byte[] srcAddress, in byte[] p2pDeviceAddress, in byte[] primaryDeviceType, in String deviceName, in android.hardware.wifi.supplicant.WpsConfigMethods configMethods, in byte deviceCapabilities, in android.hardware.wifi.supplicant.P2pGroupCapabilityMask groupCapabilities, in byte[] wfdDeviceInfo, in byte[] wfdR2DeviceInfo);
+  oneway void onServiceDiscoveryResponse(in byte[] srcAddress, in char updateIndicator, in byte[] tlvs);
+  oneway void onStaAuthorized(in byte[] srcAddress, in byte[] p2pDeviceAddress);
+  oneway void onStaDeauthorized(in byte[] srcAddress, in byte[] p2pDeviceAddress);
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pNetwork.aidl
similarity index 74%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pNetwork.aidl
index 41a1afe..ef72724 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pNetwork.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,10 +31,17 @@
 // 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.graphics.composer3;
+package android.hardware.wifi.supplicant;
 @VintfStability
-parcelable ExecuteCommandsStatus {
-  boolean queueChanged;
-  int length;
-  android.hardware.common.NativeHandle[] handles;
+interface ISupplicantP2pNetwork {
+  byte[] getBssid();
+  android.hardware.wifi.supplicant.MacAddress[] getClientList();
+  int getId();
+  String getInterfaceName();
+  byte[] getSsid();
+  android.hardware.wifi.supplicant.IfaceType getType();
+  boolean isCurrent();
+  boolean isGroupOwner();
+  boolean isPersistent();
+  void setClientList(in android.hardware.wifi.supplicant.MacAddress[] clients);
 }
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl
new file mode 100644
index 0000000..ca40379
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl
@@ -0,0 +1,93 @@
+/*
+ * 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.wifi.supplicant;
+@VintfStability
+interface ISupplicantStaIface {
+  int addDppPeerUri(in String uri);
+  int addExtRadioWork(in String name, in int freqInMhz, in int timeoutInSec);
+  android.hardware.wifi.supplicant.ISupplicantStaNetwork addNetwork();
+  void addRxFilter(in android.hardware.wifi.supplicant.RxFilterType type);
+  void cancelWps();
+  void disconnect();
+  void enableAutoReconnect(in boolean enable);
+  void filsHlpAddRequest(in byte[] dst_mac, in byte[] pkt);
+  void filsHlpFlushRequest();
+  android.hardware.wifi.supplicant.DppResponderBootstrapInfo generateDppBootstrapInfoForResponder(in byte[] macAddress, in String deviceInfo, in android.hardware.wifi.supplicant.DppCurve curve);
+  android.hardware.wifi.supplicant.ConnectionCapabilities getConnectionCapabilities();
+  android.hardware.wifi.supplicant.KeyMgmtMask getKeyMgmtCapabilities();
+  byte[] getMacAddress();
+  String getName();
+  android.hardware.wifi.supplicant.ISupplicantStaNetwork getNetwork(in int id);
+  android.hardware.wifi.supplicant.IfaceType getType();
+  android.hardware.wifi.supplicant.WpaDriverCapabilitiesMask getWpaDriverCapabilities();
+  void initiateAnqpQuery(in byte[] macAddress, in android.hardware.wifi.supplicant.AnqpInfoId[] infoElements, in android.hardware.wifi.supplicant.Hs20AnqpSubtypes[] subTypes);
+  void initiateHs20IconQuery(in byte[] macAddress, in String fileName);
+  void initiateTdlsDiscover(in byte[] macAddress);
+  void initiateTdlsSetup(in byte[] macAddress);
+  void initiateTdlsTeardown(in byte[] macAddress);
+  void initiateVenueUrlAnqpQuery(in byte[] macAddress);
+  int[] listNetworks();
+  void reassociate();
+  void reconnect();
+  void registerCallback(in android.hardware.wifi.supplicant.ISupplicantStaIfaceCallback callback);
+  void removeDppUri(in int id);
+  void removeExtRadioWork(in int id);
+  void removeNetwork(in int id);
+  void removeRxFilter(in android.hardware.wifi.supplicant.RxFilterType type);
+  void setBtCoexistenceMode(in android.hardware.wifi.supplicant.BtCoexistenceMode mode);
+  void setBtCoexistenceScanModeEnabled(in boolean enable);
+  void setCountryCode(in byte[] code);
+  void setExternalSim(in boolean useExternalSim);
+  void setMboCellularDataStatus(in boolean available);
+  void setPowerSave(in boolean enable);
+  void setSuspendModeEnabled(in boolean enable);
+  void setWpsConfigMethods(in android.hardware.wifi.supplicant.WpsConfigMethods configMethods);
+  void setWpsDeviceName(in String name);
+  void setWpsDeviceType(in byte[] type);
+  void setWpsManufacturer(in String manufacturer);
+  void setWpsModelName(in String modelName);
+  void setWpsModelNumber(in String modelNumber);
+  void setWpsSerialNumber(in String serialNumber);
+  void startDppConfiguratorInitiator(in int peerBootstrapId, in int ownBootstrapId, in String ssid, in String password, in String psk, in android.hardware.wifi.supplicant.DppNetRole netRole, in android.hardware.wifi.supplicant.DppAkm securityAkm);
+  void startDppEnrolleeInitiator(in int peerBootstrapId, in int ownBootstrapId);
+  void startDppEnrolleeResponder(in int listenChannel);
+  void startRxFilter();
+  void startWpsPbc(in byte[] bssid);
+  String startWpsPinDisplay(in byte[] bssid);
+  void startWpsPinKeypad(in String pin);
+  void startWpsRegistrar(in byte[] bssid, in String pin);
+  void stopDppInitiator();
+  void stopDppResponder(in int ownBootstrapId);
+  void stopRxFilter();
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl
new file mode 100644
index 0000000..37b34cf
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl
@@ -0,0 +1,63 @@
+/*
+ * 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.wifi.supplicant;
+@VintfStability
+interface ISupplicantStaIfaceCallback {
+  oneway void onAnqpQueryDone(in byte[] bssid, in android.hardware.wifi.supplicant.AnqpData data, in android.hardware.wifi.supplicant.Hs20AnqpData hs20Data);
+  oneway void onAssociationRejected(in android.hardware.wifi.supplicant.AssociationRejectionData assocRejectData);
+  oneway void onAuthenticationTimeout(in byte[] bssid);
+  oneway void onBssTmHandlingDone(in android.hardware.wifi.supplicant.BssTmData tmData);
+  oneway void onBssidChanged(in android.hardware.wifi.supplicant.BssidChangeReason reason, in byte[] bssid);
+  oneway void onDisconnected(in byte[] bssid, in boolean locallyGenerated, in android.hardware.wifi.supplicant.StaIfaceReasonCode reasonCode);
+  oneway void onDppFailure(in android.hardware.wifi.supplicant.DppFailureCode code, in String ssid, in String channelList, in char[] bandList);
+  oneway void onDppProgress(in android.hardware.wifi.supplicant.DppProgressCode code);
+  oneway void onDppSuccess(in android.hardware.wifi.supplicant.DppEventType event);
+  oneway void onDppSuccessConfigReceived(in byte[] ssid, in String password, in byte[] psk, in android.hardware.wifi.supplicant.DppAkm securityAkm);
+  oneway void onDppSuccessConfigSent();
+  oneway void onEapFailure(in int errorCode);
+  oneway void onExtRadioWorkStart(in int id);
+  oneway void onExtRadioWorkTimeout(in int id);
+  oneway void onHs20DeauthImminentNotice(in byte[] bssid, in int reasonCode, in int reAuthDelayInSec, in String url);
+  oneway void onHs20IconQueryDone(in byte[] bssid, in String fileName, in byte[] data);
+  oneway void onHs20SubscriptionRemediation(in byte[] bssid, in android.hardware.wifi.supplicant.OsuMethod osuMethod, in String url);
+  oneway void onHs20TermsAndConditionsAcceptanceRequestedNotification(in byte[] bssid, in String url);
+  oneway void onNetworkAdded(in int id);
+  oneway void onNetworkNotFound(in byte[] ssid);
+  oneway void onNetworkRemoved(in int id);
+  oneway void onPmkCacheAdded(in long expirationTimeInSec, in byte[] serializedEntry);
+  oneway void onStateChanged(in android.hardware.wifi.supplicant.StaIfaceCallbackState newState, in byte[] bssid, in int id, in byte[] ssid, in boolean filsHlpSent);
+  oneway void onWpsEventFail(in byte[] bssid, in android.hardware.wifi.supplicant.WpsConfigError configError, in android.hardware.wifi.supplicant.WpsErrorIndication errorInd);
+  oneway void onWpsEventPbcOverlap();
+  oneway void onWpsEventSuccess();
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaNetwork.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaNetwork.aidl
new file mode 100644
index 0000000..18baea6
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaNetwork.aidl
@@ -0,0 +1,134 @@
+/*
+ * 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.wifi.supplicant;
+@VintfStability
+interface ISupplicantStaNetwork {
+  void disable();
+  void enable(in boolean noConnect);
+  void enableSaePkOnlyMode(in boolean enable);
+  void enableSuiteBEapOpenSslCiphers();
+  void enableTlsSuiteBEapPhase1Param(in boolean enable);
+  android.hardware.wifi.supplicant.AuthAlgMask getAuthAlg();
+  byte[] getBssid();
+  String getEapAltSubjectMatch();
+  byte[] getEapAnonymousIdentity();
+  String getEapCACert();
+  String getEapCAPath();
+  String getEapClientCert();
+  String getEapDomainSuffixMatch();
+  boolean getEapEngine();
+  String getEapEngineId();
+  byte[] getEapIdentity();
+  android.hardware.wifi.supplicant.EapMethod getEapMethod();
+  byte[] getEapPassword();
+  android.hardware.wifi.supplicant.EapPhase2Method getEapPhase2Method();
+  String getEapPrivateKeyId();
+  String getEapSubjectMatch();
+  boolean getEdmg();
+  android.hardware.wifi.supplicant.GroupCipherMask getGroupCipher();
+  android.hardware.wifi.supplicant.GroupMgmtCipherMask getGroupMgmtCipher();
+  int getId();
+  String getIdStr();
+  String getInterfaceName();
+  android.hardware.wifi.supplicant.KeyMgmtMask getKeyMgmt();
+  android.hardware.wifi.supplicant.OcspType getOcsp();
+  android.hardware.wifi.supplicant.PairwiseCipherMask getPairwiseCipher();
+  android.hardware.wifi.supplicant.ProtoMask getProto();
+  byte[] getPsk();
+  String getPskPassphrase();
+  boolean getRequirePmf();
+  String getSaePassword();
+  String getSaePasswordId();
+  boolean getScanSsid();
+  byte[] getSsid();
+  android.hardware.wifi.supplicant.IfaceType getType();
+  String getWapiCertSuite();
+  byte[] getWepKey(in int keyIdx);
+  int getWepTxKeyIdx();
+  byte[] getWpsNfcConfigurationToken();
+  void registerCallback(in android.hardware.wifi.supplicant.ISupplicantStaNetworkCallback callback);
+  void select();
+  void sendNetworkEapIdentityResponse(in byte[] identity, in byte[] encryptedIdentity);
+  void sendNetworkEapSimGsmAuthFailure();
+  void sendNetworkEapSimGsmAuthResponse(in android.hardware.wifi.supplicant.NetworkResponseEapSimGsmAuthParams[] params);
+  void sendNetworkEapSimUmtsAuthFailure();
+  void sendNetworkEapSimUmtsAuthResponse(in android.hardware.wifi.supplicant.NetworkResponseEapSimUmtsAuthParams params);
+  void sendNetworkEapSimUmtsAutsResponse(in byte[] auts);
+  void setAuthAlg(in android.hardware.wifi.supplicant.AuthAlgMask authAlgMask);
+  void setBssid(in byte[] bssid);
+  void setEapAltSubjectMatch(in String match);
+  void setEapAnonymousIdentity(in byte[] identity);
+  void setEapCACert(in String path);
+  void setEapCAPath(in String path);
+  void setEapClientCert(in String path);
+  void setEapDomainSuffixMatch(in String match);
+  void setEapEncryptedImsiIdentity(in byte[] identity);
+  void setEapEngine(in boolean enable);
+  void setEapEngineID(in String id);
+  void setEapErp(in boolean enable);
+  void setEapIdentity(in byte[] identity);
+  void setEapMethod(in android.hardware.wifi.supplicant.EapMethod method);
+  void setEapPassword(in byte[] password);
+  void setEapPhase2Method(in android.hardware.wifi.supplicant.EapPhase2Method method);
+  void setEapPrivateKeyId(in String id);
+  void setEapSubjectMatch(in String match);
+  void setEdmg(in boolean enable);
+  void setGroupCipher(in android.hardware.wifi.supplicant.GroupCipherMask groupCipherMask);
+  void setGroupMgmtCipher(in android.hardware.wifi.supplicant.GroupMgmtCipherMask groupMgmtCipherMask);
+  void setIdStr(in String idStr);
+  void setKeyMgmt(in android.hardware.wifi.supplicant.KeyMgmtMask keyMgmtMask);
+  void setOcsp(in android.hardware.wifi.supplicant.OcspType ocspType);
+  void setPairwiseCipher(in android.hardware.wifi.supplicant.PairwiseCipherMask pairwiseCipherMask);
+  void setPmkCache(in byte[] serializedEntry);
+  void setProactiveKeyCaching(in boolean enable);
+  void setProto(in android.hardware.wifi.supplicant.ProtoMask protoMask);
+  void setPsk(in byte[] psk);
+  void setPskPassphrase(in String psk);
+  void setRequirePmf(in boolean enable);
+  void setSaeH2eMode(in android.hardware.wifi.supplicant.SaeH2eMode mode);
+  void setSaePassword(in String saePassword);
+  void setSaePasswordId(in String saePasswordId);
+  void setScanSsid(in boolean enable);
+  void setSsid(in byte[] ssid);
+  void setUpdateIdentifier(in int id);
+  void setWapiCertSuite(in String suite);
+  void setWepKey(in int keyIdx, in byte[] wepKey);
+  void setWepTxKeyIdx(in int keyIdx);
+  const int SSID_MAX_LEN_IN_BYTES = 32;
+  const int PSK_PASSPHRASE_MIN_LEN_IN_BYTES = 8;
+  const int PSK_PASSPHRASE_MAX_LEN_IN_BYTES = 63;
+  const int WEP_KEYS_MAX_NUM = 4;
+  const int WEP40_KEY_LEN_IN_BYTES = 5;
+  const int WEP104_KEY_LEN_IN_BYTES = 13;
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl
similarity index 72%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl
index 41a1afe..4f7584d 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ExecuteCommandsStatus.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,10 +31,11 @@
 // 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.graphics.composer3;
+package android.hardware.wifi.supplicant;
 @VintfStability
-parcelable ExecuteCommandsStatus {
-  boolean queueChanged;
-  int length;
-  android.hardware.common.NativeHandle[] handles;
+interface ISupplicantStaNetworkCallback {
+  oneway void onNetworkEapIdentityRequest();
+  oneway void onNetworkEapSimGsmAuthRequest(in android.hardware.wifi.supplicant.NetworkRequestEapSimGsmAuthParams params);
+  oneway void onNetworkEapSimUmtsAuthRequest(in android.hardware.wifi.supplicant.NetworkRequestEapSimUmtsAuthParams params);
+  oneway void onTransitionDisable(in android.hardware.wifi.supplicant.TransitionDisableIndication ind);
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/IfaceInfo.aidl
similarity index 85%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/IfaceInfo.aidl
index cfafc50..6706c8c 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/IfaceInfo.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,8 +31,9 @@
 // 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.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum LayerRequest {
-  CLEAR_CLIENT_TARGET = 1,
+package android.hardware.wifi.supplicant;
+@VintfStability
+parcelable IfaceInfo {
+  android.hardware.wifi.supplicant.IfaceType type;
+  String name;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/IfaceType.aidl
similarity index 88%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/IfaceType.aidl
index cfafc50..557dbd7 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/IfaceType.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,8 +31,9 @@
 // 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.graphics.composer3;
+package android.hardware.wifi.supplicant;
 @Backing(type="int") @VintfStability
-enum LayerRequest {
-  CLEAR_CLIENT_TARGET = 1,
+enum IfaceType {
+  STA = 0,
+  P2P = 1,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/KeyMgmtMask.aidl
similarity index 76%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/KeyMgmtMask.aidl
index a522d53..7228480 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/KeyMgmtMask.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,11 +31,24 @@
 // 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.graphics.composer3;
+package android.hardware.wifi.supplicant;
 @Backing(type="int") @VintfStability
-enum BlendMode {
-  INVALID = 0,
-  NONE = 1,
-  PREMULTIPLIED = 2,
-  COVERAGE = 3,
+enum KeyMgmtMask {
+  WPA_EAP = 1,
+  WPA_PSK = 2,
+  NONE = 4,
+  IEEE8021X = 8,
+  FT_EAP = 32,
+  FT_PSK = 64,
+  OSEN = 32768,
+  WPA_EAP_SHA256 = 128,
+  WPA_PSK_SHA256 = 256,
+  SAE = 1024,
+  SUITE_B_192 = 131072,
+  OWE = 4194304,
+  DPP = 8388608,
+  WAPI_PSK = 4096,
+  WAPI_CERT = 8192,
+  FILS_SHA256 = 262144,
+  FILS_SHA384 = 524288,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/LegacyMode.aidl
similarity index 87%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/LegacyMode.aidl
index cfafc50..6896d75 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/LegacyMode.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,8 +31,11 @@
 // 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.graphics.composer3;
+package android.hardware.wifi.supplicant;
 @Backing(type="int") @VintfStability
-enum LayerRequest {
-  CLEAR_CLIENT_TARGET = 1,
+enum LegacyMode {
+  UNKNOWN = 0,
+  A_MODE = 1,
+  B_MODE = 2,
+  G_MODE = 3,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MacAddress.aidl
similarity index 86%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MacAddress.aidl
index cfafc50..d17930a 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MacAddress.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,8 +31,8 @@
 // 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.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum LayerRequest {
-  CLEAR_CLIENT_TARGET = 1,
+package android.hardware.wifi.supplicant;
+@VintfStability
+parcelable MacAddress {
+  byte[] data;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MboAssocDisallowedReasonCode.aidl
similarity index 80%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MboAssocDisallowedReasonCode.aidl
index a522d53..661165d 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MboAssocDisallowedReasonCode.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,11 +31,13 @@
 // 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.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum BlendMode {
-  INVALID = 0,
-  NONE = 1,
-  PREMULTIPLIED = 2,
-  COVERAGE = 3,
+package android.hardware.wifi.supplicant;
+@Backing(type="byte") @VintfStability
+enum MboAssocDisallowedReasonCode {
+  RESERVED = 0,
+  UNSPECIFIED = 1,
+  MAX_NUM_STA_ASSOCIATED = 2,
+  AIR_INTERFACE_OVERLOADED = 3,
+  AUTH_SERVER_OVERLOADED = 4,
+  INSUFFICIENT_RSSI = 5,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MboCellularDataConnectionPrefValue.aidl
similarity index 86%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MboCellularDataConnectionPrefValue.aidl
index a522d53..c4024d0 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MboCellularDataConnectionPrefValue.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,11 +31,10 @@
 // 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.graphics.composer3;
+package android.hardware.wifi.supplicant;
 @Backing(type="int") @VintfStability
-enum BlendMode {
-  INVALID = 0,
-  NONE = 1,
-  PREMULTIPLIED = 2,
-  COVERAGE = 3,
+enum MboCellularDataConnectionPrefValue {
+  EXCLUDED = 0,
+  NOT_PREFERRED = 1,
+  PREFERRED = 255,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MboTransitionReasonCode.aidl
similarity index 76%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MboTransitionReasonCode.aidl
index a522d53..caed095 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MboTransitionReasonCode.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,11 +31,17 @@
 // 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.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum BlendMode {
-  INVALID = 0,
-  NONE = 1,
-  PREMULTIPLIED = 2,
-  COVERAGE = 3,
+package android.hardware.wifi.supplicant;
+@Backing(type="byte") @VintfStability
+enum MboTransitionReasonCode {
+  UNSPECIFIED = 0,
+  EXCESSIVE_FRAME_LOSS = 1,
+  EXCESSIVE_TRAFFIC_DELAY = 2,
+  INSUFFICIENT_BANDWIDTH = 3,
+  LOAD_BALANCING = 4,
+  LOW_RSSI = 5,
+  RX_EXCESSIVE_RETRIES = 6,
+  HIGH_INTERFERENCE = 7,
+  GRAY_ZONE = 8,
+  TRANSITION_TO_PREMIUM_AP = 9,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MiracastMode.aidl
similarity index 85%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MiracastMode.aidl
index cfafc50..6bc9e4d 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MiracastMode.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,8 +31,10 @@
 // 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.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum LayerRequest {
-  CLEAR_CLIENT_TARGET = 1,
+package android.hardware.wifi.supplicant;
+@Backing(type="byte") @VintfStability
+enum MiracastMode {
+  DISABLED = 0,
+  SOURCE = 1,
+  SINK = 2,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/NetworkRequestEapSimGsmAuthParams.aidl
similarity index 84%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/NetworkRequestEapSimGsmAuthParams.aidl
index a522d53..1f03bb8 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/NetworkRequestEapSimGsmAuthParams.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,11 +31,8 @@
 // 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.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum BlendMode {
-  INVALID = 0,
-  NONE = 1,
-  PREMULTIPLIED = 2,
-  COVERAGE = 3,
+package android.hardware.wifi.supplicant;
+@VintfStability
+parcelable NetworkRequestEapSimGsmAuthParams {
+  android.hardware.wifi.supplicant.GsmRand[] rands;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/NetworkRequestEapSimUmtsAuthParams.aidl
similarity index 85%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/NetworkRequestEapSimUmtsAuthParams.aidl
index cfafc50..956a799 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/NetworkRequestEapSimUmtsAuthParams.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,8 +31,9 @@
 // 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.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum LayerRequest {
-  CLEAR_CLIENT_TARGET = 1,
+package android.hardware.wifi.supplicant;
+@VintfStability
+parcelable NetworkRequestEapSimUmtsAuthParams {
+  byte[] rand;
+  byte[] autn;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/NetworkResponseEapSimGsmAuthParams.aidl
similarity index 86%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/NetworkResponseEapSimGsmAuthParams.aidl
index cfafc50..29415b7 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/NetworkResponseEapSimGsmAuthParams.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,8 +31,9 @@
 // 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.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum LayerRequest {
-  CLEAR_CLIENT_TARGET = 1,
+package android.hardware.wifi.supplicant;
+@VintfStability
+parcelable NetworkResponseEapSimGsmAuthParams {
+  byte[] kc;
+  byte[] sres;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/NetworkResponseEapSimUmtsAuthParams.aidl
similarity index 85%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/NetworkResponseEapSimUmtsAuthParams.aidl
index cfafc50..4e58dd8 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/NetworkResponseEapSimUmtsAuthParams.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,8 +31,10 @@
 // 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.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum LayerRequest {
-  CLEAR_CLIENT_TARGET = 1,
+package android.hardware.wifi.supplicant;
+@VintfStability
+parcelable NetworkResponseEapSimUmtsAuthParams {
+  byte[] res;
+  byte[] ik;
+  byte[] ck;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/OceRssiBasedAssocRejectAttr.aidl
similarity index 86%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/OceRssiBasedAssocRejectAttr.aidl
index cfafc50..95a95bc 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/OceRssiBasedAssocRejectAttr.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,8 +31,9 @@
 // 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.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum LayerRequest {
-  CLEAR_CLIENT_TARGET = 1,
+package android.hardware.wifi.supplicant;
+@VintfStability
+parcelable OceRssiBasedAssocRejectAttr {
+  int deltaRssi;
+  int retryDelayS;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/OcspType.aidl
similarity index 85%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/OcspType.aidl
index a522d53..89de811 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/OcspType.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,11 +31,11 @@
 // 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.graphics.composer3;
+package android.hardware.wifi.supplicant;
 @Backing(type="int") @VintfStability
-enum BlendMode {
-  INVALID = 0,
-  NONE = 1,
-  PREMULTIPLIED = 2,
-  COVERAGE = 3,
+enum OcspType {
+  NONE = 0,
+  REQUEST_CERT_STATUS = 1,
+  REQUIRE_CERT_STATUS = 2,
+  REQUIRE_ALL_CERTS_STATUS = 3,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/OsuMethod.aidl
similarity index 86%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/OsuMethod.aidl
index cfafc50..1b99e2f 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/OsuMethod.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,8 +31,9 @@
 // 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.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum LayerRequest {
-  CLEAR_CLIENT_TARGET = 1,
+package android.hardware.wifi.supplicant;
+@Backing(type="byte") @VintfStability
+enum OsuMethod {
+  OMA_DM = 0,
+  SOAP_XML_SPP = 1,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pGroupCapabilityMask.aidl
similarity index 82%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pGroupCapabilityMask.aidl
index a522d53..ffee12c 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pGroupCapabilityMask.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,11 +31,14 @@
 // 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.graphics.composer3;
+package android.hardware.wifi.supplicant;
 @Backing(type="int") @VintfStability
-enum BlendMode {
-  INVALID = 0,
-  NONE = 1,
-  PREMULTIPLIED = 2,
-  COVERAGE = 3,
+enum P2pGroupCapabilityMask {
+  GROUP_OWNER = 1,
+  PERSISTENT_GROUP = 2,
+  GROUP_LIMIT = 4,
+  INTRA_BSS_DIST = 8,
+  CROSS_CONN = 16,
+  PERSISTENT_RECONN = 32,
+  GROUP_FORMATION = 64,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pProvDiscStatusCode.aidl
similarity index 83%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pProvDiscStatusCode.aidl
index a522d53..c8e53b9 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pProvDiscStatusCode.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,11 +31,12 @@
 // 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.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum BlendMode {
-  INVALID = 0,
-  NONE = 1,
-  PREMULTIPLIED = 2,
-  COVERAGE = 3,
+package android.hardware.wifi.supplicant;
+@Backing(type="byte") @VintfStability
+enum P2pProvDiscStatusCode {
+  SUCCESS = 0,
+  TIMEOUT = 1,
+  REJECTED = 2,
+  TIMEOUT_JOIN = 3,
+  INFO_UNAVAILABLE = 4,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pStatusCode.aidl
similarity index 74%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pStatusCode.aidl
index a522d53..c7ad383 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pStatusCode.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,11 +31,20 @@
 // 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.graphics.composer3;
+package android.hardware.wifi.supplicant;
 @Backing(type="int") @VintfStability
-enum BlendMode {
-  INVALID = 0,
-  NONE = 1,
-  PREMULTIPLIED = 2,
-  COVERAGE = 3,
+enum P2pStatusCode {
+  SUCCESS = 0,
+  FAIL_INFO_CURRENTLY_UNAVAILABLE = 1,
+  FAIL_INCOMPATIBLE_PARAMS = 2,
+  FAIL_LIMIT_REACHED = 3,
+  FAIL_INVALID_PARAMS = 4,
+  FAIL_UNABLE_TO_ACCOMMODATE = 5,
+  FAIL_PREV_PROTOCOL_ERROR = 6,
+  FAIL_NO_COMMON_CHANNELS = 7,
+  FAIL_UNKNOWN_GROUP = 8,
+  FAIL_BOTH_GO_INTENT_15 = 9,
+  FAIL_INCOMPATIBLE_PROV_METHOD = 10,
+  FAIL_REJECTED_BY_USER = 11,
+  SUCCESS_DEFERRED = 12,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/PairwiseCipherMask.aidl
similarity index 86%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/PairwiseCipherMask.aidl
index a522d53..d9b00e1 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/PairwiseCipherMask.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,11 +31,13 @@
 // 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.graphics.composer3;
+package android.hardware.wifi.supplicant;
 @Backing(type="int") @VintfStability
-enum BlendMode {
-  INVALID = 0,
+enum PairwiseCipherMask {
   NONE = 1,
-  PREMULTIPLIED = 2,
-  COVERAGE = 3,
+  TKIP = 8,
+  CCMP = 16,
+  GCMP_128 = 64,
+  SMS4 = 128,
+  GCMP_256 = 256,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ProtoMask.aidl
similarity index 87%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ProtoMask.aidl
index cfafc50..de92428 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ProtoMask.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,8 +31,11 @@
 // 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.graphics.composer3;
+package android.hardware.wifi.supplicant;
 @Backing(type="int") @VintfStability
-enum LayerRequest {
-  CLEAR_CLIENT_TARGET = 1,
+enum ProtoMask {
+  WPA = 1,
+  RSN = 2,
+  WAPI = 4,
+  OSEN = 8,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/RxFilterType.aidl
similarity index 85%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/RxFilterType.aidl
index cfafc50..63f5bf2 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/RxFilterType.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,8 +31,9 @@
 // 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.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum LayerRequest {
-  CLEAR_CLIENT_TARGET = 1,
+package android.hardware.wifi.supplicant;
+@Backing(type="byte") @VintfStability
+enum RxFilterType {
+  V4_MULTICAST = 0,
+  V6_MULTICAST = 1,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/SaeH2eMode.aidl
similarity index 85%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/SaeH2eMode.aidl
index cfafc50..978c337 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/SaeH2eMode.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,8 +31,10 @@
 // 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.graphics.composer3;
-@Backing(type="int") @VintfStability
-enum LayerRequest {
-  CLEAR_CLIENT_TARGET = 1,
+package android.hardware.wifi.supplicant;
+@Backing(type="byte") @VintfStability
+enum SaeH2eMode {
+  DISABLED = 0,
+  H2E_OPTIONAL = 1,
+  H2E_MANDATORY = 2,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/StaIfaceCallbackState.aidl
similarity index 80%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/StaIfaceCallbackState.aidl
index a522d53..d78cfa2 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/StaIfaceCallbackState.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,11 +31,17 @@
 // 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.graphics.composer3;
+package android.hardware.wifi.supplicant;
 @Backing(type="int") @VintfStability
-enum BlendMode {
-  INVALID = 0,
-  NONE = 1,
-  PREMULTIPLIED = 2,
-  COVERAGE = 3,
+enum StaIfaceCallbackState {
+  DISCONNECTED = 0,
+  IFACE_DISABLED = 1,
+  INACTIVE = 2,
+  SCANNING = 3,
+  AUTHENTICATING = 4,
+  ASSOCIATING = 5,
+  ASSOCIATED = 6,
+  FOURWAY_HANDSHAKE = 7,
+  GROUP_HANDSHAKE = 8,
+  COMPLETED = 9,
 }
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/StaIfaceReasonCode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/StaIfaceReasonCode.aidl
new file mode 100644
index 0000000..f26e7c5
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/StaIfaceReasonCode.aidl
@@ -0,0 +1,98 @@
+/*
+ * 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.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum StaIfaceReasonCode {
+  UNSPECIFIED = 1,
+  PREV_AUTH_NOT_VALID = 2,
+  DEAUTH_LEAVING = 3,
+  DISASSOC_DUE_TO_INACTIVITY = 4,
+  DISASSOC_AP_BUSY = 5,
+  CLASS2_FRAME_FROM_NONAUTH_STA = 6,
+  CLASS3_FRAME_FROM_NONASSOC_STA = 7,
+  DISASSOC_STA_HAS_LEFT = 8,
+  STA_REQ_ASSOC_WITHOUT_AUTH = 9,
+  PWR_CAPABILITY_NOT_VALID = 10,
+  SUPPORTED_CHANNEL_NOT_VALID = 11,
+  BSS_TRANSITION_DISASSOC = 12,
+  INVALID_IE = 13,
+  MICHAEL_MIC_FAILURE = 14,
+  FOURWAY_HANDSHAKE_TIMEOUT = 15,
+  GROUP_KEY_UPDATE_TIMEOUT = 16,
+  IE_IN_4WAY_DIFFERS = 17,
+  GROUP_CIPHER_NOT_VALID = 18,
+  PAIRWISE_CIPHER_NOT_VALID = 19,
+  AKMP_NOT_VALID = 20,
+  UNSUPPORTED_RSN_IE_VERSION = 21,
+  INVALID_RSN_IE_CAPAB = 22,
+  IEEE_802_1X_AUTH_FAILED = 23,
+  CIPHER_SUITE_REJECTED = 24,
+  TDLS_TEARDOWN_UNREACHABLE = 25,
+  TDLS_TEARDOWN_UNSPECIFIED = 26,
+  SSP_REQUESTED_DISASSOC = 27,
+  NO_SSP_ROAMING_AGREEMENT = 28,
+  BAD_CIPHER_OR_AKM = 29,
+  NOT_AUTHORIZED_THIS_LOCATION = 30,
+  SERVICE_CHANGE_PRECLUDES_TS = 31,
+  UNSPECIFIED_QOS_REASON = 32,
+  NOT_ENOUGH_BANDWIDTH = 33,
+  DISASSOC_LOW_ACK = 34,
+  EXCEEDED_TXOP = 35,
+  STA_LEAVING = 36,
+  END_TS_BA_DLS = 37,
+  UNKNOWN_TS_BA = 38,
+  TIMEOUT = 39,
+  PEERKEY_MISMATCH = 45,
+  AUTHORIZED_ACCESS_LIMIT_REACHED = 46,
+  EXTERNAL_SERVICE_REQUIREMENTS = 47,
+  INVALID_FT_ACTION_FRAME_COUNT = 48,
+  INVALID_PMKID = 49,
+  INVALID_MDE = 50,
+  INVALID_FTE = 51,
+  MESH_PEERING_CANCELLED = 52,
+  MESH_MAX_PEERS = 53,
+  MESH_CONFIG_POLICY_VIOLATION = 54,
+  MESH_CLOSE_RCVD = 55,
+  MESH_MAX_RETRIES = 56,
+  MESH_CONFIRM_TIMEOUT = 57,
+  MESH_INVALID_GTK = 58,
+  MESH_INCONSISTENT_PARAMS = 59,
+  MESH_INVALID_SECURITY_CAP = 60,
+  MESH_PATH_ERROR_NO_PROXY_INFO = 61,
+  MESH_PATH_ERROR_NO_FORWARDING_INFO = 62,
+  MESH_PATH_ERROR_DEST_UNREACHABLE = 63,
+  MAC_ADDRESS_ALREADY_EXISTS_IN_MBSS = 64,
+  MESH_CHANNEL_SWITCH_REGULATORY_REQ = 65,
+  MESH_CHANNEL_SWITCH_UNSPECIFIED = 66,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/StaIfaceStatusCode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/StaIfaceStatusCode.aidl
new file mode 100644
index 0000000..13529a5
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/StaIfaceStatusCode.aidl
@@ -0,0 +1,134 @@
+/*
+ * 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.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum StaIfaceStatusCode {
+  SUCCESS = 0,
+  UNSPECIFIED_FAILURE = 1,
+  TDLS_WAKEUP_ALTERNATE = 2,
+  TDLS_WAKEUP_REJECT = 3,
+  SECURITY_DISABLED = 5,
+  UNACCEPTABLE_LIFETIME = 6,
+  NOT_IN_SAME_BSS = 7,
+  CAPS_UNSUPPORTED = 10,
+  REASSOC_NO_ASSOC = 11,
+  ASSOC_DENIED_UNSPEC = 12,
+  NOT_SUPPORTED_AUTH_ALG = 13,
+  UNKNOWN_AUTH_TRANSACTION = 14,
+  CHALLENGE_FAIL = 15,
+  AUTH_TIMEOUT = 16,
+  AP_UNABLE_TO_HANDLE_NEW_STA = 17,
+  ASSOC_DENIED_RATES = 18,
+  ASSOC_DENIED_NOSHORT = 19,
+  SPEC_MGMT_REQUIRED = 22,
+  PWR_CAPABILITY_NOT_VALID = 23,
+  SUPPORTED_CHANNEL_NOT_VALID = 24,
+  ASSOC_DENIED_NO_SHORT_SLOT_TIME = 25,
+  ASSOC_DENIED_NO_HT = 27,
+  R0KH_UNREACHABLE = 28,
+  ASSOC_DENIED_NO_PCO = 29,
+  ASSOC_REJECTED_TEMPORARILY = 30,
+  ROBUST_MGMT_FRAME_POLICY_VIOLATION = 31,
+  UNSPECIFIED_QOS_FAILURE = 32,
+  DENIED_INSUFFICIENT_BANDWIDTH = 33,
+  DENIED_POOR_CHANNEL_CONDITIONS = 34,
+  DENIED_QOS_NOT_SUPPORTED = 35,
+  REQUEST_DECLINED = 37,
+  INVALID_PARAMETERS = 38,
+  REJECTED_WITH_SUGGESTED_CHANGES = 39,
+  INVALID_IE = 40,
+  GROUP_CIPHER_NOT_VALID = 41,
+  PAIRWISE_CIPHER_NOT_VALID = 42,
+  AKMP_NOT_VALID = 43,
+  UNSUPPORTED_RSN_IE_VERSION = 44,
+  INVALID_RSN_IE_CAPAB = 45,
+  CIPHER_REJECTED_PER_POLICY = 46,
+  TS_NOT_CREATED = 47,
+  DIRECT_LINK_NOT_ALLOWED = 48,
+  DEST_STA_NOT_PRESENT = 49,
+  DEST_STA_NOT_QOS_STA = 50,
+  ASSOC_DENIED_LISTEN_INT_TOO_LARGE = 51,
+  INVALID_FT_ACTION_FRAME_COUNT = 52,
+  INVALID_PMKID = 53,
+  INVALID_MDIE = 54,
+  INVALID_FTIE = 55,
+  REQUESTED_TCLAS_NOT_SUPPORTED = 56,
+  INSUFFICIENT_TCLAS_PROCESSING_RESOURCES = 57,
+  TRY_ANOTHER_BSS = 58,
+  GAS_ADV_PROTO_NOT_SUPPORTED = 59,
+  NO_OUTSTANDING_GAS_REQ = 60,
+  GAS_RESP_NOT_RECEIVED = 61,
+  STA_TIMED_OUT_WAITING_FOR_GAS_RESP = 62,
+  GAS_RESP_LARGER_THAN_LIMIT = 63,
+  REQ_REFUSED_HOME = 64,
+  ADV_SRV_UNREACHABLE = 65,
+  REQ_REFUSED_SSPN = 67,
+  REQ_REFUSED_UNAUTH_ACCESS = 68,
+  INVALID_RSNIE = 72,
+  U_APSD_COEX_NOT_SUPPORTED = 73,
+  U_APSD_COEX_MODE_NOT_SUPPORTED = 74,
+  BAD_INTERVAL_WITH_U_APSD_COEX = 75,
+  ANTI_CLOGGING_TOKEN_REQ = 76,
+  FINITE_CYCLIC_GROUP_NOT_SUPPORTED = 77,
+  CANNOT_FIND_ALT_TBTT = 78,
+  TRANSMISSION_FAILURE = 79,
+  REQ_TCLAS_NOT_SUPPORTED = 80,
+  TCLAS_RESOURCES_EXCHAUSTED = 81,
+  REJECTED_WITH_SUGGESTED_BSS_TRANSITION = 82,
+  REJECT_WITH_SCHEDULE = 83,
+  REJECT_NO_WAKEUP_SPECIFIED = 84,
+  SUCCESS_POWER_SAVE_MODE = 85,
+  PENDING_ADMITTING_FST_SESSION = 86,
+  PERFORMING_FST_NOW = 87,
+  PENDING_GAP_IN_BA_WINDOW = 88,
+  REJECT_U_PID_SETTING = 89,
+  REFUSED_EXTERNAL_REASON = 92,
+  REFUSED_AP_OUT_OF_MEMORY = 93,
+  REJECTED_EMERGENCY_SERVICE_NOT_SUPPORTED = 94,
+  QUERY_RESP_OUTSTANDING = 95,
+  REJECT_DSE_BAND = 96,
+  TCLAS_PROCESSING_TERMINATED = 97,
+  TS_SCHEDULE_CONFLICT = 98,
+  DENIED_WITH_SUGGESTED_BAND_AND_CHANNEL = 99,
+  MCCAOP_RESERVATION_CONFLICT = 100,
+  MAF_LIMIT_EXCEEDED = 101,
+  MCCA_TRACK_LIMIT_EXCEEDED = 102,
+  DENIED_DUE_TO_SPECTRUM_MANAGEMENT = 103,
+  ASSOC_DENIED_NO_VHT = 104,
+  ENABLEMENT_DENIED = 105,
+  RESTRICTION_FROM_AUTHORIZED_GDB = 106,
+  AUTHORIZATION_DEENABLED = 107,
+  FILS_AUTHENTICATION_FAILURE = 112,
+  UNKNOWN_AUTHENTICATION_SERVER = 113,
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/SupplicantStatusCode.aidl
similarity index 76%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/SupplicantStatusCode.aidl
index a522d53..32d71a3 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/SupplicantStatusCode.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,11 +31,18 @@
 // 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.graphics.composer3;
+package android.hardware.wifi.supplicant;
 @Backing(type="int") @VintfStability
-enum BlendMode {
-  INVALID = 0,
-  NONE = 1,
-  PREMULTIPLIED = 2,
-  COVERAGE = 3,
+enum SupplicantStatusCode {
+  SUCCESS = 0,
+  FAILURE_UNKNOWN = 1,
+  FAILURE_ARGS_INVALID = 2,
+  FAILURE_IFACE_INVALID = 3,
+  FAILURE_IFACE_UNKNOWN = 4,
+  FAILURE_IFACE_EXISTS = 5,
+  FAILURE_IFACE_DISABLED = 6,
+  FAILURE_IFACE_NOT_DISCONNECTED = 7,
+  FAILURE_NETWORK_INVALID = 8,
+  FAILURE_NETWORK_UNKNOWN = 9,
+  FAILURE_UNSUPPORTED = 10,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/TransitionDisableIndication.aidl
similarity index 84%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/TransitionDisableIndication.aidl
index a522d53..7c63217 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/TransitionDisableIndication.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,11 +31,11 @@
 // 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.graphics.composer3;
+package android.hardware.wifi.supplicant;
 @Backing(type="int") @VintfStability
-enum BlendMode {
-  INVALID = 0,
-  NONE = 1,
-  PREMULTIPLIED = 2,
-  COVERAGE = 3,
+enum TransitionDisableIndication {
+  USE_WPA3_PERSONAL = 1,
+  USE_SAE_PK = 2,
+  USE_WPA3_ENTERPRISE = 4,
+  USE_ENHANCED_OPEN = 8,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WifiTechnology.aidl
similarity index 86%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WifiTechnology.aidl
index a522d53..ad36e68 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WifiTechnology.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,11 +31,12 @@
 // 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.graphics.composer3;
+package android.hardware.wifi.supplicant;
 @Backing(type="int") @VintfStability
-enum BlendMode {
-  INVALID = 0,
-  NONE = 1,
-  PREMULTIPLIED = 2,
-  COVERAGE = 3,
+enum WifiTechnology {
+  UNKNOWN = 0,
+  LEGACY = 1,
+  HT = 2,
+  VHT = 3,
+  HE = 4,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl
similarity index 86%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl
index a522d53..43772af 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,11 +31,11 @@
 // 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.graphics.composer3;
+package android.hardware.wifi.supplicant;
 @Backing(type="int") @VintfStability
-enum BlendMode {
-  INVALID = 0,
-  NONE = 1,
-  PREMULTIPLIED = 2,
-  COVERAGE = 3,
+enum WpaDriverCapabilitiesMask {
+  MBO = 1,
+  OCE = 2,
+  SAE_PK = 4,
+  WFD_R2 = 8,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WpsConfigError.aidl
similarity index 68%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WpsConfigError.aidl
index a522d53..c48b282 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WpsConfigError.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,11 +31,28 @@
 // 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.graphics.composer3;
+package android.hardware.wifi.supplicant;
 @Backing(type="int") @VintfStability
-enum BlendMode {
-  INVALID = 0,
-  NONE = 1,
-  PREMULTIPLIED = 2,
-  COVERAGE = 3,
+enum WpsConfigError {
+  NO_ERROR = 0,
+  OOB_IFACE_READ_ERROR = 1,
+  DECRYPTION_CRC_FAILURE = 2,
+  CHAN_24_NOT_SUPPORTED = 3,
+  CHAN_50_NOT_SUPPORTED = 4,
+  SIGNAL_TOO_WEAK = 5,
+  NETWORK_AUTH_FAILURE = 6,
+  NETWORK_ASSOC_FAILURE = 7,
+  NO_DHCP_RESPONSE = 8,
+  FAILED_DHCP_CONFIG = 9,
+  IP_ADDR_CONFLICT = 10,
+  NO_CONN_TO_REGISTRAR = 11,
+  MULTIPLE_PBC_DETECTED = 12,
+  ROGUE_SUSPECTED = 13,
+  DEVICE_BUSY = 14,
+  SETUP_LOCKED = 15,
+  MSG_TIMEOUT = 16,
+  REG_SESS_TIMEOUT = 17,
+  DEV_PASSWORD_AUTH_FAILURE = 18,
+  CHAN_60G_NOT_SUPPORTED = 19,
+  PUBLIC_KEY_HASH_MISMATCH = 20,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WpsConfigMethods.aidl
similarity index 78%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WpsConfigMethods.aidl
index a522d53..c98c479 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WpsConfigMethods.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,11 +31,21 @@
 // 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.graphics.composer3;
+package android.hardware.wifi.supplicant;
 @Backing(type="int") @VintfStability
-enum BlendMode {
-  INVALID = 0,
-  NONE = 1,
-  PREMULTIPLIED = 2,
-  COVERAGE = 3,
+enum WpsConfigMethods {
+  USBA = 1,
+  ETHERNET = 2,
+  LABEL = 4,
+  DISPLAY = 8,
+  EXT_NFC_TOKEN = 16,
+  INT_NFC_TOKEN = 32,
+  NFC_INTERFACE = 64,
+  PUSHBUTTON = 128,
+  KEYPAD = 256,
+  VIRT_PUSHBUTTON = 640,
+  PHY_PUSHBUTTON = 1152,
+  P2PS = 4096,
+  VIRT_DISPLAY = 8200,
+  PHY_DISPLAY = 16392,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WpsDevPasswordId.aidl
similarity index 81%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WpsDevPasswordId.aidl
index a522d53..975f1ab 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WpsDevPasswordId.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,11 +31,15 @@
 // 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.graphics.composer3;
+package android.hardware.wifi.supplicant;
 @Backing(type="int") @VintfStability
-enum BlendMode {
-  INVALID = 0,
-  NONE = 1,
-  PREMULTIPLIED = 2,
-  COVERAGE = 3,
+enum WpsDevPasswordId {
+  DEFAULT = 0,
+  USER_SPECIFIED = 1,
+  MACHINE_SPECIFIED = 2,
+  REKEY = 3,
+  PUSHBUTTON = 4,
+  REGISTRAR_SPECIFIED = 5,
+  NFC_CONNECTION_HANDOVER = 7,
+  P2PS_DEFAULT = 8,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WpsErrorIndication.aidl
similarity index 84%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WpsErrorIndication.aidl
index a522d53..50e69ff 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/BlendMode.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WpsErrorIndication.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,11 +31,11 @@
 // 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.graphics.composer3;
+package android.hardware.wifi.supplicant;
 @Backing(type="int") @VintfStability
-enum BlendMode {
-  INVALID = 0,
-  NONE = 1,
-  PREMULTIPLIED = 2,
-  COVERAGE = 3,
+enum WpsErrorIndication {
+  NO_ERROR = 0,
+  SECURITY_TKIP_ONLY_PROHIBITED = 1,
+  SECURITY_WEP_PROHIBITED = 2,
+  AUTH_FAILURE = 3,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WpsProvisionMethod.aidl
similarity index 87%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WpsProvisionMethod.aidl
index cfafc50..f6dba23 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerRequest.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WpsProvisionMethod.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,8 +31,10 @@
 // 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.graphics.composer3;
+package android.hardware.wifi.supplicant;
 @Backing(type="int") @VintfStability
-enum LayerRequest {
-  CLEAR_CLIENT_TARGET = 1,
+enum WpsProvisionMethod {
+  PBC = 0,
+  DISPLAY = 1,
+  KEYPAD = 2,
 }
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/AnqpData.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/AnqpData.aidl
new file mode 100644
index 0000000..5bc1015
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/AnqpData.aidl
@@ -0,0 +1,33 @@
+/*
+ * 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.wifi.supplicant;
+
+/**
+ * ANQP data for IEEE Std 802.11-2016.
+ * The format of the data within these elements follows the IEEE
+ * Std 802.11-2016 standard, section 9.4.5.
+ */
+@VintfStability
+parcelable AnqpData {
+    byte[] venueName;
+    byte[] roamingConsortium;
+    byte[] ipAddrTypeAvailability;
+    byte[] naiRealm;
+    byte[] anqp3gppCellularNetwork;
+    byte[] domainName;
+    byte[] venueUrl;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/AnqpInfoId.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/AnqpInfoId.aidl
new file mode 100644
index 0000000..7b2eb23
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/AnqpInfoId.aidl
@@ -0,0 +1,32 @@
+/*
+ * 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.wifi.supplicant;
+
+/**
+ * Access Network Query Protocol info ID elements
+ * for IEEE Std 802.11u-2011.
+ */
+@VintfStability
+@Backing(type="int")
+enum AnqpInfoId {
+    VENUE_NAME = 258,
+    ROAMING_CONSORTIUM = 261,
+    IP_ADDR_TYPE_AVAILABILITY = 262,
+    NAI_REALM = 263,
+    ANQP_3GPP_CELLULAR_NETWORK = 264,
+    DOMAIN_NAME = 268,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/AssociationRejectionData.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/AssociationRejectionData.aidl
new file mode 100644
index 0000000..5673021
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/AssociationRejectionData.aidl
@@ -0,0 +1,69 @@
+/*
+ * 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.wifi.supplicant;
+
+import android.hardware.wifi.supplicant.MboAssocDisallowedReasonCode;
+import android.hardware.wifi.supplicant.OceRssiBasedAssocRejectAttr;
+import android.hardware.wifi.supplicant.StaIfaceStatusCode;
+
+/**
+ * Association Rejection related information.
+ */
+@VintfStability
+parcelable AssociationRejectionData {
+    /**
+     * SSID of the AP that rejected the association.
+     */
+    byte[] ssid;
+    /**
+     * BSSID of the AP that rejected the association.
+     */
+    byte[/* 6 */] bssid;
+    /*
+     * 802.11 code to indicate the reject reason.
+     * Refer to section 8.4.1.9 of IEEE 802.11 spec.
+     */
+    StaIfaceStatusCode statusCode;
+    /*
+     * Flag to indicate that failure is due to timeout rather than
+     * explicit rejection response from the AP.
+     */
+    boolean timedOut;
+    /**
+     * Flag to indicate that MboAssocDisallowedReasonCode is present
+     * in the (Re-)Association response frame.
+     */
+    boolean isMboAssocDisallowedReasonCodePresent;
+    /**
+     * mboAssocDisallowedReason is extracted from MBO association disallowed attribute
+     * in (Re-)Association response frame to indicate that the AP is not accepting new
+     * associations.
+     * Refer MBO spec v1.2 section 4.2.4 Table 13 for the details of reason code.
+     * The value is undefined if isMboAssocDisallowedReasonCodePresent is false.
+     */
+    MboAssocDisallowedReasonCode mboAssocDisallowedReason;
+    /**
+     * Flag to indicate that OceRssiBasedAssocRejectAttr is present
+     * in the (Re-)Association response frame.
+     */
+    boolean isOceRssiBasedAssocRejectAttrPresent;
+    /*
+     * OCE RSSI-based (Re-)Association rejection attribute.
+     * The contents are undefined if isOceRssiBasedAssocRejectAttrPresent is false.
+     */
+    OceRssiBasedAssocRejectAttr oceRssiBasedAssocRejectData;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/AuthAlgMask.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/AuthAlgMask.aidl
new file mode 100644
index 0000000..e8101ea
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/AuthAlgMask.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.wifi.supplicant;
+
+/**
+ * Possible mask of values for AuthAlg param.
+ * See /external/wpa_supplicant_8/src/common/defs.h for
+ * all possible values (starting at WPA_AUTH_ALG_OPEN).
+ */
+@VintfStability
+@Backing(type="int")
+enum AuthAlgMask {
+    OPEN = 1 << 0,
+    SHARED = 1 << 1,
+    LEAP = 1 << 2,
+    SAE = 1 << 4,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/BssTmData.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/BssTmData.aidl
new file mode 100644
index 0000000..233e54a
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/BssTmData.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.wifi.supplicant;
+
+import android.hardware.wifi.supplicant.BssTmDataFlagsMask;
+import android.hardware.wifi.supplicant.BssTmStatusCode;
+import android.hardware.wifi.supplicant.MboCellularDataConnectionPrefValue;
+import android.hardware.wifi.supplicant.MboTransitionReasonCode;
+
+/**
+ * Data retrieved from received BSS transition management request frame.
+ */
+@VintfStability
+parcelable BssTmData {
+    /*
+     * Status code filled in BSS transition management response frame
+     */
+    BssTmStatusCode status;
+    /*
+     * Bitmask of BssTmDataFlagsMask
+     */
+    BssTmDataFlagsMask flags;
+    /*
+     * Duration for which STA shouldn't try to re-associate.
+     */
+    int assocRetryDelayMs;
+    /*
+     * Reason for BSS transition request.
+     */
+    MboTransitionReasonCode mboTransitionReason;
+    /*
+     * Cellular Data Connection preference value.
+     */
+    MboCellularDataConnectionPrefValue mboCellPreference;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/BssTmDataFlagsMask.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/BssTmDataFlagsMask.aidl
new file mode 100644
index 0000000..1eb75f4
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/BssTmDataFlagsMask.aidl
@@ -0,0 +1,57 @@
+/*
+ * 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.wifi.supplicant;
+
+/**
+ * Bitmask of various information retrieved from BSS transition management request frame.
+ */
+@VintfStability
+@Backing(type="int")
+enum BssTmDataFlagsMask {
+    /**
+     * Preferred candidate list included.
+     */
+    WNM_MODE_PREFERRED_CANDIDATE_LIST_INCLUDED = 1 << 0,
+    /**
+     * Abridged.
+     */
+    WNM_MODE_ABRIDGED = 1 << 1,
+    /**
+     * Disassociation Imminent.
+     */
+    WNM_MODE_DISASSOCIATION_IMMINENT = 1 << 2,
+    /**
+     * BSS termination included.
+     */
+    WNM_MODE_BSS_TERMINATION_INCLUDED = 1 << 3,
+    /**
+     * ESS Disassociation Imminent.
+     */
+    WNM_MODE_ESS_DISASSOCIATION_IMMINENT = 1 << 4,
+    /**
+     * MBO transition reason code included.
+     */
+    MBO_TRANSITION_REASON_CODE_INCLUDED = 1 << 5,
+    /**
+     * MBO retry delay time included.
+     */
+    MBO_ASSOC_RETRY_DELAY_INCLUDED = 1 << 6,
+    /**
+     * MBO cellular data connection preference value included.
+     */
+    MBO_CELLULAR_DATA_CONNECTION_PREFERENCE_INCLUDED = 1 << 7,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/BssTmStatusCode.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/BssTmStatusCode.aidl
new file mode 100644
index 0000000..51fbfed
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/BssTmStatusCode.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.wifi.supplicant;
+
+/**
+ * IEEE Std 802.11-2016 - Table 9-357.
+ * BTM status code filled in BSS transition management response frame.
+ */
+@VintfStability
+@Backing(type="byte")
+enum BssTmStatusCode {
+    ACCEPT = 0,
+    REJECT_UNSPECIFIED = 1,
+    REJECT_INSUFFICIENT_BEACON = 2,
+    REJECT_INSUFFICIENT_CAPABITY = 3,
+    REJECT_BSS_TERMINATION_UNDESIRED = 4,
+    REJECT_BSS_TERMINATION_DELAY_REQUEST = 5,
+    REJECT_STA_CANDIDATE_LIST_PROVIDED = 6,
+    REJECT_NO_SUITABLE_CANDIDATES = 7,
+    REJECT_LEAVING_ESS = 8,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/BssidChangeReason.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/BssidChangeReason.aidl
new file mode 100644
index 0000000..8532bd7
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/BssidChangeReason.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.wifi.supplicant;
+
+/**
+ * BSSID change Reasons.
+ */
+@VintfStability
+@Backing(type="byte")
+enum BssidChangeReason {
+    /**
+     * Started association with new bssid.
+     */
+    ASSOC_START = 0,
+    /**
+     * Completed association with new bssid.
+     */
+    ASSOC_COMPLETE = 1,
+    /**
+     * Dis-association with current bssid.
+     */
+    DISASSOC = 2,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/BtCoexistenceMode.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/BtCoexistenceMode.aidl
new file mode 100644
index 0000000..4972744
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/BtCoexistenceMode.aidl
@@ -0,0 +1,29 @@
+/*
+ * 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.wifi.supplicant;
+
+/**
+ * Enum describing the modes of BT coexistence supported
+ * via driver commands.
+ */
+@VintfStability
+@Backing(type="byte")
+enum BtCoexistenceMode {
+    ENABLED = 0,
+    DISABLED = 1,
+    SENSE = 2,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ConnectionCapabilities.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ConnectionCapabilities.aidl
new file mode 100644
index 0000000..1718413
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ConnectionCapabilities.aidl
@@ -0,0 +1,47 @@
+/*
+ * 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.wifi.supplicant;
+
+import android.hardware.wifi.supplicant.LegacyMode;
+import android.hardware.wifi.supplicant.WifiTechnology;
+
+/**
+ * Connection Capabilities supported by current network and device
+ */
+@VintfStability
+parcelable ConnectionCapabilities {
+    /**
+     * Wifi Technology
+     */
+    WifiTechnology technology;
+    /**
+     * channel bandwidth
+     */
+    int channelBandwidth;
+    /**
+     * max number of Tx spatial streams
+     */
+    int maxNumberTxSpatialStreams;
+    /**
+     * max number of Rx spatial streams
+     */
+    int maxNumberRxSpatialStreams;
+    /**
+     * detailed network mode for legacy network
+     */
+    LegacyMode legacyMode;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/DebugLevel.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/DebugLevel.aidl
new file mode 100644
index 0000000..7caa406
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/DebugLevel.aidl
@@ -0,0 +1,33 @@
+/*
+ * 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.wifi.supplicant;
+
+/**
+ * Debug levels for the supplicant.
+ * Only log messages with a level greater than the set level
+ * (via |setDebugParams|) will be logged.
+ */
+@VintfStability
+@Backing(type="int")
+enum DebugLevel {
+    EXCESSIVE = 0,
+    MSGDUMP = 1,
+    DEBUG = 2,
+    INFO = 3,
+    WARNING = 4,
+    ERROR = 5,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/DppAkm.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/DppAkm.aidl
new file mode 100644
index 0000000..63fff54
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/DppAkm.aidl
@@ -0,0 +1,29 @@
+/*
+ * 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.wifi.supplicant;
+
+/**
+ * DppAkm: The various AKMs that can be provisioned using DPP.
+ */
+@VintfStability
+@Backing(type="int")
+enum DppAkm {
+    PSK,
+    PSK_SAE,
+    SAE,
+    DPP,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/DppCurve.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/DppCurve.aidl
new file mode 100644
index 0000000..ea57505
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/DppCurve.aidl
@@ -0,0 +1,32 @@
+/*
+ * 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.wifi.supplicant;
+
+/**
+ * DppCurve: Elliptic curve cryptography type used to generate DPP
+ * public/private key pair.
+ */
+@VintfStability
+@Backing(type="int")
+enum DppCurve {
+    PRIME256V1,
+    SECP384R1,
+    SECP521R1,
+    BRAINPOOLP256R1,
+    BRAINPOOLP384R1,
+    BRAINPOOLP512R1,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/DppEventType.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/DppEventType.aidl
new file mode 100644
index 0000000..4b9b38b
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/DppEventType.aidl
@@ -0,0 +1,27 @@
+/*
+ * 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.wifi.supplicant;
+
+/**
+ * DppEventType: Major events for DPP (Easy Connect) Configurator
+ */
+@VintfStability
+@Backing(type="int")
+enum DppEventType {
+    CONFIGURATION_SENT,
+    CONFIGURATION_APPLIED,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/DppFailureCode.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/DppFailureCode.aidl
new file mode 100644
index 0000000..5c0c6e8
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/DppFailureCode.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.
+ */
+
+package android.hardware.wifi.supplicant;
+
+/**
+ * DppFailureCode: Error codes for DPP (Easy Connect)
+ */
+@VintfStability
+@Backing(type="int")
+enum DppFailureCode {
+    INVALID_URI,
+    AUTHENTICATION,
+    NOT_COMPATIBLE,
+    CONFIGURATION,
+    BUSY,
+    TIMEOUT,
+    FAILURE,
+    NOT_SUPPORTED,
+    CONFIGURATION_REJECTED,
+    CANNOT_FIND_NETWORK,
+    ENROLLEE_AUTHENTICATION,
+    /**
+     * Failure to generate a DPP URI.
+     */
+    URI_GENERATION,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/DppNetRole.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/DppNetRole.aidl
new file mode 100644
index 0000000..d92cfa3
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/DppNetRole.aidl
@@ -0,0 +1,27 @@
+/*
+ * 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.wifi.supplicant;
+
+/**
+ * DppNetRole: The network role that the configurator offers the enrollee.
+ */
+@VintfStability
+@Backing(type="int")
+enum DppNetRole {
+    STA,
+    AP,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/DppProgressCode.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/DppProgressCode.aidl
new file mode 100644
index 0000000..f8b35c0
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/DppProgressCode.aidl
@@ -0,0 +1,29 @@
+/*
+ * 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.wifi.supplicant;
+
+/**
+ * DppProgressCode: Progress codes for DPP (Easy Connect)
+ */
+@VintfStability
+@Backing(type="int")
+enum DppProgressCode {
+    AUTHENTICATION_SUCCESS,
+    RESPONSE_PENDING,
+    CONFIGURATION_SENT_WAITING_RESPONSE,
+    CONFIGURATION_ACCEPTED,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/DppResponderBootstrapInfo.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/DppResponderBootstrapInfo.aidl
new file mode 100644
index 0000000..4f4778d
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/DppResponderBootstrapInfo.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.wifi.supplicant;
+
+/**
+ * DPP bootstrap info generated for responder mode operation
+ */
+@VintfStability
+parcelable DppResponderBootstrapInfo {
+    /**
+     * Generated bootstrap identifier
+     */
+    int bootstrapId;
+    /**
+     * The Wi-Fi channel that the DPP responder is listening on.
+     */
+    int listenChannel;
+    /**
+     * Bootstrapping URI per DPP specification, "section 5.2 Bootstrapping
+     * information", may contain listen channel, MAC address, public key, or other information.
+     */
+    String uri;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/EapErrorCode.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/EapErrorCode.aidl
new file mode 100644
index 0000000..49f9e34
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/EapErrorCode.aidl
@@ -0,0 +1,30 @@
+/*
+ * 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.wifi.supplicant;
+
+/*
+ * EapErrorCode: Error code for EAP or EAP Method as per RFC-4186
+ */
+@VintfStability
+@Backing(type="int")
+enum EapErrorCode {
+    SIM_GENERAL_FAILURE_AFTER_AUTH = 0,
+    SIM_TEMPORARILY_DENIED = 1026,
+    SIM_NOT_SUBSCRIBED = 1031,
+    SIM_GENERAL_FAILURE_BEFORE_AUTH = 16384,
+    SIM_VENDOR_SPECIFIC_EXPIRED_CERT = 16385,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/EapMethod.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/EapMethod.aidl
new file mode 100644
index 0000000..351fb6c
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/EapMethod.aidl
@@ -0,0 +1,33 @@
+/*
+ * 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.wifi.supplicant;
+
+/**
+ * Possble values for EapMethod param.
+ */
+@VintfStability
+@Backing(type="int")
+enum EapMethod {
+    PEAP = 0,
+    TLS = 1,
+    TTLS = 2,
+    PWD = 3,
+    SIM = 4,
+    AKA = 5,
+    AKA_PRIME = 6,
+    WFA_UNAUTH_TLS = 7,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/EapPhase2Method.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/EapPhase2Method.aidl
new file mode 100644
index 0000000..a7eeca8
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/EapPhase2Method.aidl
@@ -0,0 +1,33 @@
+/*
+ * 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.wifi.supplicant;
+
+/**
+ * Possble values for Phase2Method param.
+ */
+@VintfStability
+@Backing(type="int")
+enum EapPhase2Method {
+    NONE = 0,
+    PAP = 1,
+    MSPAP = 2,
+    MSPAPV2 = 3,
+    GTC = 4,
+    SIM = 5,
+    AKA = 6,
+    AKA_PRIME = 7,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ExtRadioWorkDefaults.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ExtRadioWorkDefaults.aidl
new file mode 100644
index 0000000..7325ba2
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ExtRadioWorkDefaults.aidl
@@ -0,0 +1,23 @@
+/*
+ * 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.wifi.supplicant;
+
+@VintfStability
+@Backing(type="int")
+enum ExtRadioWorkDefaults {
+    TIMEOUT_IN_SECS = 10,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/FreqRange.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/FreqRange.aidl
new file mode 100644
index 0000000..a88c011
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/FreqRange.aidl
@@ -0,0 +1,27 @@
+/*
+ * 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.wifi.supplicant;
+
+/**
+ * Use to specify a range of frequencies.
+ * For example: 2412-2432,2462,5000-6000, etc.
+ */
+@VintfStability
+parcelable FreqRange {
+    int min;
+    int max;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/GroupCipherMask.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/GroupCipherMask.aidl
new file mode 100644
index 0000000..d5b26ad
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/GroupCipherMask.aidl
@@ -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 android.hardware.wifi.supplicant;
+
+/**
+ * Possible mask of values for GroupCipher param.
+ * See /external/wpa_supplicant_8/src/common/defs.h for
+ * all possible values (starting at WPA_CIPHER_WEP40).
+ */
+@VintfStability
+@Backing(type="int")
+enum GroupCipherMask {
+    WEP40 = 1 << 1,
+    WEP104 = 1 << 2,
+    TKIP = 1 << 3,
+    CCMP = 1 << 4,
+    GTK_NOT_USED = 1 << 14,
+    /**
+     * GCMP-256 Group Cipher
+     */
+    GCMP_256 = 1 << 8,
+    /**
+     * SMS4 Group Cipher
+     */
+    SMS4 = 1 << 7,
+    /**
+     * GCMP-128 Group Cipher
+     */
+    GCMP_128 = 1 << 6,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/GroupMgmtCipherMask.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/GroupMgmtCipherMask.aidl
new file mode 100644
index 0000000..07544f0
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/GroupMgmtCipherMask.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.wifi.supplicant;
+
+/**
+ * Possble mask of values for GroupMgmtCipher param.
+ * See /external/wpa_supplicant_8/src/common/defs.h for
+ * all possible values (starting at WPA_CIPHER_BIP_GMAC_128).
+ */
+@VintfStability
+@Backing(type="int")
+enum GroupMgmtCipherMask {
+    /**
+     * BIP_GMAC-128 Group Management Cipher
+     */
+    BIP_GMAC_128 = 1 << 11,
+    /**
+     * BIP_GMAC-256 Group Management Cipher
+     */
+    BIP_GMAC_256 = 1 << 12,
+    /**
+     * BIP_CMAC-256 Group Management Cipher
+     */
+    BIP_CMAC_256 = 1 << 13,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/GsmRand.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/GsmRand.aidl
new file mode 100644
index 0000000..4e31323
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/GsmRand.aidl
@@ -0,0 +1,28 @@
+/*
+ * 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.wifi.supplicant;
+
+/**
+ * Byte array with expected length 16. Used by NetworkRequestEapSimGsmAuthParams
+ * to pass an array of byte arrays, as 2D arrays are not supported in AIDL.
+ *
+ * TODO (b/210705533): Replace this type with a 2D byte array.
+ */
+@VintfStability
+parcelable GsmRand {
+    byte[/* 16 */] data;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/Hs20AnqpData.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/Hs20AnqpData.aidl
new file mode 100644
index 0000000..bdb9ec6
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/Hs20AnqpData.aidl
@@ -0,0 +1,30 @@
+/*
+ * 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.wifi.supplicant;
+
+/**
+ * ANQP data for Hotspot 2.0.
+ * The format of the data within these elements follows the Hotspot 2.0
+ * standard.
+ */
+@VintfStability
+parcelable Hs20AnqpData {
+    byte[] operatorFriendlyName;
+    byte[] wanMetrics;
+    byte[] connectionCapability;
+    byte[] osuProvidersList;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/Hs20AnqpSubtypes.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/Hs20AnqpSubtypes.aidl
new file mode 100644
index 0000000..e08411d
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/Hs20AnqpSubtypes.aidl
@@ -0,0 +1,30 @@
+/*
+ * 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.wifi.supplicant;
+
+/**
+ * Access Network Query Protocol subtype elements
+ * for Hotspot 2.0.
+ */
+@VintfStability
+@Backing(type="int")
+enum Hs20AnqpSubtypes {
+    OPERATOR_FRIENDLY_NAME = 3,
+    WAN_METRICS = 4,
+    CONNECTION_CAPABILITY = 5,
+    OSU_PROVIDERS_LIST = 8,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicant.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicant.aidl
new file mode 100644
index 0000000..2ac1db7
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicant.aidl
@@ -0,0 +1,161 @@
+/*
+ * 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.wifi.supplicant;
+
+import android.hardware.wifi.supplicant.DebugLevel;
+import android.hardware.wifi.supplicant.ISupplicantCallback;
+import android.hardware.wifi.supplicant.ISupplicantP2pIface;
+import android.hardware.wifi.supplicant.ISupplicantStaIface;
+import android.hardware.wifi.supplicant.IfaceInfo;
+import android.hardware.wifi.supplicant.IfaceType;
+
+/**
+ * Interface exposed by the supplicant AIDL service registered
+ * with the service manager. This is the root level object for
+ * any of the supplicant interactions.
+ */
+@VintfStability
+interface ISupplicant {
+    /**
+     * Default timeout (in seconds) for external radio work.
+     */
+    const int EXT_RADIO_WORK_TIMEOUT_IN_SECS = 10;
+
+    /**
+     * Registers a wireless interface in supplicant.
+     *
+     * @param ifName Name of the interface (e.g wlan0).
+     * @return AIDL interface object representing the interface if
+     *         successful, null otherwise.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_EXISTS|
+     */
+    ISupplicantP2pIface addP2pInterface(in String ifName);
+    ISupplicantStaIface addStaInterface(in String ifName);
+
+    /**
+     * Get the debug level set.
+     *
+     * @return one of |DebugLevel| values.
+     */
+    DebugLevel getDebugLevel();
+
+    /**
+     * Gets an AIDL interface object for the interface corresponding
+     * to an iface name which the supplicant already controls.
+     *
+     * @param ifName Name of the interface retrieved
+     *        using |listInterfaces|.
+     * @return AIDL interface object representing the interface if
+     *         successful, null otherwise.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_UNKNOWN|
+     */
+    ISupplicantP2pIface getP2pInterface(in String ifName);
+    ISupplicantStaIface getStaInterface(in String ifName);
+
+    /**
+     * Get whether the keys are shown in the debug logs or not.
+     *
+     * @return true if set, false otherwise.
+     */
+    boolean isDebugShowKeysEnabled();
+
+    /**
+     * Get whether the timestamps are shown in the debug logs or not.
+     *
+     * @return true if set, false otherwise.
+     */
+    boolean isDebugShowTimestampEnabled();
+
+    /**
+     * Retrieve a list of all interfaces controlled by the supplicant.
+     *
+     * The corresponding |ISupplicantIface| object for any interface can be
+     * retrieved using the proper |getInterface| method.
+     *
+     * @return List of all interfaces controlled by the supplicant.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+     */
+    IfaceInfo[] listInterfaces();
+
+    /**
+     * Register for callbacks from the supplicant service.
+     *
+     * These callbacks are invoked for global events that are not specific
+     * to any interface or network. Registration of multiple callback
+     * objects is supported. These objects must be deleted when the corresponding
+     * client process is dead.
+     *
+     * @param callback An instance of the |ISupplicantCallback| AIDL interface
+     *        object.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+     */
+    void registerCallback(in ISupplicantCallback callback);
+
+    /**
+     * Deregisters a wireless interface from supplicant.
+     *
+     * @param ifaceInfo Combination of the interface type and name (e.g wlan0).
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_UNKNOWN|
+     */
+    void removeInterface(in IfaceInfo ifaceInfo);
+
+    /**
+     * Set concurrency priority.
+     *
+     * When both P2P and STA mode ifaces are active, this must be used
+     * to prioritize either STA or P2P connection to resolve conflicts
+     * arising during single channel concurrency.
+     *
+     * @param type The type of iface to prioritize.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+     */
+    void setConcurrencyPriority(in IfaceType type);
+
+    /**
+     * Set debug parameters for the supplicant.
+     *
+     * @param level Debug logging level for the supplicant.
+     *        (one of |DebugLevel| values).
+     * @param timestamp Determines whether to show timestamps in logs or
+     *        not.
+     * @param showKeys Determines whether to show keys in debug logs or
+     *        not.
+     *        CAUTION: Do not set this param in production code!
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+     */
+    void setDebugParams(in DebugLevel level, in boolean showTimestamp, in boolean showKeys);
+
+    /**
+     * Terminate the service.
+     * This must de-register the service and clear all state. If this HAL
+     * supports the lazy HAL protocol, then this may trigger daemon to exit and
+     * wait to be restarted.
+     */
+    oneway void terminate();
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantCallback.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantCallback.aidl
new file mode 100644
index 0000000..6f15900
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantCallback.aidl
@@ -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.
+ */
+
+package android.hardware.wifi.supplicant;
+
+/**
+ * Callback Interface exposed by the supplicant service (ISupplicant).
+ *
+ * Clients need to host an instance of this AIDL interface object and
+ * pass a reference of the object to the supplicant via the
+ * |ISupplicant.registerCallback| method.
+ */
+@VintfStability
+interface ISupplicantCallback {
+    /**
+     * Used to indicate that a new interface has been created.
+     *
+     * @param ifaceName Name of the network interface, e.g., wlan0
+     */
+    oneway void onInterfaceCreated(in String ifaceName);
+
+    /**
+     * Used to indicate that an interface has been removed.
+     *
+     * @param ifaceName Name of the network interface, e.g., wlan0
+     */
+    oneway void onInterfaceRemoved(in String ifaceName);
+
+    /**
+     * Used to indicate that the supplicant daemon is terminating.
+     */
+    oneway void onTerminating();
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl
new file mode 100644
index 0000000..64839e7
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl
@@ -0,0 +1,770 @@
+/*
+ * 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.wifi.supplicant;
+
+import android.hardware.wifi.supplicant.FreqRange;
+import android.hardware.wifi.supplicant.ISupplicantP2pIfaceCallback;
+import android.hardware.wifi.supplicant.ISupplicantP2pNetwork;
+import android.hardware.wifi.supplicant.IfaceType;
+import android.hardware.wifi.supplicant.MiracastMode;
+import android.hardware.wifi.supplicant.P2pGroupCapabilityMask;
+import android.hardware.wifi.supplicant.WpsConfigMethods;
+import android.hardware.wifi.supplicant.WpsProvisionMethod;
+
+/**
+ * Interface exposed by the supplicant for each P2P mode network
+ * interface (e.g p2p0) it controls.
+ */
+@VintfStability
+interface ISupplicantP2pIface {
+    /**
+     * This command can be used to add a bonjour service.
+     *
+     * @param query Hex dump of the query data.
+     * @param return Hex dump of the response data.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void addBonjourService(in byte[] query, in byte[] response);
+
+    /**
+     * Set up a P2P group owner manually (i.e., without group owner
+     * negotiation with a specific peer). This is also known as autonomous
+     * group owner. Optional |persistentNetworkId| may be used to specify
+     * restart of a persistent group.
+     *
+     * @param persistent Used to request a persistent group to be formed.
+     * @param persistentNetworkId Used to specify the restart of a persistent
+     *        group. Set to UINT32_MAX for a non-persistent group.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void addGroup(in boolean persistent, in int persistentNetworkId);
+
+    /**
+     * Set up a P2P group owner or join a group as a group client
+     * with the specified configuration.
+     *
+     * If joinExistingGroup is false, this device sets up a P2P group owner manually (i.e.,
+     * without group owner negotiation with a specific peer) with the specified SSID,
+     * passphrase, persistent mode, and frequency/band.
+     *
+     * If joinExistingGroup is true, this device acts as a group client and joins the group
+     * whose network name and group owner's MAC address matches the specified SSID
+     * and peer address without WPS process. If peerAddress is 00:00:00:00:00:00, the first found
+     * group whose network name matches the specified SSID is joined.
+     *
+     * @param ssid The SSID of this group.
+     * @param pskPassphrase The passphrase of this group.
+     * @param persistent Used to request a persistent group to be formed,
+     *        only applied for the group owner.
+     * @param freq The required frequency or band for this group.
+     *        only applied for the group owner.
+     *        The following values are supported:
+     *        0: automatic channel selection,
+     *        2: for 2.4GHz channels
+     *        5: for 5GHz channels
+     *        specific frequency, i.e., 2412, 5500, etc.
+     *        If an invalid band or unsupported frequency are specified, it fails.
+     * @param peerAddress the group owner's MAC address, only applied for the group client.
+     *        If the MAC is "00:00:00:00:00:00", the device must try to find a peer
+     *        whose network name matches the specified SSID.
+     * @param joinExistingGroup if true, join a group as a group client; otherwise,
+     *        create a group as a group owner.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void addGroupWithConfig(in byte[] ssid, in String pskPassphrase, in boolean persistent,
+            in int freq, in byte[] peerAddress, in boolean joinExistingGroup);
+
+    /**
+     * Add a new network to the interface.
+     *
+     * @return AIDL interface object representing the new network if
+     *         successful, null otherwise.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    ISupplicantP2pNetwork addNetwork();
+
+    /**
+     * This command can be used to add a UPNP service.
+     *
+     * @param version Version to be used.
+     * @package serviceName Service name to be used.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void addUpnpService(in int version, in String serviceName);
+
+    /**
+     * Cancel an ongoing P2P group formation and joining-a-group related
+     * operation. This operation unauthorizes the specific peer device (if any
+     * had been authorized to start group formation), stops P2P find (if in
+     * progress), stops pending operations for join-a-group, and removes the
+     * P2P group interface (if one was used) that is in the WPS provisioning
+     * step. If the WPS provisioning step has been completed, the group is not
+     * terminated.
+     *
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_NOT_STARTED|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void cancelConnect();
+
+    /**
+     * Cancel a previous service discovery request.
+     *
+     * @param identifier Identifier for the request to cancel.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_NOT_STARTED|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void cancelServiceDiscovery(in long identifier);
+
+    /**
+     * Cancel any ongoing WPS operations.
+     *
+     * @param groupIfName Group interface name to use.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void cancelWps(in String groupIfName);
+
+    /**
+     * Configure Extended Listen Timing.
+     *
+     * If enabled, listen state must be entered every |intervalInMillis| for at
+     * least |periodInMillis|. Both values have acceptable range of 1-65535
+     * (with interval obviously having to be larger than or equal to duration).
+     * If the P2P module is not idle at the time the Extended Listen Timing
+     * timeout occurs, the Listen State operation must be skipped.
+     *
+     * @param periodInMillis Period in milliseconds.
+     * @param intervalInMillis Interval in milliseconds.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void configureExtListen(in int periodInMillis, in int intervalInMillis);
+
+    /**
+     * Start P2P group formation with a discovered P2P peer. This includes
+     * optional group owner negotiation, group interface setup, provisioning,
+     * and establishing data connection.
+     *
+     * @param peerAddress MAC address of the device to connect to.
+     * @param provisionMethod Provisioning method to use.
+     * @param preSelectedPin Pin to be used, if |provisionMethod| uses one of the
+     *        preselected |PIN*| methods.
+     * @param joinExistingGroup Indicates that this is a command to join an
+     *        existing group as a client. It skips the group owner negotiation
+     *        part. This must send a Provision Discovery Request message to the
+     *        target group owner before associating for WPS provisioning.
+     * @param persistent Used to request a persistent group to be formed.
+     * @param goIntent Used to override the default Intent for this group owner
+     *        negotiation (Values from 1-15). Refer to section 4.1.6 in
+     *        Wi-Fi Peer-to-Peer (P2P) Technical Specification Version 1.7.
+     * @return Pin generated, if |provisionMethod| uses one of the
+     *         generated |PIN*| methods.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    String connect(in byte[] peerAddress, in WpsProvisionMethod provisionMethod,
+            in String preSelectedPin, in boolean joinExistingGroup, in boolean persistent,
+            in int goIntent);
+
+    /**
+     * Creates a NFC handover request message.
+     *
+     * @return Bytes representing the handover request as specified in
+     *         section 3.1.1 of NFC Connection Handover 1.2 Technical
+     *         Specification.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    byte[] createNfcHandoverRequestMessage();
+
+    /**
+     * Creates a NFC handover select message.
+     *
+     * @return Bytes representing the handover select as specified in
+     *         section 3.1.2 of NFC Connection Handover 1.2 Technical
+     *         Specification.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    byte[] createNfcHandoverSelectMessage();
+
+    /**
+     * Enable/Disable Wifi Display.
+     *
+     * @param enable true to enable, false to disable.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void enableWfd(in boolean enable);
+
+    /**
+     * Initiate a P2P service discovery with an optional timeout.
+     *
+     * @param timeoutInSec Max time to be spent is performing discovery.
+     *        Set to 0 to indefinely continue discovery until an explicit
+     *        |stopFind| is sent.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     *         |SupplicantStatusCode.FAILURE_IFACE_DISABLED|
+     */
+    void find(in int timeoutInSec);
+
+    /**
+     * Flush P2P peer table and state.
+     *
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void flush();
+
+    /**
+     * This command can be used to flush all services from the
+     * device.
+     *
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void flushServices();
+
+    /**
+     * Gets the MAC address of the device.
+     *
+     * @return MAC address of the device.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    byte[] getDeviceAddress();
+
+    /**
+     * Get whether EDMG(802.11ay) is enabled for this network.
+     *
+     * @return true if set, false otherwise.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    boolean getEdmg();
+
+    /**
+     * Gets the capability of the group which the device is a
+     * member of.
+     *
+     * @param peerAddress MAC address of the peer.
+     * @return Combination of |P2pGroupCapabilityMask| values.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    P2pGroupCapabilityMask getGroupCapability(in byte[] peerAddress);
+
+    /**
+     * Retrieves the name of the network interface.
+     *
+     * @return Name of the network interface, e.g., wlan0
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    String getName();
+
+    /**
+     * Gets an AIDL interface object for the network corresponding to the
+     * network id.
+     *
+     * Use |ISupplicantP2pNetwork.getId()| on the corresponding network AIDL
+     * interface object to retrieve the ID.
+     *
+     * @param id Network ID allocated to the corresponding network.
+     * @return AIDL interface object representing the new network if
+     *         successful, null otherwise.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_UNKNOWN|
+     */
+    ISupplicantP2pNetwork getNetwork(in int id);
+
+    /**
+     * Gets the operational SSID of the device.
+     *
+     * @param peerAddress MAC address of the peer.
+     * @return SSID of the device
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    byte[] getSsid(in byte[] peerAddress);
+
+    /**
+     * Retrieves the type of the network interface.
+     *
+     * @return Type of the network interface, e.g., STA.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    IfaceType getType();
+
+    /**
+     * Invite a device to a persistent group.
+     * If the peer device is the group owner of the persistent group, the peer
+     * parameter is not needed. Otherwise it is used to specify which
+     * device to invite. |goDeviceAddress| parameter may be used to override
+     * the group owner device address for Invitation Request should it not be
+     * known for some reason (this should not be needed in most cases).
+     *
+     * @param groupIfName Group interface name to use.
+     * @param goDeviceAddress MAC address of the group owner device.
+     * @param peerAddress MAC address of the device to invite.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void invite(in String groupIfName, in byte[] goDeviceAddress, in byte[] peerAddress);
+
+    /**
+     * Retrieve a list of all the network Id's controlled by the supplicant.
+     *
+     * The corresponding |ISupplicantP2pNetwork| object for any network can be
+     * retrieved using the |getNetwork| method.
+     *
+     * @return List of all network Id's controlled by the supplicant.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+     */
+    int[] listNetworks();
+
+    /**
+     * Send P2P provision discovery request to the specified peer. The
+     * parameters for this command are the P2P device address of the peer and the
+     * desired configuration method.
+     *
+     * @param peerAddress MAC address of the device to send discovery.
+     * @method provisionMethod Provisioning method to use.
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void provisionDiscovery(in byte[] peerAddress, in WpsProvisionMethod provisionMethod);
+
+    /**
+     * Register for callbacks from this interface.
+     *
+     * These callbacks are invoked for events that are specific to this interface.
+     * Registration of multiple callback objects is supported. These objects must
+     * be automatically deleted when the corresponding client process is dead or
+     * if this interface is removed.
+     *
+     * @param callback An instance of the |ISupplicantP2pIfaceCallback| AIDL
+     *        interface object.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void registerCallback(in ISupplicantP2pIfaceCallback callback);
+
+    /**
+     * Reinvoke a device from a persistent group.
+     *
+     * @param persistentNetworkId Used to specify the persistent group.
+     * @param peerAddress MAC address of the device to reinvoke.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void reinvoke(in int persistentNetworkId, in byte[] peerAddress);
+
+    /**
+     * Reject connection attempt from a peer (specified with a device
+     * address). This is a mechanism to reject a pending group owner negotiation
+     * with a peer and request to automatically block any further connection or
+     * discovery of the peer.
+     *
+     * @param peerAddress MAC address of the device to reject.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     *         |SupplicantStatusCode.FAILURE_IFACE_DISABLED|
+     */
+    void reject(in byte[] peerAddress);
+
+    /**
+     * This command can be used to remove a bonjour service.
+     *
+     * @param query Hex dump of the query data.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NOT_STARTED|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void removeBonjourService(in byte[] query);
+
+    /**
+     * Terminate a P2P group. If a new virtual network interface was used for
+     * the group, it must also be removed. The network interface name of the
+     * group interface is used as a parameter for this command.
+     *
+     * @param groupIfName Group interface name to use.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void removeGroup(in String groupIfName);
+
+    /**
+     * Remove a network from the interface.
+     *
+     * Use |ISupplicantP2pNetwork.getId()| on the corresponding network AIDL
+     * interface object to retrieve the ID.
+     *
+     * @param id Network ID allocated to the corresponding network.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_UNKNOWN|
+     */
+    void removeNetwork(in int id);
+
+    /**
+     * This command can be used to remove a UPNP service.
+     *
+     * @param version Version to be used.
+     * @package serviceName Service name to be used.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NOT_STARTED|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void removeUpnpService(in int version, in String serviceName);
+
+    /**
+     * Report the initiation of the NFC handover select.
+     *
+     * @param select Bytes representing the handover select as specified in
+     *        section 3.1.2 of NFC Connection Handover 1.2 Technical
+     *        Specification.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void reportNfcHandoverInitiation(in byte[] select);
+
+    /**
+     * Report the response of the NFC handover request.
+     *
+     * @param request Bytes representing the handover request as specified in
+     *        section 3.1.1 of NFC Connection Handover 1.2 Technical
+     *        Specification.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void reportNfcHandoverResponse(in byte[] request);
+
+    /**
+     * Schedule a P2P service discovery request. The parameters for this command
+     * are the device address of the peer device (or 00:00:00:00:00:00 for
+     * wildcard query that is sent to every discovered P2P peer that supports
+     * service discovery) and P2P Service Query TLV(s) as hexdump.
+     *
+     * @param peerAddress MAC address of the device to discover.
+     * @param query Hex dump of the query data.
+     * @return Identifier for the request. Can be used to cancel the
+     *         request.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    long requestServiceDiscovery(in byte[] peerAddress, in byte[] query);
+
+    /**
+     * Persist the current configuration to disk.
+     *
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void saveConfig();
+
+    /**
+     * Set P2P disallowed frequency ranges.
+     *
+     * Specify ranges of frequencies that are disallowed for any P2P operations.
+     *
+     * @param ranges List of ranges which needs to be disallowed.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void setDisallowedFrequencies(in FreqRange[] ranges);
+
+    /**
+     * Set whether to enable EDMG(802.11ay). Only allowed if hw mode is |HOSTAPD_MODE_IEEE80211AD|
+     *
+     * @param enable true to set, false otherwise.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void setEdmg(in boolean enable);
+
+    /**
+     * Set the Maximum idle time in seconds for P2P groups.
+     * This value controls how long a P2P group is maintained after there
+     * is no other members in the group. As a group owner, this means no
+     * associated stations in the group. As a P2P client, this means no
+     * group owner seen in scan results.
+     *
+     * @param groupIfName Group interface name to use.
+     * @param timeoutInSec Timeout value in seconds.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void setGroupIdle(in String groupIfName, in int timeoutInSec);
+
+    /**
+     * Set P2P Listen channel.
+     *
+     * When specifying a social channel on the 2.4 GHz band (1/6/11) there is no
+     * need to specify the operating class since it defaults to 81. When
+     * specifying a social channel on the 60 GHz band (2), specify the 60 GHz
+     * operating class (180).
+     *
+     * @param channel Wifi channel. eg, 1, 6, 11.
+     * @param operatingClass Operating Class indicates the channel set of the AP
+     *        indicated by this BSSID
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void setListenChannel(in int channel, in int operatingClass);
+
+    /**
+     * Set MAC randomization enabled/disabled.
+     *
+     * @param enable true to enable, false to disable.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void setMacRandomization(in boolean enable);
+
+    /**
+     * Send driver command to set Miracast mode.
+     *
+     * @param mode Mode of Miracast.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void setMiracastMode(in MiracastMode mode);
+
+    /**
+     * Turn on/off power save mode for the interface.
+     *
+     * @param groupIfName Group interface name to use.
+     * @param enable Indicate if power save is to be turned on/off.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_DISABLED|
+     */
+    void setPowerSave(in String groupIfName, in boolean enable);
+
+    /**
+     * Set the postfix to be used for P2P SSID's.
+     *
+     * @param postfix String to be appended to SSID.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void setSsidPostfix(in byte[] postfix);
+
+    /**
+     * Set Wifi Display device info.
+     *
+     * @param info WFD device info as described in section 5.1.2 of WFD technical
+     *        specification v1.0.0.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void setWfdDeviceInfo(in byte[] info);
+
+    /**
+     * Set Wifi Display R2 device info.
+     *
+     * @param info WFD R2 device info as described in section 5.1.12 of WFD technical
+     *        specification v2.1.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void setWfdR2DeviceInfo(in byte[] info);
+
+    /**
+     * Set the list of supported config methods for WPS operations.
+     *
+     * @param configMethods Mask of WPS configuration methods supported by the
+     *        device.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+     */
+    void setWpsConfigMethods(in WpsConfigMethods configMethods);
+
+    /**
+     * Set the device name for WPS operations.
+     * User-friendly description of device (up to |WPS_DEVICE_NAME_MAX_LEN|
+     * octets encoded in UTF-8).
+     *
+     * @param name Name to be set.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+     */
+    void setWpsDeviceName(in String name);
+
+    /**
+     * Set the device type for WPS operations.
+     *
+     * @param type Type of device. Refer to section B.1 of Wifi P2P
+     *       Technical specification v1.2.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+     */
+    void setWpsDeviceType(in byte[] type);
+
+    /**
+     * Set the manufacturer for WPS operations.
+     * The manufacturer of the device (up to |WPS_MANUFACTURER_MAX_LEN| ASCII
+     * characters).
+     *
+     * @param manufacturer Manufacture to be set.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+     */
+    void setWpsManufacturer(in String manufacturer);
+
+    /**
+     * Set the model name for WPS operations.
+     * Model of the device (up to |WPS_MODEL_NAME_MAX_LEN| ASCII characters).
+     *
+     * @param modelName Model name to be set.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+     */
+    void setWpsModelName(in String modelName);
+
+    /**
+     * Set the model number for WPS operations.
+     * Additional device description (up to |WPS_MODEL_NUMBER_MAX_LEN| ASCII
+     * characters).
+     *
+     * @param modelNumber Model number to be set.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+     */
+    void setWpsModelNumber(in String modelNumber);
+
+    /**
+     * Set the serial number for WPS operations.
+     * Serial number of the device (up to |WPS_SERIAL_NUMBER_MAX_LEN| characters)
+     *
+     * @param serialNumber Serial number to be set.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+     */
+    void setWpsSerialNumber(in String serialNumber);
+
+    /**
+     * Initiate WPS Push Button setup.
+     * The PBC operation requires that a button is also pressed at the
+     * AP/Registrar at about the same time (2 minute window).
+     *
+     * @param groupIfName Group interface name to use.
+     * @param bssid BSSID of the AP. Use zero'ed bssid to indicate wildcard.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void startWpsPbc(in String groupIfName, in byte[] bssid);
+
+    /**
+     * Initiate WPS Pin Display setup.
+     *
+     * @param groupIfName Group interface name to use.
+     * @param bssid BSSID of the AP. Use zero'ed bssid to indicate wildcard.
+     * @return 8 digit pin generated.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    String startWpsPinDisplay(in String groupIfName, in byte[] bssid);
+
+    /**
+     * Initiate WPS Pin Keypad setup.
+     *
+     * @param groupIfName Group interface name to use.
+     * @param pin 8 digit pin to be used.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void startWpsPinKeypad(in String groupIfName, in String pin);
+
+    /**
+     * Stop an ongoing P2P service discovery.
+     *
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     *         |SupplicantStatusCode.FAILURE_IFACE_DISABLED|
+     */
+    void stopFind();
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl
new file mode 100644
index 0000000..f0cabd6
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl
@@ -0,0 +1,208 @@
+/*
+ * 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.wifi.supplicant;
+
+import android.hardware.wifi.supplicant.P2pGroupCapabilityMask;
+import android.hardware.wifi.supplicant.P2pProvDiscStatusCode;
+import android.hardware.wifi.supplicant.P2pStatusCode;
+import android.hardware.wifi.supplicant.WpsConfigMethods;
+import android.hardware.wifi.supplicant.WpsDevPasswordId;
+
+/**
+ * Callback Interface exposed by the supplicant service
+ * for each P2P mode interface (ISupplicantP2pIface).
+ *
+ * Clients need to host an instance of this AIDL interface object and
+ * pass a reference of the object to the supplicant via the
+ * corresponding |ISupplicantP2pIface.registerCallback| method.
+ */
+@VintfStability
+interface ISupplicantP2pIfaceCallback {
+    /**
+     * Used to indicate that a P2P device has been found.
+     *
+     * @param srcAddress MAC address of the device found. This must either
+     *        be the P2P device address or the P2P interface address.
+     * @param p2pDeviceAddress P2P device address.
+     * @param primaryDeviceType Type of device. Refer to section B.1 of Wifi P2P
+     *        Technical specification v1.2.
+     * @param deviceName Name of the device.
+     * @param configMethods Mask of WPS configuration methods supported by the
+     *        device.
+     * @param deviceCapabilities Refer to section 4.1.4 of Wifi P2P Technical
+     *        specification v1.2.
+     * @param groupCapabilites Refer to section 4.1.4 of Wifi P2P Technical
+     *        specification v1.2.
+     * @param wfdDeviceInfo WFD device info as described in section 5.1.2 of WFD
+     *        technical specification v1.0.0.
+     */
+    oneway void onDeviceFound(in byte[] srcAddress, in byte[] p2pDeviceAddress,
+            in byte[] primaryDeviceType, in String deviceName, in WpsConfigMethods configMethods,
+            in byte deviceCapabilities, in P2pGroupCapabilityMask groupCapabilities,
+            in byte[] wfdDeviceInfo);
+
+    /**
+     * Used to indicate that a P2P device has been lost.
+     *
+     * @param p2pDeviceAddress P2P device address.
+     */
+    oneway void onDeviceLost(in byte[] p2pDeviceAddress);
+
+    /**
+     * Used to indicate the termination of P2P find operation.
+     */
+    oneway void onFindStopped();
+
+    /**
+     * Used to indicate the completion of a P2P Group Owner negotiation request.
+     *
+     * @param status Status of the GO negotiation.
+     */
+    oneway void onGoNegotiationCompleted(in P2pStatusCode status);
+
+    /**
+     * Used to indicate the reception of a P2P Group Owner negotiation request.
+     *
+     * @param srcAddress MAC address of the device that initiated the GO
+     *        negotiation request.
+     * @param passwordId Type of password.
+     */
+    oneway void onGoNegotiationRequest(in byte[] srcAddress, in WpsDevPasswordId passwordId);
+
+    /**
+     * Used to indicate a failure to form a P2P group.
+     *
+     * @param failureReason Failure reason string for debug purposes.
+     */
+    oneway void onGroupFormationFailure(in String failureReason);
+
+    /**
+     * Used to indicate a successful formation of a P2P group.
+     */
+    oneway void onGroupFormationSuccess();
+
+    /**
+     * Used to indicate the removal of a P2P group.
+     *
+     * @param groupIfName Interface name of the group. (For ex: p2p-p2p0-1)
+     * @param isGroupOwner Whether this device is owner of the group.
+     */
+    oneway void onGroupRemoved(in String groupIfname, in boolean isGroupOwner);
+
+    /**
+     * Used to indicate the start of a P2P group.
+     *
+     * @param groupIfName Interface name of the group. (For ex: p2p-p2p0-1)
+     * @param isGroupOwner Whether this device is owner of the group.
+     * @param ssid SSID of the group.
+     * @param frequency Frequency on which this group is created.
+     * @param psk PSK used to secure the group.
+     * @param passphrase PSK passphrase used to secure the group.
+     * @param goDeviceAddress MAC Address of the owner of this group.
+     * @param isPersistent Whether this group is persisted or not.
+     */
+    oneway void onGroupStarted(in String groupIfname, in boolean isGroupOwner, in byte[] ssid,
+            in int frequency, in byte[] psk, in String passphrase, in byte[] goDeviceAddress,
+            in boolean isPersistent);
+
+    /**
+     * Used to indicate the reception of a P2P invitation.
+     *
+     * @param srcAddress MAC address of the device that sent the invitation.
+     * @param goDeviceAddress MAC Address of the owner of this group.
+     * @param bssid Bssid of the group.
+     * @param persistentNetworkId Persistent network Id of the group.
+     * @param operatingFrequency Frequency on which the invitation was received.
+     */
+    oneway void onInvitationReceived(in byte[] srcAddress, in byte[] goDeviceAddress,
+            in byte[] bssid, in int persistentNetworkId, in int operatingFrequency);
+
+    /**
+     * Used to indicate the result of the P2P invitation request.
+     *
+     * @param bssid Bssid of the group.
+     * @param status Status of the invitation.
+     */
+    oneway void onInvitationResult(in byte[] bssid, in P2pStatusCode status);
+
+    /**
+     * Used to indicate the completion of a P2P provision discovery request.
+     *
+     * @param p2pDeviceAddress P2P device address.
+     * @param isRequest Whether we received or sent the provision discovery.
+     * @param status Status of the provision discovery.
+     * @param configMethods Mask of WPS configuration methods supported.
+     * @param generatedPin 8 digit pin generated.
+     */
+    oneway void onProvisionDiscoveryCompleted(in byte[] p2pDeviceAddress, in boolean isRequest,
+            in P2pProvDiscStatusCode status, in WpsConfigMethods configMethods,
+            in String generatedPin);
+
+    /**
+     * Used to indicate that a P2P Wi-Fi Display R2 device has been found. Refer to
+     * Wi-Fi Display Technical Specification Version 2.0.
+     *
+     * @param srcAddress MAC address of the device found. This must either
+     *        be the P2P device address for a peer which is not in a group,
+     *        or the P2P interface address for a peer which is a Group Owner.
+     * @param p2pDeviceAddress P2P device address.
+     * @param primaryDeviceType Type of device. Refer to section B.1 of Wifi P2P
+     *        Technical specification v1.2.
+     * @param deviceName Name of the device.
+     * @param configMethods Mask of WPS configuration methods supported by the
+     *        device.
+     * @param deviceCapabilities Refer to section 4.1.4 of Wifi P2P Technical
+     *        specification v1.2.
+     * @param groupCapabilites Refer to section 4.1.4 of Wifi P2P Technical
+     *        specification v1.2.
+     * @param wfdDeviceInfo WFD device info as described in section 5.1.2 of WFD
+     *        technical specification v1.0.0.
+     * @param wfdR2DeviceInfo WFD R2 device info as described in section 5.1.12 of WFD
+     *        technical specification v2.1.
+     */
+    oneway void onR2DeviceFound(in byte[] srcAddress, in byte[] p2pDeviceAddress,
+            in byte[] primaryDeviceType, in String deviceName, in WpsConfigMethods configMethods,
+            in byte deviceCapabilities, in P2pGroupCapabilityMask groupCapabilities,
+            in byte[] wfdDeviceInfo, in byte[] wfdR2DeviceInfo);
+
+    /**
+     * Used to indicate the reception of a P2P service discovery response.
+     *
+     * @param srcAddress MAC address of the device that sent the service discovery.
+     * @param updateIndicator Service update indicator. Refer to section 3.1.3 of
+     *        Wifi P2P Technical specification v1.2.
+     * @parm tlvs Refer to section 3.1.3.1 of Wifi P2P Technical specification v1.2.
+     */
+    oneway void onServiceDiscoveryResponse(
+            in byte[] srcAddress, in char updateIndicator, in byte[] tlvs);
+
+    /**
+     * Used to indicate when a STA device is connected to this device.
+     *
+     * @param srcAddress MAC address of the device that was authorized.
+     * @param p2pDeviceAddress P2P device address.
+     */
+    oneway void onStaAuthorized(in byte[] srcAddress, in byte[] p2pDeviceAddress);
+
+    /**
+     * Used to indicate when a STA device is disconnected from this device.
+     *
+     * @param srcAddress MAC address of the device that was deauthorized.
+     * @param p2pDeviceAddress P2P device address.
+     */
+    oneway void onStaDeauthorized(in byte[] srcAddress, in byte[] p2pDeviceAddress);
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pNetwork.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pNetwork.aidl
new file mode 100644
index 0000000..f037252
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pNetwork.aidl
@@ -0,0 +1,131 @@
+/*
+ * 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.wifi.supplicant;
+
+import android.hardware.wifi.supplicant.IfaceType;
+import android.hardware.wifi.supplicant.MacAddress;
+
+/**
+ * Interface exposed by the supplicant for each P2P mode network
+ * configuration it controls.
+ */
+@VintfStability
+interface ISupplicantP2pNetwork {
+    /**
+     * Get the BSSID set for this network.
+     *
+     * @return bssid Value set.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    byte[] getBssid();
+
+    /**
+     * Get the list of P2P Clients in a persistent group (GO).
+     * This is a list of P2P Clients (P2P Device Address) that have joined
+     * the persistent group. This is maintained on the GO for persistent
+     * group entries (disabled == 2).
+     *
+     * @return MAC addresses of the clients.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantP2ptusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    MacAddress[] getClientList();
+
+    /**
+     * Retrieves the ID allocated to this network by the supplicant.
+     *
+     * This is not the |SSID| of the network, but an internal identifier for
+     * this network used by the supplicant.
+     *
+     * @return Network ID.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    int getId();
+
+    /**
+     * Retrieves the name of the interface this network belongs to.
+     *
+     * @return Name of the network interface, e.g., wlan0
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    String getInterfaceName();
+
+    /**
+     * Getters for the various network params.
+     *
+     *
+     * Get SSID for this network.
+     *
+     * @return ssid value set.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    byte[] getSsid();
+
+    /**
+     * Retrieves the type of the interface this network belongs to.
+     *
+     * @return Type of the network interface, e.g., STA.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    IfaceType getType();
+
+    /**
+     * Check if the network is currently active one.
+     *
+     * @return true if current, false otherwise.
+     * @throws ServiceSpecificException with one of the following values:,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    boolean isCurrent();
+
+    /**
+     * Check if the device is the group owner of the network.
+     *
+     * @return true if group owner, false otherwise.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    boolean isGroupOwner();
+
+    /**
+     * Check if the network is marked persistent.
+     *
+     * @return true if persistent, false otherwise.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    boolean isPersistent();
+
+    /**
+     * Set the list of P2P Clients in a persistent group (GO).
+     * This is a list of P2P Clients (P2P Device Address) that have joined
+     * the persistent group. This is maintained on the GO for persistent
+     * group entries (disabled == 2).
+     *
+     * @param clients MAC address of the clients.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantP2ptusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void setClientList(in MacAddress[] clients);
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl
new file mode 100644
index 0000000..b48fa04
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl
@@ -0,0 +1,715 @@
+/*
+ * 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.wifi.supplicant;
+
+import android.hardware.wifi.supplicant.AnqpInfoId;
+import android.hardware.wifi.supplicant.BtCoexistenceMode;
+import android.hardware.wifi.supplicant.ConnectionCapabilities;
+import android.hardware.wifi.supplicant.DppAkm;
+import android.hardware.wifi.supplicant.DppCurve;
+import android.hardware.wifi.supplicant.DppNetRole;
+import android.hardware.wifi.supplicant.DppResponderBootstrapInfo;
+import android.hardware.wifi.supplicant.Hs20AnqpSubtypes;
+import android.hardware.wifi.supplicant.ISupplicantStaIfaceCallback;
+import android.hardware.wifi.supplicant.ISupplicantStaNetwork;
+import android.hardware.wifi.supplicant.IfaceType;
+import android.hardware.wifi.supplicant.KeyMgmtMask;
+import android.hardware.wifi.supplicant.RxFilterType;
+import android.hardware.wifi.supplicant.WpaDriverCapabilitiesMask;
+import android.hardware.wifi.supplicant.WpsConfigMethods;
+
+/**
+ * Interface exposed by the supplicant for each station mode network
+ * interface (e.g wlan0) it controls.
+ */
+@VintfStability
+interface ISupplicantStaIface {
+    /**
+     * Add a DPP peer URI. URI is acquired externally, e.g. by scanning a QR code
+     *
+     * @param uri Peer's DPP URI.
+     * @return ID for the URI
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    int addDppPeerUri(in String uri);
+
+    /**
+     * External programs can request supplicant to not start offchannel
+     * operations during other tasks that may need exclusive control of the
+     * radio.
+     *
+     * This method can be used to reserve a slot for radio access. If freq is
+     * specified, other radio work items on the same channel can be completed in
+     * parallel. Otherwise, all other radio work items are blocked during
+     * execution. Timeout must be set to |ExtRadioWorkDefaults.TIMEOUT_IN_SECS|
+     * seconds by default to avoid blocking supplicant operations on the iface
+     * for excessive time. If a longer (or shorter) safety timeout is needed,
+     * that may be specified with the optional timeout parameter. This command
+     * returns an identifier for the radio work item.
+     *
+     * Once the radio work item has been started,
+     * |ISupplicant.onExtRadioWorkStart| callback is indicated that the external
+     * processing can start.
+     *
+     * @param name Name for the radio work being added.
+     * @param freqInMhz Frequency to specify. Set to 0 for all channels.
+     * @param timeoutInSec Timeout to specify. Set to 0 for default timeout.
+     * @return Identifier for this radio work.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+     */
+    int addExtRadioWork(in String name, in int freqInMhz, in int timeoutInSec);
+
+    /**
+     * Add a new network to the interface.
+     *
+     * @return AIDL interface object representing the new network if
+     *         successful, null otherwise.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    ISupplicantStaNetwork addNetwork();
+
+    /**
+     * Send driver command to add the specified RX filter.
+     *
+     * @param type Type of filter.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void addRxFilter(in RxFilterType type);
+
+    /**
+     * Cancel any ongoing WPS operations.
+     *
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void cancelWps();
+
+    /**
+     * Disconnect from the current active network.
+     *
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_DISABLED|
+     */
+    void disconnect();
+
+    /**
+     * Enable/Disable auto reconnect to networks.
+     * Use this to prevent wpa_supplicant from trying to connect to networks
+     * on its own.
+     *
+     * @param enable true to enable, false to disable.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_DISABLED|
+     */
+    void enableAutoReconnect(in boolean enable);
+
+    /**
+     * Add fast initial link setup (IEEE 802.11ai FILS) HLP packets.
+     * Use this to add higher layer protocol (HLP) packet in FILS (Re)Association Request frame
+     * (Eg: DHCP discover packet).
+     *
+     * @param dst_mac MAC address of the destination
+     * @param pkt The contents of the HLP packet starting from ethertype
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_DISABLED|
+     */
+    void filsHlpAddRequest(in byte[] dst_mac, in byte[] pkt);
+
+    /**
+     * Flush fast initial link setup (IEEE 802.11ai FILS) HLP packets.
+     * Use this to flush all the higher layer protocol (HLP) packets added in
+     * wpa_supplicant to send in FILS (Re)Association Request frame
+     * (Eg: DHCP discover packet).
+     *
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_DISABLED|
+     */
+    void filsHlpFlushRequest();
+
+    /**
+     * Generates DPP bootstrap information: Bootstrap ID, DPP URI and listen
+     * channel for responder mode.
+     *
+     * @param macAddress MAC address of the interface for the DPP operation.
+     * @param deviceInfo Device specific information.
+     *        As per DPP Specification V1.0 section 5.2,
+     *        allowed Range of ASCII characters in deviceInfo - %x20-7E
+     *        semicolon is not allowed.
+     * @param curve Elliptic curve cryptography type used to generate DPP
+     *        public/private key pair.
+     * @return Bootstrap info.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+     *         |SupplicantStatusCode.FAILURE_UNSUPPORTED|
+     */
+    DppResponderBootstrapInfo generateDppBootstrapInfoForResponder(
+            in byte[] macAddress, in String deviceInfo, in DppCurve curve);
+
+    /**
+     * Get Connection capabilities
+     *
+     * @return Connection capabilities.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+     */
+    ConnectionCapabilities getConnectionCapabilities();
+
+    /**
+     * Get Key management capabilities of the device
+     *
+     * @return Bitmap of key management mask.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+     */
+    KeyMgmtMask getKeyMgmtCapabilities();
+
+    /**
+     * Send driver command to get MAC address of the device.
+     *
+     * @return MAC address of the device.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    byte[] getMacAddress();
+
+    /**
+     * Retrieves the name of the network interface.
+     *
+     * @return Name of the network interface, e.g., wlan0
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    String getName();
+
+    /**
+     * Gets an AIDL interface object for the network corresponding to the
+     * network id.
+     *
+     * Use |ISupplicantStaNetwork.getId()| on the corresponding network AIDL
+     * interface object to retrieve the ID.
+     *
+     * @param id Network ID allocated to the corresponding network.
+     * @return AIDL interface object representing the new network if
+     *         successful, null otherwise.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_UNKNOWN|
+     */
+    ISupplicantStaNetwork getNetwork(in int id);
+
+    /**
+     * Retrieves the type of the network interface.
+     *
+     * @return Type of the network interface, e.g., STA.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    IfaceType getType();
+
+    /**
+     * Get wpa driver capabilities.
+     *
+     * @return Bitmap of wpa driver features.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+     */
+    WpaDriverCapabilitiesMask getWpaDriverCapabilities();
+
+    /**
+     * Initiate ANQP (for IEEE 802.11u Interworking/Hotspot 2.0) queries with the
+     * specified access point.
+     * The ANQP data fetched must be returned in the
+     * |ISupplicantStaIfaceCallback.onAnqpQueryDone| callback.
+     *
+     * @param macAddress MAC address of the access point.
+     * @param infoElements List of information elements to query for.
+     * @param subtypes List of HS20 subtypes to query for.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void initiateAnqpQuery(
+            in byte[] macAddress, in AnqpInfoId[] infoElements, in Hs20AnqpSubtypes[] subTypes);
+
+    /**
+     * Initiate the Hotspot 2.0 icon query with the specified accesss point.
+     * The icon data fetched must be returned in the
+     * |ISupplicantStaIfaceCallback.onHs20IconQueryDone| callback.
+     *
+     * @param macAddress MAC address of the access point.
+     * @param fileName Name of the file to request from the access point.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void initiateHs20IconQuery(in byte[] macAddress, in String fileName);
+
+    /**
+     * Initiate TDLS discover with the provided peer MAC address.
+     *
+     * @param macAddress MAC address of the peer.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void initiateTdlsDiscover(in byte[] macAddress);
+
+    /**
+     * Initiate TDLS setup with the provided peer MAC address.
+     *
+     * @param macAddress MAC address of the peer.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void initiateTdlsSetup(in byte[] macAddress);
+
+    /**
+     * Initiate TDLS teardown with the provided peer MAC address.
+     *
+     * @param macAddress MAC address of the peer.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void initiateTdlsTeardown(in byte[] macAddress);
+
+    /**
+     * Initiate Venue URL ANQP (for IEEE 802.11u Interworking/Hotspot 2.0) query with the
+     * specified access point. This specific query can be used only post connection, once security
+     * is established and PMF is enabled, to avoid spoofing preassociation ANQP responses.
+     * The ANQP data fetched must be returned in the
+     * |ISupplicantStaIfaceCallback.onAnqpQueryDone| callback.
+     *
+     * @param macAddress MAC address of the access point.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void initiateVenueUrlAnqpQuery(in byte[] macAddress);
+
+    /**
+     * Retrieve a list of all the network Id's controlled by the supplicant.
+     *
+     * The corresponding |ISupplicantStaNetwork| object for any network can be
+     * retrieved using |getNetwork| method.
+     *
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+     * @return List of all network Id's controlled by the supplicant.
+     */
+    int[] listNetworks();
+
+    /**
+     * Reconnect to the currently active network, even if we are already
+     * connected.
+     *
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_DISABLED|
+     */
+    void reassociate();
+
+    /**
+     * Reconnect to the currently active network, if we are currently
+     * disconnected.
+     *
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_DISABLED|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_NOT_DISCONNECTED|
+     */
+    void reconnect();
+
+    /**
+     * Register for callbacks from this interface.
+     *
+     * These callbacks are invoked for events that are specific to this interface.
+     * Registration of multiple callback objects is supported. These objects must
+     * be automatically deleted when the corresponding client process is dead or
+     * if this interface is removed.
+     *
+     * @param callback An instance of the |ISupplicantStaIfaceCallback| AIDL
+     *        interface object.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void registerCallback(in ISupplicantStaIfaceCallback callback);
+
+    /**
+     * Remove a DPP peer URI.
+     *
+     * @param id The ID of the URI, as returned by |addDppPeerUri|.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void removeDppUri(in int id);
+
+    /**
+     * Indicates to supplicant that the external radio work has completed.
+     * This allows other radio works to be performed. If this method is not
+     * invoked (e.g., due to the external program terminating), supplicant
+     * must time out the radio work item on the iface and send
+     * |ISupplicantCallback.onExtRadioWorkTimeout| event to indicate
+     * that this has happened.
+     *
+     * This method may also be used to cancel items that have been scheduled
+     * via |addExtRadioWork|, but have not yet been started (notified via
+     * |ISupplicantCallback.onExtRadioWorkStart|).
+     *
+     * @param id Identifier generated for the radio work addition
+     *         (using |addExtRadioWork|).
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+     */
+    void removeExtRadioWork(in int id);
+
+    /**
+     * Remove a network from the interface.
+     *
+     * Use |ISupplicantStaNetwork.getId()| on the corresponding network AIDL
+     * interface object to retrieve the ID.
+     *
+     * @param id Network ID allocated to the corresponding network.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_UNKNOWN|
+     */
+    void removeNetwork(in int id);
+
+    /**
+     * Send driver command to remove the specified RX filter.
+     *
+     * @param type Type of filter.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void removeRxFilter(in RxFilterType type);
+
+    /**
+     * Send driver command to set Bluetooth coexistence mode.
+     *
+     * @param mode Mode of Bluetooth coexistence.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void setBtCoexistenceMode(in BtCoexistenceMode mode);
+
+    /**
+     * Send driver command to set Bluetooth coexistence scan mode.
+     * When this mode is on, some of the low-level scan parameters
+     * used by the driver are changed to reduce interference
+     * with A2DP streaming.
+     *
+     * @param enable true to enable, false to disable.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void setBtCoexistenceScanModeEnabled(in boolean enable);
+
+    /**
+     * Send driver command to set country code.
+     *
+     * @param code 2 byte country code (as defined in ISO 3166) to set.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void setCountryCode(in byte[] code);
+
+    /**
+     * Use external processing for SIM/USIM operations
+     *
+     * @param useExternalSim true to use external, false otherwise.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void setExternalSim(in boolean useExternalSim);
+
+    /**
+     * Set Wi-Fi Alliance Agile Multiband (MBO) cellular data status.
+     *
+     * @param available true means cellular data available, false otherwise.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+     */
+    void setMboCellularDataStatus(in boolean available);
+
+    /**
+     * Turn on/off power save mode for the interface.
+     *
+     * @param enable Indicate if power save is to be turned on/off.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_DISABLED|
+     */
+    void setPowerSave(in boolean enable);
+
+    /**
+     * Send driver command to set suspend optimizations for power save.
+     *
+     * @param enable true to enable, false to disable.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void setSuspendModeEnabled(in boolean enable);
+
+    /**
+     * Set the list of supported config methods for WPS operations.
+     *
+     * @param configMethods Mask of WPS configuration methods supported by the
+     *        device.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+     */
+    void setWpsConfigMethods(in WpsConfigMethods configMethods);
+
+    /**
+     * Set the device name for WPS operations.
+     * User-friendly description of device (up to |WPS_DEVICE_NAME_MAX_LEN|
+     * octets encoded in UTF-8).
+     *
+     * @parm name Name to be set.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+     */
+    void setWpsDeviceName(in String name);
+
+    /**
+     * Set the device type for WPS operations.
+     *
+     * @parm type Type of device. Refer to section B.1 of Wifi P2P
+     *       Technical specification v1.2.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+     */
+    void setWpsDeviceType(in byte[] type);
+
+    /**
+     * Set the manufacturer for WPS operations.
+     * The manufacturer of the device (up to |WPS_MANUFACTURER_MAX_LEN| ASCII
+     * characters).
+     *
+     * @parm manufacturer Manufacture to be set.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+     */
+    void setWpsManufacturer(in String manufacturer);
+
+    /**
+     * Set the model name for WPS operations.
+     * Model of the device (up to |WPS_MODEL_NAME_MAX_LEN| ASCII characters).
+     *
+     * @parm modelName Model name to be set.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+     */
+    void setWpsModelName(in String modelName);
+
+    /**
+     * Set the model number for WPS operations.
+     * Additional device description (up to |WPS_MODEL_NUMBER_MAX_LEN| ASCII
+     * characters).
+     *
+     * @parm modelNumber Model number to be set.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+     */
+    void setWpsModelNumber(in String modelNumber);
+
+    /**
+     * Set the serial number for WPS operations.
+     * Serial number of the device (up to |WPS_SERIAL_NUMBER_MAX_LEN| characters)
+     *
+     * @parm serialNumber Serial number to be set.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+     */
+    void setWpsSerialNumber(in String serialNumber);
+
+    /**
+     * Start DPP in Configurator-Initiator mode.
+     *
+     * @param peerBootstrapId Peer device's URI ID.
+     * @param ownBootstrapId Local device's URI ID (0 for none, optional).
+     * @param ssid Network SSID to send to peer (SAE/PSK mode).
+     * @param password Network password to send to peer (SAE/PSK mode).
+     * @param psk Network PSK to send to peer (PSK mode only). Either password or psk should be set.
+     * @param netRole Role to configure the peer, |DppNetRole.DPP_NET_ROLE_STA| or
+     *        |DppNetRole.DPP_NET_ROLE_AP|.
+     * @param securityAkm Security AKM to use (See DppAkm).
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void startDppConfiguratorInitiator(in int peerBootstrapId, in int ownBootstrapId,
+            in String ssid, in String password, in String psk, in DppNetRole netRole,
+            in DppAkm securityAkm);
+
+    /**
+     * Start DPP in Enrollee-Initiator mode.
+     *
+     * @param peerBootstrapId Peer device's URI ID.
+     * @param ownBootstrapId Local device's URI ID (0 for none, optional).
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void startDppEnrolleeInitiator(in int peerBootstrapId, in int ownBootstrapId);
+
+    /**
+     * Start DPP in Enrollee-Responder mode.
+     * Framework must first call |generateDppBootstrapInfoForResponder| to generate
+     * the bootstrapping information: Bootstrap ID, DPP URI and the listen channel.
+     * Then call this API with derived listen channel to start listening for
+     * authentication request from Peer initiator.
+     *
+     * @param listenChannel DPP listen channel.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     *         |SupplicantStatusCode.FAILURE_UNSUPPORTED|
+     */
+    void startDppEnrolleeResponder(in int listenChannel);
+
+    /**
+     * Send driver command to start RX filter.
+     *
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void startRxFilter();
+
+    /**
+     * Initiate WPS Push Button setup.
+     * The PBC operation requires that a button is also pressed at the
+     * AP/Registrar at about the same time (2 minute window).
+     *
+     * @param bssid BSSID of the AP. Use zero'ed bssid to indicate wildcard.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void startWpsPbc(in byte[] bssid);
+
+    /**
+     * Initiate WPS Pin Display setup.
+     *
+     * @param bssid BSSID of the AP. Use zero'ed bssid to indicate wildcard.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     * @return 8 digit pin generated.
+     */
+    String startWpsPinDisplay(in byte[] bssid);
+
+    /**
+     * Initiate WPS Pin Keypad setup.
+     *
+     * @param pin 8 digit pin to be used.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void startWpsPinKeypad(in String pin);
+
+    /**
+     * Initiate WPS setup in registrar role to learn the current AP configuration.
+     *
+     * @param bssid BSSID of the AP.
+     * @param pin Pin of the AP.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void startWpsRegistrar(in byte[] bssid, in String pin);
+
+    /**
+     * Stop DPP Initiator operation.
+     *
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void stopDppInitiator();
+
+    /**
+     * Stop DPP Responder operation - Remove the bootstrap code and stop listening.
+     *
+     * @param ownBootstrapId Local device's URI ID obtained through
+     *        |generateDppBootstrapInfoForResponder| call.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     *         |SupplicantStatusCode.FAILURE_UNSUPPORTED|
+     */
+    void stopDppResponder(in int ownBootstrapId);
+
+    /**
+     * Send driver command to stop RX filter.
+     *
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void stopRxFilter();
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl
new file mode 100644
index 0000000..594fef9
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl
@@ -0,0 +1,278 @@
+/*
+ * 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.wifi.supplicant;
+
+import android.hardware.wifi.supplicant.AnqpData;
+import android.hardware.wifi.supplicant.AssociationRejectionData;
+import android.hardware.wifi.supplicant.BssTmData;
+import android.hardware.wifi.supplicant.BssidChangeReason;
+import android.hardware.wifi.supplicant.DppAkm;
+import android.hardware.wifi.supplicant.DppEventType;
+import android.hardware.wifi.supplicant.DppFailureCode;
+import android.hardware.wifi.supplicant.DppProgressCode;
+import android.hardware.wifi.supplicant.Hs20AnqpData;
+import android.hardware.wifi.supplicant.OsuMethod;
+import android.hardware.wifi.supplicant.StaIfaceCallbackState;
+import android.hardware.wifi.supplicant.StaIfaceReasonCode;
+import android.hardware.wifi.supplicant.WpsConfigError;
+import android.hardware.wifi.supplicant.WpsErrorIndication;
+
+/**
+ * Callback Interface exposed by the supplicant service
+ * for each station mode interface (ISupplicantStaIface).
+ *
+ * Clients need to host an instance of this AIDL interface object and
+ * pass a reference of the object to the supplicant via the
+ * corresponding |ISupplicantStaIface.registerCallback| method.
+ */
+@VintfStability
+interface ISupplicantStaIfaceCallback {
+    /**
+     * Used to indicate the result of ANQP (either for IEEE 802.11u Interworking
+     * or Hotspot 2.0) query.
+     *
+     * @param bssid BSSID of the access point.
+     * @param data ANQP data fetched from the access point.
+     *        All the fields in this struct must be empty if the query failed.
+     * @param hs20Data ANQP data fetched from the Hotspot 2.0 access point.
+     *        All the fields in this struct must be empty if the query failed.
+     */
+    oneway void onAnqpQueryDone(in byte[] bssid, in AnqpData data, in Hs20AnqpData hs20Data);
+
+    /**
+     * Used to indicate an association rejection received from the AP
+     * to which the connection is being attempted.
+     *
+     * @param assocRejectData Association Rejection related information.
+     */
+    oneway void onAssociationRejected(in AssociationRejectionData assocRejectData);
+
+    /**
+     * Used to indicate the timeout of authentication to an AP.
+     *
+     * @param bssid BSSID of the corresponding AP.
+     */
+    oneway void onAuthenticationTimeout(in byte[] bssid);
+
+    /**
+     * Indicates BTM request frame handling status.
+     *
+     * @param tmData Data retrieved from received BSS transition management
+     * request frame.
+     */
+    oneway void onBssTmHandlingDone(in BssTmData tmData);
+
+    /**
+     * Used to indicate the change of active bssid.
+     * This is useful to figure out when the driver/firmware roams to a bssid
+     * on its own.
+     *
+     * @param reason Reason why the bssid changed.
+     * @param bssid BSSID of the corresponding AP.
+     */
+    oneway void onBssidChanged(in BssidChangeReason reason, in byte[] bssid);
+
+    /**
+     * Used to indicate the disconnection from the currently connected
+     * network on this iface.
+     *
+     * @param bssid BSSID of the AP from which we disconnected.
+     * @param locallyGenerated If the disconnect was triggered by
+     *        wpa_supplicant.
+     * @param reasonCode 802.11 code to indicate the disconnect reason
+     *        from access point. Refer to section 8.4.1.7 of IEEE802.11 spec.
+     */
+    oneway void onDisconnected(
+            in byte[] bssid, in boolean locallyGenerated, in StaIfaceReasonCode reasonCode);
+
+    /**
+     * Indicates a DPP failure event.
+     *
+     * ssid: A string indicating the SSID for the AP that the Enrollee attempted to connect.
+     * channelList: A string containing a list of operating channels and operating classes
+     *     indicating the channels that the Enrollee scanned in attempting to discover the AP.
+     *     The list conforms to the following ABNF syntax:
+     *         channel-list2 = class-and-channels *(“,” class-and-channels)
+     *         class-and-channels = class “/” channel *(“,” channel)
+     *         class = 1*3DIGIT
+     *         channel = 1*3DIGIT
+     * bandList: A list of band parameters that are supported by the Enrollee expressed as the
+     *     Operating Class.
+     */
+    oneway void onDppFailure(
+            in DppFailureCode code, in String ssid, in String channelList, in char[] bandList);
+
+    /**
+     * Indicates a DPP progress event.
+     */
+    oneway void onDppProgress(in DppProgressCode code);
+
+    /**
+     * Indicates a DPP success event.
+     */
+    oneway void onDppSuccess(in DppEventType event);
+
+    /**
+     * Indicates DPP configuration received success event (Enrolee mode).
+     */
+    oneway void onDppSuccessConfigReceived(
+            in byte[] ssid, in String password, in byte[] psk, in DppAkm securityAkm);
+
+    /**
+     * Indicates DPP configuration sent success event (Configurator mode).
+     */
+    oneway void onDppSuccessConfigSent();
+
+    /**
+     * Indicates an EAP authentication failure.
+     * @param errorCode Error code for EAP authentication failure.
+     *        Either standard error code (enum EapErrorCode) or
+     *        private error code defined by network provider.
+     */
+    oneway void onEapFailure(in int errorCode);
+
+    /**
+     * Used to indicate that the external radio work can start now.
+     *
+     * @param id Identifier generated for the radio work request.
+     */
+    oneway void onExtRadioWorkStart(in int id);
+
+    /**
+     * Used to indicate that the external radio work request has timed out.
+     *
+     * @param id Identifier generated for the radio work request.
+     */
+    oneway void onExtRadioWorkTimeout(in int id);
+
+    /**
+     * Used to indicate a Hotspot 2.0 imminent deauth notice.
+     *
+     * @param bssid BSSID of the access point.
+     * @param reasonCode Code to indicate the deauth reason.
+     *        Refer to section 3.2.1.2 of the Hotspot 2.0 spec.
+     * @param reAuthDelayInSec Delay before reauthenticating.
+     * @param url URL of the server.
+     */
+    oneway void onHs20DeauthImminentNotice(
+            in byte[] bssid, in int reasonCode, in int reAuthDelayInSec, in String url);
+
+    /**
+     * Used to indicate the result of Hotspot 2.0 Icon query.
+     *
+     * @param bssid BSSID of the access point.
+     * @param fileName Name of the file that was requested.
+     * @param data Icon data fetched from the access point.
+     *        Must be empty if the query failed.
+     */
+    oneway void onHs20IconQueryDone(in byte[] bssid, in String fileName, in byte[] data);
+
+    /**
+     * Used to indicate a Hotspot 2.0 subscription remediation event.
+     *
+     * @param bssid BSSID of the access point.
+     * @param osuMethod OSU method.
+     * @param url URL of the server.
+     */
+    oneway void onHs20SubscriptionRemediation(
+            in byte[] bssid, in OsuMethod osuMethod, in String url);
+
+    /**
+     * Used to indicate a Hotspot 2.0 terms and conditions acceptance is requested from the user
+     * before allowing the device to get internet access.
+     *
+     * @param bssid BSSID of the access point.
+     * @param url URL of the T&C server.
+     */
+    oneway void onHs20TermsAndConditionsAcceptanceRequestedNotification(
+            in byte[] bssid, in String url);
+
+    /**
+     * Used to indicate that a new network has been added.
+     *
+     * @param id Network ID allocated to the corresponding network.
+     */
+    oneway void onNetworkAdded(in int id);
+
+    /**
+     * Used to indicate that the supplicant failed to find a network in scan result
+     * which matches with the network capabilities requested by upper layer
+     * for connection.
+     *
+     * @param ssid network name supplicant tried to connect.
+     */
+    oneway void onNetworkNotFound(in byte[] ssid);
+
+    /**
+     * Used to indicate that a network has been removed.
+     *
+     * @param id Network ID allocated to the corresponding network.
+     */
+    oneway void onNetworkRemoved(in int id);
+
+    /**
+     * Indicates pairwise master key (PMK) cache added event.
+     *
+     * @param expirationTimeInSec expiration time in seconds
+     * @param serializedEntry is serialized PMK cache entry, the content is
+     *              opaque for the framework and depends on the native implementation.
+     */
+    oneway void onPmkCacheAdded(in long expirationTimeInSec, in byte[] serializedEntry);
+
+    /**
+     * Used to indicate a state change event on this particular iface. If this
+     * event is triggered by a particular network, the |SupplicantNetworkId|,
+     * |ssid|, |bssid| parameters must indicate the parameters of the network/AP
+     * which caused this state transition.
+     *
+     * @param newState New State of the interface. This must be one of the |State|
+     *        values above.
+     * @param bssid BSSID of the corresponding AP which caused this state
+     *        change event. This must be zero'ed if this event is not
+     *        specific to a particular network.
+     * @param id ID of the corresponding network which caused this
+     *        state change event. This must be invalid (UINT32_MAX) if this
+     *        event is not specific to a particular network.
+     * @param ssid SSID of the corresponding network which caused this state
+     *        change event. This must be empty if this event is not specific
+     *        to a particular network.
+     * @param filsHlpSent If FILS HLP IEs were included in this association.
+     */
+    oneway void onStateChanged(in StaIfaceCallbackState newState, in byte[] bssid, in int id,
+            in byte[] ssid, in boolean filsHlpSent);
+
+    /**
+     * Used to indicate the failure of a WPS connection attempt.
+     *
+     * @param bssid BSSID of the AP to which we initiated WPS
+     *        connection.
+     * @param configError Configuration error code.
+     * @param errorInd Error indication code.
+     */
+    oneway void onWpsEventFail(
+            in byte[] bssid, in WpsConfigError configError, in WpsErrorIndication errorInd);
+
+    /**
+     * Used to indicate the overlap of a WPS PBC connection attempt.
+     */
+    oneway void onWpsEventPbcOverlap();
+
+    /**
+     * Used to indicate the success of a WPS connection attempt.
+     */
+    oneway void onWpsEventSuccess();
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaNetwork.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaNetwork.aidl
new file mode 100644
index 0000000..603e2ad
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaNetwork.aidl
@@ -0,0 +1,1095 @@
+/*
+ * 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.wifi.supplicant;
+
+import android.hardware.wifi.supplicant.AuthAlgMask;
+import android.hardware.wifi.supplicant.EapMethod;
+import android.hardware.wifi.supplicant.EapPhase2Method;
+import android.hardware.wifi.supplicant.GroupCipherMask;
+import android.hardware.wifi.supplicant.GroupMgmtCipherMask;
+import android.hardware.wifi.supplicant.ISupplicantStaNetworkCallback;
+import android.hardware.wifi.supplicant.IfaceType;
+import android.hardware.wifi.supplicant.KeyMgmtMask;
+import android.hardware.wifi.supplicant.NetworkResponseEapSimGsmAuthParams;
+import android.hardware.wifi.supplicant.NetworkResponseEapSimUmtsAuthParams;
+import android.hardware.wifi.supplicant.OcspType;
+import android.hardware.wifi.supplicant.PairwiseCipherMask;
+import android.hardware.wifi.supplicant.ProtoMask;
+import android.hardware.wifi.supplicant.SaeH2eMode;
+
+/**
+ * Interface exposed by the supplicant for each station mode network
+ * configuration it controls.
+ */
+@VintfStability
+interface ISupplicantStaNetwork {
+    /**
+     * Max length of SSID param.
+     */
+    const int SSID_MAX_LEN_IN_BYTES = 32;
+
+    /**
+     * Min length of PSK passphrase param.
+     */
+    const int PSK_PASSPHRASE_MIN_LEN_IN_BYTES = 8;
+
+    /**
+     * Max length of PSK passphrase param.
+     */
+    const int PSK_PASSPHRASE_MAX_LEN_IN_BYTES = 63;
+
+    /**
+     * Max number of WEP keys param.
+     */
+    const int WEP_KEYS_MAX_NUM = 4;
+
+    /**
+     * Length of each WEP40 keys param.
+     */
+    const int WEP40_KEY_LEN_IN_BYTES = 5;
+
+    /**
+     * Length of each WEP104 keys param.
+     */
+    const int WEP104_KEY_LEN_IN_BYTES = 13;
+
+    /**
+     * Disable the network for connection purposes.
+     *
+     * This must trigger a disconnection from the network, if currently
+     * connected to this one.
+     *
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void disable();
+
+    /**
+     * Enable the network for connection purposes.
+     *
+     * This must trigger a connection to the network if:
+     * a) |noConnect| is false, and
+     * b) This is the only network configured, and
+     * c) Is visible in the current scan results.
+     *
+     * @param noConnect Only enable the network, don't trigger a connect.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void enable(in boolean noConnect);
+
+    /**
+     * Set whether to enable SAE PK (Public Key) only mode to enable public AP validation.
+     * When enabled, only SAE PK network is allowed; otherwise PK is optional.
+     * If this API is not called before connecting to an SAE
+     * network, SAE PK mode depends on SAE PK config in wpa_supplicant configuration.
+     * If SAE PK config of wpa_supplicant configuration is not set,
+     * the default mode is optional (support for both PK and standard mode).
+     *
+     * @param enable true to set, false otherwise.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNSUPPORTED|
+     */
+    void enableSaePkOnlyMode(in boolean enable);
+
+    /**
+     * Set EAP OpenSSL Suite-B-192 ciphers for WPA3-Enterprise
+     *        Supported option:
+     *
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void enableSuiteBEapOpenSslCiphers();
+
+    /**
+     * Enable TLS Suite-B in EAP Phase1
+     *
+     * @param enable Set to true to enable TLS Suite-B in EAP phase1
+     *
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void enableTlsSuiteBEapPhase1Param(in boolean enable);
+
+    /**
+     * Get the auth alg mask set for the network.
+     *
+     * @return Combination of |AuthAlgMask| values.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    AuthAlgMask getAuthAlg();
+
+    /**
+     * Get the BSSID set for this network.
+     *
+     * @return bssid Value set.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    byte[] getBssid();
+
+    /**
+     * Get EAP Alt subject match set for this network.
+     *
+     * @return value set.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    String getEapAltSubjectMatch();
+
+    /**
+     * Get EAP Anonymous Identity set for this network.
+     *
+     * @return identity value set.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    byte[] getEapAnonymousIdentity();
+
+    /**
+     * Get EAP CA certificate file path set for this network.
+     *
+     * @return value set.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    String getEapCACert();
+
+    /**
+     * Get EAP CA certificate directory path set for this network.
+     *
+     * @return value set.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    String getEapCAPath();
+
+    /**
+     * Get EAP Client certificate file path set for this network.
+     *
+     * @return value set.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    String getEapClientCert();
+
+    /**
+     * Get EAP Domain suffix match set for this network.
+     *
+     * @return value set.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    String getEapDomainSuffixMatch();
+
+    /**
+     * Get whether EAP Open SSL Engine is enabled for this network.
+     *
+     * @return true if set, false otherwise.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    boolean getEapEngine();
+
+    /**
+     * Get EAP Open SSL Engine ID set for this network.
+     *
+     * @return value set.
+     * throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    String getEapEngineId();
+
+    /**
+     * Get EAP Identity set for this network.
+     *
+     * @return value set.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    byte[] getEapIdentity();
+
+    /**
+     * Get EAP Method set for this network.
+     *
+     * @return value set.
+     *        Must be one of |EapMethod| values.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    EapMethod getEapMethod();
+
+    /**
+     * Get EAP Password set for this network.
+     *
+     * @return value set.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    byte[] getEapPassword();
+
+    /**
+     * Get EAP Phase2 Method set for this network.
+     *
+     * @return value set.
+     *        Must be one of |EapPhase2Method| values.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    EapPhase2Method getEapPhase2Method();
+
+    /**
+     * Get EAP private key Id set for this network.
+     *
+     * @return value set.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|)
+     */
+    String getEapPrivateKeyId();
+
+    /**
+     * Get EAP subject match set for this network.
+     *
+     * @return value set.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    String getEapSubjectMatch();
+
+    /**
+     * Get whether enhanced directional multi-gigabit (802.11ay EDMG) is enabled for this network.
+     *
+     * @return true if set, false otherwise.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    boolean getEdmg();
+
+    /**
+     * Get the group cipher mask set for the network.
+     *
+     * @return Combination of |GroupCipherMask| values.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+     */
+    GroupCipherMask getGroupCipher();
+
+    /**
+     * Get the group management cipher mask set for the network.
+     *
+     * @return Combination of |GroupMgmtCipherMask| values.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    GroupMgmtCipherMask getGroupMgmtCipher();
+
+    /**
+     * Retrieves the ID allocated to this network by the supplicant.
+     *
+     * This is not the |SSID| of the network, but an internal identifier for
+     * this network used by the supplicant.
+     *
+     * @return Network ID.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    int getId();
+
+    /**
+     * Get ID string set for this network.
+     * Network identifier string for external scripts.
+     *
+     * @return ID string set.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    String getIdStr();
+
+    /**
+     * Retrieves the name of the interface this network belongs to.
+     *
+     * @return Name of the network interface, e.g., wlan0
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    String getInterfaceName();
+
+    /**
+     * Get the key mgmt mask set for the network.
+     *
+     * @return Combination of |KeyMgmtMask| values.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+     */
+    KeyMgmtMask getKeyMgmt();
+
+    /**
+     * Get OCSP (Online Certificate Status Protocol) type for this network.
+     *
+     * @return ocsp type.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    OcspType getOcsp();
+
+    /**
+     * Get the pairwise cipher mask set for the network.
+     *
+     * @return Combination of |PairwiseCipherMask| values.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+     */
+    PairwiseCipherMask getPairwiseCipher();
+
+    /**
+     * Get the proto mask set for the network.
+     *
+     * @return Combination of |ProtoMask| values.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+     */
+    ProtoMask getProto();
+
+    /**
+     * Get raw psk for WPA_PSK network.
+     *
+     * @return value set.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    byte[] getPsk();
+
+    /**
+     * Get passphrase for WPA_PSK network.
+     * Must return a failure if network has no passphrase set (use |getPsk| if
+     * network was configured with raw psk instead).
+     *
+     * @return value set.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    String getPskPassphrase();
+
+    /**
+     * Get whether RequirePmf is enabled for this network.
+     *
+     * @return true if set, false otherwise.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    boolean getRequirePmf();
+
+    /**
+     * Get SAE password for WPA3-Personal
+     *
+     * @return value set.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    String getSaePassword();
+
+    /**
+     * Get SAE password ID for WPA3-Personal
+     *
+     * @return value set.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    String getSaePasswordId();
+
+    /**
+     * Get whether Probe Requests are being sent for this network (hidden).
+     *
+     * @return true if set, false otherwise.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    boolean getScanSsid();
+
+    /**
+     *
+     * Getters for the various network params.
+     *
+     */
+
+    /**
+     * Get SSID for this network.
+     *
+     * @return value set.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    byte[] getSsid();
+
+    /**
+     * Retrieves the type of the interface this network belongs to.
+     *
+     * @return Type of the network interface, e.g., STA.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    IfaceType getType();
+
+    /**
+     * Get WAPI certificate suite name set for this network.
+     *
+     * @return The name of a suite.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+     */
+    String getWapiCertSuite();
+
+    /**
+     * Get WEP key for WEP network.
+     *
+     * @param keyIdx Index of wep key to be fetched.
+     *        Max of |WEP_KEYS_MAX_NUM|.
+     * @return value set.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    byte[] getWepKey(in int keyIdx);
+
+    /**
+     * Get default Tx key index for WEP network.
+     *
+     * @return value set.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    int getWepTxKeyIdx();
+
+    /**
+     * Retrieves a WPS-NFC configuration token for this network.
+     *
+     * @return Bytes representing WPS-NFC configuration token.
+     *         This is a dump of all the WPS atrributes of the AP configuration
+     *         as specified in the Wi-Fi Protected Setup Specification.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    byte[] getWpsNfcConfigurationToken();
+
+    /**
+     * Register for callbacks from this network.
+     *
+     * These callbacks are invoked for events that are specific to this network.
+     * Registration of multiple callback objects is supported. These objects must
+     * be automatically deleted when the corresponding client process is dead or
+     * if this network is removed.
+     *
+     * @param callback An instance of the |ISupplicantStaNetworkCallback| AIDL
+     *        interface object.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void registerCallback(in ISupplicantStaNetworkCallback callback);
+
+    /**
+     * Initiate connection to this network.
+     *
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void select();
+
+    /**
+     * Used to send a response to the
+     * |ISupplicantNetworkCallback.onNetworkEapIdentityRequest| request.
+     *
+     * @param identity Identity string containing the IMSI.
+     * @param encryptedIdentity Identity string containing the encrypted IMSI.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void sendNetworkEapIdentityResponse(in byte[] identity, in byte[] encryptedIdentity);
+
+    /**
+     * Used to send a response to the
+     * |ISupplicantNetworkCallback.onNetworkEapSimGsmAuthRequest| request.
+     *
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void sendNetworkEapSimGsmAuthFailure();
+
+    /**
+     * Used to send a response to the
+     * |ISupplicantNetworkCallback.onNetworkEapSimGsmAuthRequest| request.
+     *
+     * @param params Params to be used for EAP GSM authentication.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void sendNetworkEapSimGsmAuthResponse(in NetworkResponseEapSimGsmAuthParams[] params);
+
+    /**
+     * Used to send a response to the
+     * |ISupplicantNetworkCallback.onNetworkEapSimUmtsAuthRequest| request.
+     *
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void sendNetworkEapSimUmtsAuthFailure();
+
+    /**
+     * Used to send a response to the
+     * |ISupplicantNetworkCallback.onNetworkEapSimUmtsAuthRequest| request.
+     *
+     * @param params Params to be used for EAP UMTS authentication.
+     * @throws ServiceSpecificException with one of the following values:
+
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void sendNetworkEapSimUmtsAuthResponse(in NetworkResponseEapSimUmtsAuthParams params);
+
+    /**
+     * Used to send a response to the
+     * |ISupplicantNetworkCallback.onNetworkEapSimUmtsAuthRequest| request.
+     *
+     * @param auts Params to be used for EAP UMTS authentication.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void sendNetworkEapSimUmtsAutsResponse(in byte[] auts);
+
+    /**
+     * Set auth alg mask for the network.
+     *
+     * @param authAlgMask value to set.
+     *        Combination of |ProtoMask| values.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void setAuthAlg(in AuthAlgMask authAlgMask);
+
+    /**
+     * Set the network to only connect to an AP with provided BSSID.
+     *
+     * @param bssid value to set.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void setBssid(in byte[] bssid);
+
+    /**
+     * Set EAP Alt subject match for this network.
+     *
+     * @param match value to set.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void setEapAltSubjectMatch(in String match);
+
+    /**
+     * Set EAP Anonymous Identity for this network.
+     *
+     * @param identity value to set.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void setEapAnonymousIdentity(in byte[] identity);
+
+    /**
+     * Set EAP CA certificate file path for this network.
+     *
+     * @param path value to set.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void setEapCACert(in String path);
+
+    /**
+     * Set EAP CA certificate directory path for this network.
+     *
+     * @param path value to set.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void setEapCAPath(in String path);
+
+    /**
+     * Set EAP Client certificate file path for this network.
+     *
+     * @param path value to set.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void setEapClientCert(in String path);
+
+    /**
+     * Set EAP Domain suffix match for this network.
+     *
+     * @param match value to set.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void setEapDomainSuffixMatch(in String match);
+
+    /**
+     * Set EAP encrypted IMSI Identity for this network.
+     *
+     * @param identity Identity string built from the encrypted IMSI.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void setEapEncryptedImsiIdentity(in byte[] identity);
+
+    /**
+     * Enable EAP Open SSL Engine for this network.
+     *
+     * @param enable true to set, false otherwise.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void setEapEngine(in boolean enable);
+
+    /**
+     * Set EAP Open SSL Engine ID for this network.
+     *
+     * @param id value to set.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void setEapEngineID(in String id);
+
+    /**
+     * Enable Extensible Authentication (EAP) - Re-authentication Protocol (ERP) for this network.
+     *
+     * @param enable true to set, false otherwise.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void setEapErp(in boolean enable);
+
+    /**
+     * Set EAP Identity for this network.
+     *
+     * @param identity value to set.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void setEapIdentity(in byte[] identity);
+
+    /**
+     * Set EAP Method for this network.
+     *
+     * @param method value to be set.
+     *        Must be one of |EapMethod| values.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void setEapMethod(in EapMethod method);
+
+    /**
+     * Set EAP Password for this network.
+     *
+     * @param password value to set.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void setEapPassword(in byte[] password);
+
+    /**
+     * Set EAP Phase2 Method for this network.
+     *
+     * EAP method needs to be set for this to work.
+     *
+     * @param method value to set.
+     *        Must be one of |EapPhase2Method| values.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void setEapPhase2Method(in EapPhase2Method method);
+
+    /**
+     * Set EAP private key Id for this network.
+     * This is used if private key operations for EAP-TLS are performed
+     * using a smartcard.
+     *
+     * @param id value to set.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void setEapPrivateKeyId(in String id);
+
+    /**
+     * Set EAP subject match for this network.
+     *
+     * @param match value to set.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void setEapSubjectMatch(in String match);
+
+    /**
+     * Set whether to enable enhanced directional multi-gigabit (802.11ay EDMG).
+     * Only allowed if hw mode is |HOSTAPD_MODE_IEEE80211AD|
+     *
+     * @param enable true to set, false otherwise.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void setEdmg(in boolean enable);
+
+    /**
+     * Set group cipher mask for the network.
+     *
+     * @param groupCipherMask value to set.
+     *        Combination of |ProtoMask| values.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+     */
+    void setGroupCipher(in GroupCipherMask groupCipherMask);
+
+    /**
+     * Set group management cipher mask for the network.
+     *
+     * @param groupMgmtCipherMask value to set.
+     *        Combination of |GroupMgmtCipherMask| values.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void setGroupMgmtCipher(in GroupMgmtCipherMask groupMgmtCipherMask);
+
+    /**
+     * Set ID string for this network.
+     * Network identifier string for external scripts.
+     *
+     * @param idStr ID string value to set.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void setIdStr(in String idStr);
+
+    /**
+     * Set key management mask for the network.
+     *
+     * @param keyMgmtMask value to set.
+     *        Combination of |KeyMgmtMask| values.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+     */
+    void setKeyMgmt(in KeyMgmtMask keyMgmtMask);
+
+    /**
+     * Set OCSP (Online Certificate Status Protocol) type for this network.
+     *
+     * @param ocspType value to set.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void setOcsp(in OcspType ocspType);
+
+    /**
+     * Set pairwise cipher mask for the network.
+     *
+     * @param pairwiseCipherMask value to set.
+     *        Combination of |ProtoMask| values.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+     */
+    void setPairwiseCipher(in PairwiseCipherMask pairwiseCipherMask);
+
+    /**
+     * Add a pairwise master key (PMK) into supplicant PMK cache.
+     *
+     * @param serializedEntry is serialized PMK cache entry, the content is
+     *              opaque for the framework and depends on the native implementation.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void setPmkCache(in byte[] serializedEntry);
+
+    /**
+     * This field can be used to enable proactive key caching which is also
+     * known as opportunistic PMKSA caching for WPA2. This is disabled (0)
+     * by default unless default value is changed with the global okc=1
+     * parameter.
+     *
+     * Proactive key caching is used to make supplicant assume that the APs
+     * are using the same PMK and generate PMKSA cache entries without
+     * doing RSN pre-authentication. This requires support from the AP side
+     * and is normally used with wireless switches that co-locate the
+     * authenticator.
+     *
+     * @param enable true to set, false otherwise.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void setProactiveKeyCaching(in boolean enable);
+
+    /**
+     * Set proto mask for the network.
+     *
+     * @param protoMask value to set.
+     *        Combination of |ProtoMask| values.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+     */
+    void setProto(in ProtoMask protoMask);
+
+    /**
+     * Set raw psk for WPA_PSK network.
+     *
+     * @param psk value to set as specified in IEEE 802.11i-2004 standard.
+     *        This is the calculated using 'wpa_passphrase <ssid> [passphrase]'
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void setPsk(in byte[] psk);
+
+    /**
+     * Set passphrase for WPA_PSK network.
+     *
+     * @param psk value to set.
+     *        Length of value must be between
+     *        |PSK_PASSPHRASE_MIN_LEN_IN_BYTES| and
+     *        |PSK_PASSPHRASE_MAX_LEN_IN_BYTES|.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void setPskPassphrase(in String psk);
+
+    /**
+     * Set whether RequirePmf is enabled for this network.
+     *
+     * @param enable true to set, false otherwise.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void setRequirePmf(in boolean enable);
+
+    /**
+     * Set SAE H2E (Hash-to-Element) mode.
+     *
+     * @param mode SAE H2E supporting mode.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void setSaeH2eMode(in SaeH2eMode mode);
+
+    /**
+     * Set SAE password for WPA3-Personal
+     *
+     * @param saePassword string with the above option
+     *
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void setSaePassword(in String saePassword);
+
+    /**
+     * Set SAE password ID for WPA3-Personal
+     *
+     * @param sae_password_id string with the above option
+     *
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void setSaePasswordId(in String saePasswordId);
+
+    /**
+     * Set whether to send probe requests for this network (hidden).
+     *
+     * @param enable true to set, false otherwise.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void setScanSsid(in boolean enable);
+
+    /**
+     *
+     * Setters for the various network params.
+     * These correspond to elements of |wpa_sssid| struct used internally by
+     * the supplicant to represent each network.
+     *
+     */
+
+    /**
+     * Set SSID for this network.
+     *
+     * @param ssid value to set.
+     *        Max length of |SSID_MAX_LEN_IN_BYTES|.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void setSsid(in byte[] ssid);
+
+    /**
+     * Set PPS MO ID for this network.
+     * (Hotspot 2.0 PerProviderSubscription/UpdateIdentifier)
+     *
+     * @param id ID value to set.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void setUpdateIdentifier(in int id);
+
+    /**
+     * Set WAPI certificate suite name for this network.
+     *
+     * @param suite value to set.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+     */
+    void setWapiCertSuite(in String suite);
+
+    /**
+     * Set WEP key for WEP network.
+     *
+     * @param keyIdx Index of wep key to set.
+     *        Max of |WEP_KEYS_MAX_NUM|.
+     * @param wepKey value to set.
+     *        Length of each key must be either
+     *        |WEP40_KEY_LEN_IN_BYTES| or
+     *        |WEP104_KEY_LEN_IN_BYTES|.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void setWepKey(in int keyIdx, in byte[] wepKey);
+
+    /**
+     * Set default Tx key index for WEP network.
+     *
+     * @param keyIdx Value to set.
+     *        Max of |WEP_KEYS_MAX_NUM|.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+     */
+    void setWepTxKeyIdx(in int keyIdx);
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl
new file mode 100644
index 0000000..c28b494
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl
@@ -0,0 +1,65 @@
+/*
+ * 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.wifi.supplicant;
+
+import android.hardware.wifi.supplicant.NetworkRequestEapSimGsmAuthParams;
+import android.hardware.wifi.supplicant.NetworkRequestEapSimUmtsAuthParams;
+import android.hardware.wifi.supplicant.TransitionDisableIndication;
+
+/**
+ * Callback Interface exposed by the supplicant service
+ * for each network (ISupplicantStaNetwork).
+ *
+ * Clients need to host an instance of this AIDL interface object and
+ * pass a reference of the object to the supplicant via the
+ * corresponding |ISupplicantStaNetwork.registerCallback| method.
+ */
+@VintfStability
+interface ISupplicantStaNetworkCallback {
+    /**
+     * Used to request EAP Identity for this particular network.
+     *
+     * The response for the request must be sent using the corresponding
+     * |ISupplicantNetwork.sendNetworkEapIdentityResponse| call.
+     */
+    oneway void onNetworkEapIdentityRequest();
+
+    /**
+     * Used to request EAP GSM SIM authentication for this particular network.
+     *
+     * The response for the request must be sent using the corresponding
+     * |ISupplicantNetwork.sendNetworkEapSimGsmAuthResponse| call.
+     *
+     * @param params Params associated with the request.
+     */
+    oneway void onNetworkEapSimGsmAuthRequest(in NetworkRequestEapSimGsmAuthParams params);
+
+    /**
+     * Used to request EAP UMTS SIM authentication for this particular network.
+     *
+     * The response for the request must be sent using the corresponding
+     * |ISupplicantNetwork.sendNetworkEapSimUmtsAuthResponse| call.
+     *
+     * @param params Params associated with the request.
+     */
+    oneway void onNetworkEapSimUmtsAuthRequest(in NetworkRequestEapSimUmtsAuthParams params);
+
+    /**
+     * Used to notify WPA3 transition disable.
+     */
+    oneway void onTransitionDisable(in TransitionDisableIndication ind);
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/IfaceInfo.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/IfaceInfo.aidl
new file mode 100644
index 0000000..7792142
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/IfaceInfo.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.wifi.supplicant;
+
+import android.hardware.wifi.supplicant.IfaceType;
+
+/**
+ * Structure describing the type and name of an iface
+ * controlled by the supplicant.
+ */
+@VintfStability
+parcelable IfaceInfo {
+    /**
+     * Type of the network interface.
+     */
+    IfaceType type;
+    /**
+     * Name of the network interface, e.g., wlan0
+     */
+    String name;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/IfaceType.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/IfaceType.aidl
new file mode 100644
index 0000000..e39dcd1
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/IfaceType.aidl
@@ -0,0 +1,27 @@
+/*
+ * 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.wifi.supplicant;
+
+/**
+ * List of Iface types supported.
+ */
+@VintfStability
+@Backing(type="int")
+enum IfaceType {
+    STA,
+    P2P,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/KeyMgmtMask.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/KeyMgmtMask.aidl
new file mode 100644
index 0000000..3225585
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/KeyMgmtMask.aidl
@@ -0,0 +1,74 @@
+/*
+ * 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.wifi.supplicant;
+
+/**
+ * Possible mask of values for KeyMgmt param.
+ * See /external/wpa_supplicant_8/src/common/defs.h for
+ * all possible values (starting at WPA_KEY_MGMT_IEEE8021X).
+ */
+@VintfStability
+@Backing(type="int")
+enum KeyMgmtMask {
+    WPA_EAP = 1 << 0,
+    WPA_PSK = 1 << 1,
+    NONE = 1 << 2,
+    IEEE8021X = 1 << 3,
+    FT_EAP = 1 << 5,
+    FT_PSK = 1 << 6,
+    OSEN = 1 << 15,
+    /**
+     * WPA using EAP authentication with stronger SHA256-based algorithms
+     */
+    WPA_EAP_SHA256 = 1 << 7,
+    /**
+     * WPA pre-shared key with stronger SHA256-based algorithms
+     */
+    WPA_PSK_SHA256 = 1 << 8,
+    /**
+     * WPA3-Personal SAE Key management
+     */
+    SAE = 1 << 10,
+    /**
+     * WPA3-Enterprise Suite-B Key management
+     */
+    SUITE_B_192 = 1 << 17,
+    /**
+     * Enhacned Open (OWE) Key management
+     */
+    OWE = 1 << 22,
+    /**
+     * Easy Connect (DPP) Key management
+     */
+    DPP = 1 << 23,
+    /*
+     * WAPI Psk
+     */
+    WAPI_PSK = 1 << 12,
+    /**
+     * WAPI Cert
+     */
+    WAPI_CERT = 1 << 13,
+    /**
+     * FILS shared key authentication with sha-256
+     */
+    FILS_SHA256 = 1 << 18,
+    /**
+     * FILS shared key authentication with sha-384
+     */
+    FILS_SHA384 = 1 << 19,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/LegacyMode.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/LegacyMode.aidl
new file mode 100644
index 0000000..f933f6c
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/LegacyMode.aidl
@@ -0,0 +1,38 @@
+/*
+ * 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.wifi.supplicant;
+
+/**
+ * Detailed network mode for legacy network
+ */
+@VintfStability
+@Backing(type="int")
+enum LegacyMode {
+    UNKNOWN = 0,
+    /**
+     * For 802.11a
+     */
+    A_MODE = 1,
+    /**
+     * For 802.11b
+     */
+    B_MODE = 2,
+    /**
+     * For 802.11g
+     */
+    G_MODE = 3,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/MacAddress.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/MacAddress.aidl
new file mode 100644
index 0000000..40ad22a
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/MacAddress.aidl
@@ -0,0 +1,29 @@
+/*
+ * 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.wifi.supplicant;
+
+/**
+ * Byte array representing a Mac Address. Use when we need
+ * to pass an array of Mac Addresses to a method, as 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/supplicant/aidl/android/hardware/wifi/supplicant/MboAssocDisallowedReasonCode.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/MboAssocDisallowedReasonCode.aidl
new file mode 100644
index 0000000..41868aa
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/MboAssocDisallowedReasonCode.aidl
@@ -0,0 +1,32 @@
+/*
+ * 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.wifi.supplicant;
+
+/**
+ *  MBO spec v1.2, 4.2.4 Table 14: MBO Association disallowed reason code attribute
+ *  values.
+ */
+@VintfStability
+@Backing(type="byte")
+enum MboAssocDisallowedReasonCode {
+    RESERVED = 0,
+    UNSPECIFIED = 1,
+    MAX_NUM_STA_ASSOCIATED = 2,
+    AIR_INTERFACE_OVERLOADED = 3,
+    AUTH_SERVER_OVERLOADED = 4,
+    INSUFFICIENT_RSSI = 5,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/MboCellularDataConnectionPrefValue.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/MboCellularDataConnectionPrefValue.aidl
new file mode 100644
index 0000000..98f707e
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/MboCellularDataConnectionPrefValue.aidl
@@ -0,0 +1,33 @@
+/*
+ * 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.wifi.supplicant;
+
+/**
+ *  MBO spec v1.2, 4.2.5 Table 16: MBO Cellular Data connection preference
+ *  attribute values. AP use this to indicate STA, its preference for the
+ *  STA to move from BSS to cellular network.
+ */
+@VintfStability
+@Backing(type="int")
+enum MboCellularDataConnectionPrefValue {
+    EXCLUDED = 0,
+    NOT_PREFERRED = 1,
+    /*
+     * 2-254 Reserved.
+     */
+    PREFERRED = 255,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/MboTransitionReasonCode.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/MboTransitionReasonCode.aidl
new file mode 100644
index 0000000..66ad9ee
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/MboTransitionReasonCode.aidl
@@ -0,0 +1,36 @@
+/*
+ * 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.wifi.supplicant;
+
+/**
+ *  MBO spec v1.2, 4.2.6 Table 18: MBO transition reason code attribute
+ *  values.
+ */
+@VintfStability
+@Backing(type="byte")
+enum MboTransitionReasonCode {
+    UNSPECIFIED = 0,
+    EXCESSIVE_FRAME_LOSS = 1,
+    EXCESSIVE_TRAFFIC_DELAY = 2,
+    INSUFFICIENT_BANDWIDTH = 3,
+    LOAD_BALANCING = 4,
+    LOW_RSSI = 5,
+    RX_EXCESSIVE_RETRIES = 6,
+    HIGH_INTERFERENCE = 7,
+    GRAY_ZONE = 8,
+    TRANSITION_TO_PREMIUM_AP = 9,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/MiracastMode.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/MiracastMode.aidl
new file mode 100644
index 0000000..4eaaf1d
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/MiracastMode.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.wifi.supplicant;
+
+/**
+ * Enum describing the modes of Miracast supported
+ * via driver commands.
+ */
+@VintfStability
+@Backing(type="byte")
+enum MiracastMode {
+    DISABLED = 0,
+    /**
+     * Operating as source.
+     */
+    SOURCE = 1,
+    /**
+     * Operating as sink.
+     */
+    SINK = 2,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/NetworkRequestEapSimGsmAuthParams.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/NetworkRequestEapSimGsmAuthParams.aidl
new file mode 100644
index 0000000..c706c81
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/NetworkRequestEapSimGsmAuthParams.aidl
@@ -0,0 +1,27 @@
+/*
+ * 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.wifi.supplicant;
+
+import android.hardware.wifi.supplicant.GsmRand;
+
+/**
+ * Params of |onNetworkEapSimGsmAuthRequest| request. (Refer RFC 4186)
+ */
+@VintfStability
+parcelable NetworkRequestEapSimGsmAuthParams {
+    GsmRand[] rands;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/NetworkRequestEapSimUmtsAuthParams.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/NetworkRequestEapSimUmtsAuthParams.aidl
new file mode 100644
index 0000000..2f5e7fa
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/NetworkRequestEapSimUmtsAuthParams.aidl
@@ -0,0 +1,26 @@
+/*
+ * 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.wifi.supplicant;
+
+/**
+ * Params of |onNetworkEapSimUmtsAuthRequest| request. (Refer RFC 4187)
+ */
+@VintfStability
+parcelable NetworkRequestEapSimUmtsAuthParams {
+    byte[/* 16 */] rand;
+    byte[/* 16 */] autn;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/NetworkResponseEapSimGsmAuthParams.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/NetworkResponseEapSimGsmAuthParams.aidl
new file mode 100644
index 0000000..38929a2
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/NetworkResponseEapSimGsmAuthParams.aidl
@@ -0,0 +1,26 @@
+/*
+ * 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.wifi.supplicant;
+
+/**
+ * Params of |sendNetworkEapSimGsmAuthResponse| request. (Refer RFC 4186)
+ */
+@VintfStability
+parcelable NetworkResponseEapSimGsmAuthParams {
+    byte[/* 8 */] kc;
+    byte[/* 4 */] sres;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/NetworkResponseEapSimUmtsAuthParams.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/NetworkResponseEapSimUmtsAuthParams.aidl
new file mode 100644
index 0000000..5311016
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/NetworkResponseEapSimUmtsAuthParams.aidl
@@ -0,0 +1,27 @@
+/*
+ * 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.wifi.supplicant;
+
+/**
+ * Params of |sendNetworkEapSimUmtsAuthResponse| request. (Refer RFC 4187)
+ */
+@VintfStability
+parcelable NetworkResponseEapSimUmtsAuthParams {
+    byte[] res;
+    byte[/* 16 */] ik;
+    byte[/* 16 */] ck;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/OceRssiBasedAssocRejectAttr.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/OceRssiBasedAssocRejectAttr.aidl
new file mode 100644
index 0000000..09ec09c
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/OceRssiBasedAssocRejectAttr.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.
+ */
+
+package android.hardware.wifi.supplicant;
+
+/**
+ * OceRssiBasedAssocRejectAttr is extracted from (Re-)Association response
+ * frame from an OCE AP to indicate that the AP has rejected the
+ * (Re-)Association request on the basis of insufficient RSSI.
+ * Refer OCE spec v1.0 section 4.2.2 Table 7.
+ */
+@VintfStability
+parcelable OceRssiBasedAssocRejectAttr {
+    /*
+     * Delta RSSI - The difference in dB between the minimum RSSI at which
+     * the AP would accept a (Re-)Association request from the STA before
+     * Retry Delay expires and the AP's measurement of the RSSI at which the
+     * (Re-)Association request was received.
+     */
+    int deltaRssi;
+    /*
+     * Retry Delay - The time period in seconds for which the AP will not
+     * accept any subsequent (Re-)Association requests from the STA, unless
+     * the received RSSI has improved by Delta RSSI.
+     */
+    int retryDelayS;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/OcspType.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/OcspType.aidl
new file mode 100644
index 0000000..876fb11
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/OcspType.aidl
@@ -0,0 +1,29 @@
+/*
+ * 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.wifi.supplicant;
+
+/**
+ * OcspType: The type of OCSP request.
+ */
+@VintfStability
+@Backing(type="int")
+enum OcspType {
+    NONE,
+    REQUEST_CERT_STATUS,
+    REQUIRE_CERT_STATUS,
+    REQUIRE_ALL_CERTS_STATUS,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/OsuMethod.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/OsuMethod.aidl
new file mode 100644
index 0000000..a060365
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/OsuMethod.aidl
@@ -0,0 +1,27 @@
+/*
+ * 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.wifi.supplicant;
+
+/**
+ * OSU Method. Refer to section 4.8.1.3 of the Hotspot 2.0 spec.
+ */
+@VintfStability
+@Backing(type="byte")
+enum OsuMethod {
+    OMA_DM = 0,
+    SOAP_XML_SPP = 1,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pGroupCapabilityMask.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pGroupCapabilityMask.aidl
new file mode 100644
index 0000000..bda3c34
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pGroupCapabilityMask.aidl
@@ -0,0 +1,34 @@
+/*
+ * 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.wifi.supplicant;
+
+/**
+ * P2P group capability.
+ * See /external/wpa_supplicant_8/src/common/ieee802_11_defs.h
+ * for all possible values (starting at P2P_GROUP_CAPAB_GROUP_OWNER).
+ */
+@VintfStability
+@Backing(type="int")
+enum P2pGroupCapabilityMask {
+    GROUP_OWNER = 1 << 0,
+    PERSISTENT_GROUP = 1 << 1,
+    GROUP_LIMIT = 1 << 2,
+    INTRA_BSS_DIST = 1 << 3,
+    CROSS_CONN = 1 << 4,
+    PERSISTENT_RECONN = 1 << 5,
+    GROUP_FORMATION = 1 << 6,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pProvDiscStatusCode.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pProvDiscStatusCode.aidl
new file mode 100644
index 0000000..9effd0a
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pProvDiscStatusCode.aidl
@@ -0,0 +1,30 @@
+/*
+ * 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.wifi.supplicant;
+
+/**
+ * Status codes for P2P discovery.
+ */
+@VintfStability
+@Backing(type="byte")
+enum P2pProvDiscStatusCode {
+    SUCCESS = 0,
+    TIMEOUT = 1,
+    REJECTED = 2,
+    TIMEOUT_JOIN = 3,
+    INFO_UNAVAILABLE = 4,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pStatusCode.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pStatusCode.aidl
new file mode 100644
index 0000000..4020f9e
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pStatusCode.aidl
@@ -0,0 +1,38 @@
+/*
+ * 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.wifi.supplicant;
+
+/**
+ * Status codes for P2P operations.
+ */
+@VintfStability
+@Backing(type="int")
+enum P2pStatusCode {
+    SUCCESS = 0,
+    FAIL_INFO_CURRENTLY_UNAVAILABLE = 1,
+    FAIL_INCOMPATIBLE_PARAMS = 2,
+    FAIL_LIMIT_REACHED = 3,
+    FAIL_INVALID_PARAMS = 4,
+    FAIL_UNABLE_TO_ACCOMMODATE = 5,
+    FAIL_PREV_PROTOCOL_ERROR = 6,
+    FAIL_NO_COMMON_CHANNELS = 7,
+    FAIL_UNKNOWN_GROUP = 8,
+    FAIL_BOTH_GO_INTENT_15 = 9,
+    FAIL_INCOMPATIBLE_PROV_METHOD = 10,
+    FAIL_REJECTED_BY_USER = 11,
+    SUCCESS_DEFERRED = 12,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/PairwiseCipherMask.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/PairwiseCipherMask.aidl
new file mode 100644
index 0000000..ad134fa
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/PairwiseCipherMask.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.
+ */
+
+package android.hardware.wifi.supplicant;
+
+/**
+ * Possible mask of values for PairwiseCipher param.
+ * See /external/wpa_supplicant_8/src/common/defs.h for
+ * all possible values (starting at WPA_CIPHER_NONE).
+ */
+@VintfStability
+@Backing(type="int")
+enum PairwiseCipherMask {
+    NONE = 1 << 0,
+    TKIP = 1 << 3,
+    CCMP = 1 << 4,
+    /**
+     * GCMP-128 Pairwise Cipher
+     */
+    GCMP_128 = 1 << 6,
+    /**
+     * SMS4 Pairwise Cipher
+     */
+    SMS4 = 1 << 7,
+    /**
+     * GCMP-256 Pairwise Cipher
+     */
+    GCMP_256 = 1 << 8,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ProtoMask.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ProtoMask.aidl
new file mode 100644
index 0000000..65c832b
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ProtoMask.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.wifi.supplicant;
+
+/**
+ * Possible mask of values for Proto param.
+ * See /external/wpa_supplicant_8/src/common/defs.h for
+ * all possible values (starting at WPA_PROTO_WPA).
+ */
+@VintfStability
+@Backing(type="int")
+enum ProtoMask {
+    WPA = 1 << 0,
+    RSN = 1 << 1,
+    WAPI = 1 << 2,
+    OSEN = 1 << 3,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/RxFilterType.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/RxFilterType.aidl
new file mode 100644
index 0000000..5dfb73e
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/RxFilterType.aidl
@@ -0,0 +1,28 @@
+/*
+ * 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.wifi.supplicant;
+
+/**
+ * Enum describing the types of RX filter supported
+ * via driver commands.
+ */
+@VintfStability
+@Backing(type="byte")
+enum RxFilterType {
+    V4_MULTICAST = 0,
+    V6_MULTICAST = 1,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/SaeH2eMode.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/SaeH2eMode.aidl
new file mode 100644
index 0000000..48a879b
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/SaeH2eMode.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.wifi.supplicant;
+
+/**
+ * SAE Hash-to-Element mode.
+ */
+@VintfStability
+@Backing(type="byte")
+enum SaeH2eMode {
+    /**
+     * Hash-to-Element is disabled, only Hunting & Pecking is allowed.
+     */
+    DISABLED,
+    /**
+     * Both Hash-to-Element and Hunting & Pecking are allowed.
+     */
+    H2E_OPTIONAL,
+    /**
+     * Only Hash-to-Element is allowed.
+     */
+    H2E_MANDATORY,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/StaIfaceCallbackState.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/StaIfaceCallbackState.aidl
new file mode 100644
index 0000000..19f6f88
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/StaIfaceCallbackState.aidl
@@ -0,0 +1,100 @@
+/*
+ * 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.wifi.supplicant;
+
+/**
+ * Various states of the interface reported by |onStateChanged|.
+ */
+@VintfStability
+@Backing(type="int")
+enum StaIfaceCallbackState {
+    /**
+     * This state indicates that client is not associated, but is likely to
+     * start looking for an access point. This state is entered when a
+     * connection is lost.
+     */
+    DISCONNECTED = 0,
+    /**
+     * This state is entered if the network interface is disabled, e.g.,
+     * due to rfkill. the supplicant refuses any new operations that would
+     * use the radio until the interface has been enabled.
+     */
+    IFACE_DISABLED = 1,
+    /**
+     * This state is entered if there are no enabled networks in the
+     * configuration. the supplicant is not trying to associate with a new
+     * network and external interaction (e.g., ctrl_iface call to add or
+     * enable a network) is needed to start association.
+     */
+    INACTIVE = 2,
+    /**
+     * This state is entered when the supplicant starts scanning for a
+     * network.
+     */
+    SCANNING = 3,
+    /**
+     * This state is entered when the supplicant has found a suitable BSS
+     * to authenticate with and the driver is configured to try to
+     * authenticate with this BSS. This state is used only with drivers
+     * that use the supplicant as the SME.
+     */
+    AUTHENTICATING = 4,
+    /**
+     * This state is entered when the supplicant has found a suitable BSS
+     * to associate with and the driver is configured to try to associate
+     * with this BSS in ap_scan=1 mode. When using ap_scan=2 mode, this
+     * state is entered when the driver is configured to try to associate
+     * with a network using the configured SSID and security policy.
+     */
+    ASSOCIATING = 5,
+    /**
+     * This state is entered when the driver reports that association has
+     * been successfully completed with an AP. If IEEE 802.1X is used
+     * (with or without WPA/WPA2), the supplicant remains in this state
+     * until the IEEE 802.1X/EAPOL authentication has been completed.
+     */
+    ASSOCIATED = 6,
+    /**
+     * This state is entered when WPA/WPA2 4-Way Handshake is started. In
+     * case of WPA-PSK, this happens when receiving the first EAPOL-Key
+     * frame after association. In case of WPA-EAP, this state is entered
+     * when the IEEE 802.1X/EAPOL authentication has been completed.
+     */
+    FOURWAY_HANDSHAKE = 7,
+    /**
+     * This state is entered when 4-Way Key Handshake has been completed
+     * (i.e., when the supplicant sends out message 4/4) and when Group
+     * Key rekeying is started by the AP (i.e., when supplicant receives
+     * message 1/2).
+     */
+    GROUP_HANDSHAKE = 8,
+    /**
+     * This state is entered when the full authentication process is
+     * completed. In case of WPA2, this happens when the 4-Way Handshake is
+     * successfully completed. With WPA, this state is entered after the
+     * Group Key Handshake; with IEEE 802.1X (non-WPA) connection is
+     * completed after dynamic keys are received (or if not used, after
+     * the EAP authentication has been completed). With static WEP keys and
+     * plaintext connections, this state is entered when an association
+     * has been completed.
+     *
+     * This state indicates that the supplicant has completed its
+     * processing for the association phase and that data connection is
+     * fully configured.
+     */
+    COMPLETED = 9,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/StaIfaceReasonCode.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/StaIfaceReasonCode.aidl
new file mode 100644
index 0000000..6b05c07
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/StaIfaceReasonCode.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.wifi.supplicant;
+
+/**
+ * Reason codes (IEEE Std 802.11-2016, 9.4.1.7, Table 9-45).
+ */
+@VintfStability
+@Backing(type="int")
+enum StaIfaceReasonCode {
+    UNSPECIFIED = 1,
+    PREV_AUTH_NOT_VALID = 2,
+    DEAUTH_LEAVING = 3,
+    DISASSOC_DUE_TO_INACTIVITY = 4,
+    DISASSOC_AP_BUSY = 5,
+    CLASS2_FRAME_FROM_NONAUTH_STA = 6,
+    CLASS3_FRAME_FROM_NONASSOC_STA = 7,
+    DISASSOC_STA_HAS_LEFT = 8,
+    STA_REQ_ASSOC_WITHOUT_AUTH = 9,
+    PWR_CAPABILITY_NOT_VALID = 10,
+    SUPPORTED_CHANNEL_NOT_VALID = 11,
+    BSS_TRANSITION_DISASSOC = 12,
+    INVALID_IE = 13,
+    MICHAEL_MIC_FAILURE = 14,
+    FOURWAY_HANDSHAKE_TIMEOUT = 15,
+    GROUP_KEY_UPDATE_TIMEOUT = 16,
+    IE_IN_4WAY_DIFFERS = 17,
+    GROUP_CIPHER_NOT_VALID = 18,
+    PAIRWISE_CIPHER_NOT_VALID = 19,
+    AKMP_NOT_VALID = 20,
+    UNSUPPORTED_RSN_IE_VERSION = 21,
+    INVALID_RSN_IE_CAPAB = 22,
+    IEEE_802_1X_AUTH_FAILED = 23,
+    CIPHER_SUITE_REJECTED = 24,
+    TDLS_TEARDOWN_UNREACHABLE = 25,
+    TDLS_TEARDOWN_UNSPECIFIED = 26,
+    SSP_REQUESTED_DISASSOC = 27,
+    NO_SSP_ROAMING_AGREEMENT = 28,
+    BAD_CIPHER_OR_AKM = 29,
+    NOT_AUTHORIZED_THIS_LOCATION = 30,
+    SERVICE_CHANGE_PRECLUDES_TS = 31,
+    UNSPECIFIED_QOS_REASON = 32,
+    NOT_ENOUGH_BANDWIDTH = 33,
+    DISASSOC_LOW_ACK = 34,
+    EXCEEDED_TXOP = 35,
+    STA_LEAVING = 36,
+    END_TS_BA_DLS = 37,
+    UNKNOWN_TS_BA = 38,
+    TIMEOUT = 39,
+    PEERKEY_MISMATCH = 45,
+    AUTHORIZED_ACCESS_LIMIT_REACHED = 46,
+    EXTERNAL_SERVICE_REQUIREMENTS = 47,
+    INVALID_FT_ACTION_FRAME_COUNT = 48,
+    INVALID_PMKID = 49,
+    INVALID_MDE = 50,
+    INVALID_FTE = 51,
+    MESH_PEERING_CANCELLED = 52,
+    MESH_MAX_PEERS = 53,
+    MESH_CONFIG_POLICY_VIOLATION = 54,
+    MESH_CLOSE_RCVD = 55,
+    MESH_MAX_RETRIES = 56,
+    MESH_CONFIRM_TIMEOUT = 57,
+    MESH_INVALID_GTK = 58,
+    MESH_INCONSISTENT_PARAMS = 59,
+    MESH_INVALID_SECURITY_CAP = 60,
+    MESH_PATH_ERROR_NO_PROXY_INFO = 61,
+    MESH_PATH_ERROR_NO_FORWARDING_INFO = 62,
+    MESH_PATH_ERROR_DEST_UNREACHABLE = 63,
+    MAC_ADDRESS_ALREADY_EXISTS_IN_MBSS = 64,
+    MESH_CHANNEL_SWITCH_REGULATORY_REQ = 65,
+    MESH_CHANNEL_SWITCH_UNSPECIFIED = 66,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/StaIfaceStatusCode.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/StaIfaceStatusCode.aidl
new file mode 100644
index 0000000..75e7f68
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/StaIfaceStatusCode.aidl
@@ -0,0 +1,122 @@
+/*
+ * 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.wifi.supplicant;
+
+/**
+ * Status codes (IEEE Std 802.11-2016, 9.4.1.9, Table 9-46).
+ */
+@VintfStability
+@Backing(type="int")
+enum StaIfaceStatusCode {
+    SUCCESS = 0,
+    UNSPECIFIED_FAILURE = 1,
+    TDLS_WAKEUP_ALTERNATE = 2,
+    TDLS_WAKEUP_REJECT = 3,
+    SECURITY_DISABLED = 5,
+    UNACCEPTABLE_LIFETIME = 6,
+    NOT_IN_SAME_BSS = 7,
+    CAPS_UNSUPPORTED = 10,
+    REASSOC_NO_ASSOC = 11,
+    ASSOC_DENIED_UNSPEC = 12,
+    NOT_SUPPORTED_AUTH_ALG = 13,
+    UNKNOWN_AUTH_TRANSACTION = 14,
+    CHALLENGE_FAIL = 15,
+    AUTH_TIMEOUT = 16,
+    AP_UNABLE_TO_HANDLE_NEW_STA = 17,
+    ASSOC_DENIED_RATES = 18,
+    ASSOC_DENIED_NOSHORT = 19,
+    SPEC_MGMT_REQUIRED = 22,
+    PWR_CAPABILITY_NOT_VALID = 23,
+    SUPPORTED_CHANNEL_NOT_VALID = 24,
+    ASSOC_DENIED_NO_SHORT_SLOT_TIME = 25,
+    ASSOC_DENIED_NO_HT = 27,
+    R0KH_UNREACHABLE = 28,
+    ASSOC_DENIED_NO_PCO = 29,
+    ASSOC_REJECTED_TEMPORARILY = 30,
+    ROBUST_MGMT_FRAME_POLICY_VIOLATION = 31,
+    UNSPECIFIED_QOS_FAILURE = 32,
+    DENIED_INSUFFICIENT_BANDWIDTH = 33,
+    DENIED_POOR_CHANNEL_CONDITIONS = 34,
+    DENIED_QOS_NOT_SUPPORTED = 35,
+    REQUEST_DECLINED = 37,
+    INVALID_PARAMETERS = 38,
+    REJECTED_WITH_SUGGESTED_CHANGES = 39,
+    INVALID_IE = 40,
+    GROUP_CIPHER_NOT_VALID = 41,
+    PAIRWISE_CIPHER_NOT_VALID = 42,
+    AKMP_NOT_VALID = 43,
+    UNSUPPORTED_RSN_IE_VERSION = 44,
+    INVALID_RSN_IE_CAPAB = 45,
+    CIPHER_REJECTED_PER_POLICY = 46,
+    TS_NOT_CREATED = 47,
+    DIRECT_LINK_NOT_ALLOWED = 48,
+    DEST_STA_NOT_PRESENT = 49,
+    DEST_STA_NOT_QOS_STA = 50,
+    ASSOC_DENIED_LISTEN_INT_TOO_LARGE = 51,
+    INVALID_FT_ACTION_FRAME_COUNT = 52,
+    INVALID_PMKID = 53,
+    INVALID_MDIE = 54,
+    INVALID_FTIE = 55,
+    REQUESTED_TCLAS_NOT_SUPPORTED = 56,
+    INSUFFICIENT_TCLAS_PROCESSING_RESOURCES = 57,
+    TRY_ANOTHER_BSS = 58,
+    GAS_ADV_PROTO_NOT_SUPPORTED = 59,
+    NO_OUTSTANDING_GAS_REQ = 60,
+    GAS_RESP_NOT_RECEIVED = 61,
+    STA_TIMED_OUT_WAITING_FOR_GAS_RESP = 62,
+    GAS_RESP_LARGER_THAN_LIMIT = 63,
+    REQ_REFUSED_HOME = 64,
+    ADV_SRV_UNREACHABLE = 65,
+    REQ_REFUSED_SSPN = 67,
+    REQ_REFUSED_UNAUTH_ACCESS = 68,
+    INVALID_RSNIE = 72,
+    U_APSD_COEX_NOT_SUPPORTED = 73,
+    U_APSD_COEX_MODE_NOT_SUPPORTED = 74,
+    BAD_INTERVAL_WITH_U_APSD_COEX = 75,
+    ANTI_CLOGGING_TOKEN_REQ = 76,
+    FINITE_CYCLIC_GROUP_NOT_SUPPORTED = 77,
+    CANNOT_FIND_ALT_TBTT = 78,
+    TRANSMISSION_FAILURE = 79,
+    REQ_TCLAS_NOT_SUPPORTED = 80,
+    TCLAS_RESOURCES_EXCHAUSTED = 81,
+    REJECTED_WITH_SUGGESTED_BSS_TRANSITION = 82,
+    REJECT_WITH_SCHEDULE = 83,
+    REJECT_NO_WAKEUP_SPECIFIED = 84,
+    SUCCESS_POWER_SAVE_MODE = 85,
+    PENDING_ADMITTING_FST_SESSION = 86,
+    PERFORMING_FST_NOW = 87,
+    PENDING_GAP_IN_BA_WINDOW = 88,
+    REJECT_U_PID_SETTING = 89,
+    REFUSED_EXTERNAL_REASON = 92,
+    REFUSED_AP_OUT_OF_MEMORY = 93,
+    REJECTED_EMERGENCY_SERVICE_NOT_SUPPORTED = 94,
+    QUERY_RESP_OUTSTANDING = 95,
+    REJECT_DSE_BAND = 96,
+    TCLAS_PROCESSING_TERMINATED = 97,
+    TS_SCHEDULE_CONFLICT = 98,
+    DENIED_WITH_SUGGESTED_BAND_AND_CHANNEL = 99,
+    MCCAOP_RESERVATION_CONFLICT = 100,
+    MAF_LIMIT_EXCEEDED = 101,
+    MCCA_TRACK_LIMIT_EXCEEDED = 102,
+    DENIED_DUE_TO_SPECTRUM_MANAGEMENT = 103,
+    ASSOC_DENIED_NO_VHT = 104,
+    ENABLEMENT_DENIED = 105,
+    RESTRICTION_FROM_AUTHORIZED_GDB = 106,
+    AUTHORIZATION_DEENABLED = 107,
+    FILS_AUTHENTICATION_FAILURE = 112,
+    UNKNOWN_AUTHENTICATION_SERVER = 113,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/SupplicantStatusCode.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/SupplicantStatusCode.aidl
new file mode 100644
index 0000000..c7b7ffd
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/SupplicantStatusCode.aidl
@@ -0,0 +1,66 @@
+/*
+ * 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.wifi.supplicant;
+
+/**
+ * Enum values indicating the status of any supplicant operation.
+ */
+@VintfStability
+@Backing(type="int")
+enum SupplicantStatusCode {
+    /**
+     * No errors.
+     */
+    SUCCESS,
+    /**
+     * Unknown failure occurred.
+     */
+    FAILURE_UNKNOWN,
+    /**
+     * One of the incoming args is invalid.
+     */
+    FAILURE_ARGS_INVALID,
+    /**
+     * |ISupplicantIface| AIDL interface object is no longer valid.
+     */
+    FAILURE_IFACE_INVALID,
+    /**
+     * Iface with the provided name does not exist.
+     */
+    FAILURE_IFACE_UNKNOWN,
+    /**
+     * Iface with the provided name already exists.
+     */
+    FAILURE_IFACE_EXISTS,
+    /**
+     * Iface is disabled and cannot be used.
+     */
+    FAILURE_IFACE_DISABLED,
+    /**
+     * Iface is not currently disconnected, so cannot reconnect.
+     */
+    FAILURE_IFACE_NOT_DISCONNECTED,
+    /**
+     * |ISupplicantNetwork| AIDL interface object is no longer valid.
+     */
+    FAILURE_NETWORK_INVALID,
+    /**
+     * Network with the provided id does not exist.
+     */
+    FAILURE_NETWORK_UNKNOWN,
+    FAILURE_UNSUPPORTED,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/TransitionDisableIndication.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/TransitionDisableIndication.aidl
new file mode 100644
index 0000000..baf20a8
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/TransitionDisableIndication.aidl
@@ -0,0 +1,33 @@
+/*
+ * 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.wifi.supplicant;
+
+/**
+ * WPA3™ Specification Addendum for WPA3 R3 - Table 3.
+ * Transition Disable Indication filled in the third
+ * 4-way handshake message.
+ * See /external/wpa_supplicant_8/src/common/wpa_common.h for
+ * all possible values (starting at TRANSITION_DISABLE_WPA3_PERSONAL).
+ */
+@VintfStability
+@Backing(type="int")
+enum TransitionDisableIndication {
+    USE_WPA3_PERSONAL = 1 << 0,
+    USE_SAE_PK = 1 << 1,
+    USE_WPA3_ENTERPRISE = 1 << 2,
+    USE_ENHANCED_OPEN = 1 << 3,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WifiTechnology.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WifiTechnology.aidl
new file mode 100644
index 0000000..00c16b4
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WifiTechnology.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.
+ */
+
+package android.hardware.wifi.supplicant;
+
+/**
+ * Wifi Technologies
+ */
+@VintfStability
+@Backing(type="int")
+enum WifiTechnology {
+    UNKNOWN = 0,
+    /**
+     * For 802.11a/b/g
+     */
+    LEGACY = 1,
+    /**
+     * For 802.11n
+     */
+    HT = 2,
+    /**
+     * For 802.11ac
+     */
+    VHT = 3,
+    /**
+     * For 802.11ax
+     */
+    HE = 4,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl
new file mode 100644
index 0000000..e174199
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.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.
+ */
+
+package android.hardware.wifi.supplicant;
+
+/**
+ * WPA Driver capability.
+ */
+@VintfStability
+@Backing(type="int")
+enum WpaDriverCapabilitiesMask {
+    /**
+     * Multi Band Operation.
+     */
+    MBO = 1 << 0,
+    /**
+     * Optimized Connectivity Experience.
+     */
+    OCE = 1 << 1,
+    /**
+     * WPA3 SAE Public-Key.
+     */
+    SAE_PK = 1 << 2,
+    /**
+     * Wi-Fi Display R2
+     */
+    WFD_R2 = 1 << 3,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WpsConfigError.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WpsConfigError.aidl
new file mode 100644
index 0000000..926946c
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WpsConfigError.aidl
@@ -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.
+ */
+
+package android.hardware.wifi.supplicant;
+
+/**
+ * WPS Configuration Error.
+ */
+@VintfStability
+@Backing(type="int")
+enum WpsConfigError {
+    NO_ERROR = 0,
+    OOB_IFACE_READ_ERROR = 1,
+    DECRYPTION_CRC_FAILURE = 2,
+    CHAN_24_NOT_SUPPORTED = 3,
+    CHAN_50_NOT_SUPPORTED = 4,
+    SIGNAL_TOO_WEAK = 5,
+    NETWORK_AUTH_FAILURE = 6,
+    NETWORK_ASSOC_FAILURE = 7,
+    NO_DHCP_RESPONSE = 8,
+    FAILED_DHCP_CONFIG = 9,
+    IP_ADDR_CONFLICT = 10,
+    NO_CONN_TO_REGISTRAR = 11,
+    MULTIPLE_PBC_DETECTED = 12,
+    ROGUE_SUSPECTED = 13,
+    DEVICE_BUSY = 14,
+    SETUP_LOCKED = 15,
+    MSG_TIMEOUT = 16,
+    REG_SESS_TIMEOUT = 17,
+    DEV_PASSWORD_AUTH_FAILURE = 18,
+    CHAN_60G_NOT_SUPPORTED = 19,
+    PUBLIC_KEY_HASH_MISMATCH = 20,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WpsConfigMethods.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WpsConfigMethods.aidl
new file mode 100644
index 0000000..ec08a45
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WpsConfigMethods.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.
+ */
+
+package android.hardware.wifi.supplicant;
+
+/**
+ * WPS config methods.
+ * Refer to section 3 of IBSS with Wi-Fi Protected Setup
+ * Technical Specification Version 1.0.0.
+ */
+@VintfStability
+@Backing(type="int")
+enum WpsConfigMethods {
+    USBA = 0x0001,
+    ETHERNET = 0x0002,
+    LABEL = 0x0004,
+    DISPLAY = 0x0008,
+    EXT_NFC_TOKEN = 0x0010,
+    INT_NFC_TOKEN = 0x0020,
+    NFC_INTERFACE = 0x0040,
+    PUSHBUTTON = 0x0080,
+    KEYPAD = 0x0100,
+    VIRT_PUSHBUTTON = 0x0280,
+    PHY_PUSHBUTTON = 0x0480,
+    P2PS = 0x1000,
+    VIRT_DISPLAY = 0x2008,
+    PHY_DISPLAY = 0x4008,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WpsDevPasswordId.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WpsDevPasswordId.aidl
new file mode 100644
index 0000000..ca5a533
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WpsDevPasswordId.aidl
@@ -0,0 +1,33 @@
+/*
+ * 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.wifi.supplicant;
+
+/**
+ * WPS Device Password ID
+ */
+@VintfStability
+@Backing(type="int")
+enum WpsDevPasswordId {
+    DEFAULT = 0x0000,
+    USER_SPECIFIED = 0x0001,
+    MACHINE_SPECIFIED = 0x0002,
+    REKEY = 0x0003,
+    PUSHBUTTON = 0x0004,
+    REGISTRAR_SPECIFIED = 0x0005,
+    NFC_CONNECTION_HANDOVER = 0x0007,
+    P2PS_DEFAULT = 0x0008,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WpsErrorIndication.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WpsErrorIndication.aidl
new file mode 100644
index 0000000..4866acc
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WpsErrorIndication.aidl
@@ -0,0 +1,29 @@
+/*
+ * 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.wifi.supplicant;
+
+/**
+ * Vendor specific Error Indication for WPS event messages.
+ */
+@VintfStability
+@Backing(type="int")
+enum WpsErrorIndication {
+    NO_ERROR = 0,
+    SECURITY_TKIP_ONLY_PROHIBITED = 1,
+    SECURITY_WEP_PROHIBITED = 2,
+    AUTH_FAILURE = 3,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WpsProvisionMethod.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WpsProvisionMethod.aidl
new file mode 100644
index 0000000..5b59392
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WpsProvisionMethod.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.wifi.supplicant;
+
+@VintfStability
+@Backing(type="int")
+enum WpsProvisionMethod {
+    /**
+     * Push button method.
+     */
+    PBC,
+    /**
+     * Display pin method configuration - pin is generated and displayed on
+     * device.
+     */
+    DISPLAY,
+    /**
+     * Keypad pin method configuration - pin is entered on device.
+     */
+    KEYPAD,
+}
diff --git a/wifi/supplicant/aidl/vts/functional/Android.bp b/wifi/supplicant/aidl/vts/functional/Android.bp
new file mode 100644
index 0000000..65f9652
--- /dev/null
+++ b/wifi/supplicant/aidl/vts/functional/Android.bp
@@ -0,0 +1,90 @@
+//
+// 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: "VtsHalWifiSupplicantStaIfaceTargetTest",
+    defaults: [
+        "VtsHalTargetTestDefaults",
+        "use_libaidlvintf_gtest_helper_static",
+    ],
+    srcs: ["supplicant_sta_iface_aidl_test.cpp"],
+    shared_libs: [
+        "libbinder",
+        "libbinder_ndk",
+    ],
+    static_libs: [
+        "android.hardware.wifi.supplicant-V1-ndk",
+        "libwifi-system",
+        "libwifi-system-iface",
+    ],
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
+}
+
+cc_test {
+    name: "VtsHalWifiSupplicantStaNetworkTargetTest",
+    defaults: [
+        "VtsHalTargetTestDefaults",
+        "use_libaidlvintf_gtest_helper_static",
+    ],
+    srcs: ["supplicant_sta_network_aidl_test.cpp"],
+    shared_libs: [
+        "libbinder",
+        "libbinder_ndk",
+    ],
+    static_libs: [
+        "android.hardware.wifi.supplicant-V1-ndk",
+        "libwifi-system",
+        "libwifi-system-iface",
+    ],
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
+}
+
+cc_test {
+    name: "VtsHalWifiSupplicantP2pIfaceTargetTest",
+    defaults: [
+        "VtsHalTargetTestDefaults",
+        "use_libaidlvintf_gtest_helper_static",
+    ],
+    srcs: ["supplicant_p2p_iface_aidl_test.cpp"],
+    shared_libs: [
+        "libbinder",
+        "libbinder_ndk",
+    ],
+    static_libs: [
+        "android.hardware.wifi.supplicant-V1-ndk",
+        "libwifi-system",
+        "libwifi-system-iface",
+    ],
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
+}
diff --git a/wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp b/wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp
new file mode 100644
index 0000000..2f4f06d
--- /dev/null
+++ b/wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp
@@ -0,0 +1,633 @@
+/*
+ * 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 <VtsCoreUtil.h>
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/wifi/supplicant/BnSupplicant.h>
+#include <aidl/android/hardware/wifi/supplicant/BnSupplicantP2pIfaceCallback.h>
+#include <android/binder_manager.h>
+#include <android/binder_status.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+#include <cutils/properties.h>
+
+#include "supplicant_test_utils.h"
+
+using aidl::android::hardware::wifi::supplicant::BnSupplicantP2pIfaceCallback;
+using aidl::android::hardware::wifi::supplicant::DebugLevel;
+using aidl::android::hardware::wifi::supplicant::FreqRange;
+using aidl::android::hardware::wifi::supplicant::IfaceType;
+using aidl::android::hardware::wifi::supplicant::ISupplicant;
+using aidl::android::hardware::wifi::supplicant::ISupplicantP2pIface;
+using aidl::android::hardware::wifi::supplicant::MiracastMode;
+using aidl::android::hardware::wifi::supplicant::P2pGroupCapabilityMask;
+using aidl::android::hardware::wifi::supplicant::P2pProvDiscStatusCode;
+using aidl::android::hardware::wifi::supplicant::P2pStatusCode;
+using aidl::android::hardware::wifi::supplicant::WpsConfigMethods;
+using aidl::android::hardware::wifi::supplicant::WpsDevPasswordId;
+using aidl::android::hardware::wifi::supplicant::WpsProvisionMethod;
+using android::ProcessState;
+
+namespace {
+const std::string kTestSsidStr = "TestSsid1234";
+const std::vector<uint8_t> kTestSsid =
+    std::vector<uint8_t>(kTestSsidStr.begin(), kTestSsidStr.end());
+const std::vector<uint8_t> kTestMacAddr = {0x56, 0x67, 0x67, 0xf4, 0x56, 0x92};
+const std::vector<uint8_t> kTestPeerMacAddr = {0x56, 0x67, 0x55,
+                                               0xf4, 0x56, 0x92};
+const std::vector<uint8_t> kTestZeroMacAddr = std::vector<uint8_t>(6, 0);
+const std::string kTestPassphrase = "P2pWorld1234";
+const std::string kTestConnectPin = "34556665";
+const std::string kTestGroupIfName = "TestGroup";
+const uint32_t kTestFindTimeout = 5;
+const uint32_t kTestConnectGoIntent = 6;
+const uint32_t kTestNetworkId = 7;
+const uint32_t kTestGroupFreq = 0;
+const bool kTestGroupPersistent = false;
+const bool kTestGroupIsJoin = false;
+
+}  // namespace
+
+class SupplicantP2pIfaceCallback : public BnSupplicantP2pIfaceCallback {
+   public:
+    SupplicantP2pIfaceCallback() = default;
+
+    ::ndk::ScopedAStatus onDeviceFound(
+        const std::vector<uint8_t>& /* srcAddress */,
+        const std::vector<uint8_t>& /* p2pDeviceAddress */,
+        const std::vector<uint8_t>& /* primaryDeviceType */,
+        const std::string& /* deviceName */,
+        WpsConfigMethods /* configMethods */, int8_t /* deviceCapabilities */,
+        P2pGroupCapabilityMask /* groupCapabilities */,
+        const std::vector<uint8_t>& /* wfdDeviceInfo */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onDeviceLost(
+        const std::vector<uint8_t>& /* p2pDeviceAddress */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onFindStopped() override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onGoNegotiationCompleted(
+        P2pStatusCode /* status */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onGoNegotiationRequest(
+        const std::vector<uint8_t>& /* srcAddress */,
+        WpsDevPasswordId /* passwordId */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onGroupFormationFailure(
+        const std::string& /* failureReason */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onGroupFormationSuccess() override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onGroupRemoved(const std::string& /* groupIfname */,
+                                        bool /* isGroupOwner */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onGroupStarted(
+        const std::string& /* groupIfname */, bool /* isGroupOwner */,
+        const std::vector<uint8_t>& /* ssid */, int32_t /* frequency */,
+        const std::vector<uint8_t>& /* psk */,
+        const std::string& /* passphrase */,
+        const std::vector<uint8_t>& /* goDeviceAddress */,
+        bool /* isPersistent */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onInvitationReceived(
+        const std::vector<uint8_t>& /* srcAddress */,
+        const std::vector<uint8_t>& /* goDeviceAddress */,
+        const std::vector<uint8_t>& /* bssid */,
+        int32_t /* persistentNetworkId */,
+        int32_t /* operatingFrequency */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onInvitationResult(
+        const std::vector<uint8_t>& /* bssid */,
+        P2pStatusCode /* status */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onProvisionDiscoveryCompleted(
+        const std::vector<uint8_t>& /* p2pDeviceAddress */,
+        bool /* isRequest */, P2pProvDiscStatusCode /* status */,
+        WpsConfigMethods /* configMethods */,
+        const std::string& /* generatedPin */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onR2DeviceFound(
+        const std::vector<uint8_t>& /* srcAddress */,
+        const std::vector<uint8_t>& /* p2pDeviceAddress */,
+        const std::vector<uint8_t>& /* primaryDeviceType */,
+        const std::string& /* deviceName */,
+        WpsConfigMethods /* configMethods */, int8_t /* deviceCapabilities */,
+        P2pGroupCapabilityMask /* groupCapabilities */,
+        const std::vector<uint8_t>& /* wfdDeviceInfo */,
+        const std::vector<uint8_t>& /* wfdR2DeviceInfo */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onServiceDiscoveryResponse(
+        const std::vector<uint8_t>& /* srcAddress */,
+        char16_t /* updateIndicator */,
+        const std::vector<uint8_t>& /* tlvs */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onStaAuthorized(
+        const std::vector<uint8_t>& /* srcAddress */,
+        const std::vector<uint8_t>& /* p2pDeviceAddress */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onStaDeauthorized(
+        const std::vector<uint8_t>& /* srcAddress */,
+        const std::vector<uint8_t>& /* p2pDeviceAddress */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+};
+
+class SupplicantP2pIfaceAidlTest : public testing::TestWithParam<std::string> {
+   public:
+    void SetUp() override {
+        initializeService();
+        supplicant_ = ISupplicant::fromBinder(ndk::SpAIBinder(
+            AServiceManager_waitForService(GetParam().c_str())));
+        ASSERT_NE(supplicant_, nullptr);
+        ASSERT_TRUE(supplicant_
+                        ->setDebugParams(DebugLevel::EXCESSIVE,
+                                         true,  // show timestamps
+                                         true)
+                        .isOk());
+
+        bool p2pEnabled =
+            testing::deviceSupportsFeature("android.hardware.wifi.direct");
+        if (!p2pEnabled) {
+            GTEST_SKIP() << "Wi-Fi Direct is not supported, skip this test.";
+        }
+
+        EXPECT_TRUE(supplicant_->addP2pInterface(getP2pIfaceName(), &p2p_iface_)
+                        .isOk());
+        ASSERT_NE(p2p_iface_, nullptr);
+    }
+
+    void TearDown() override {
+        stopSupplicant();
+        startWifiFramework();
+    }
+
+   protected:
+    std::shared_ptr<ISupplicant> supplicant_;
+    std::shared_ptr<ISupplicantP2pIface> p2p_iface_;
+};
+
+/*
+ * RegisterCallback
+ */
+TEST_P(SupplicantP2pIfaceAidlTest, RegisterCallback) {
+    std::shared_ptr<SupplicantP2pIfaceCallback> callback =
+        ndk::SharedRefBase::make<SupplicantP2pIfaceCallback>();
+    ASSERT_NE(callback, nullptr);
+    EXPECT_TRUE(p2p_iface_->registerCallback(callback).isOk());
+}
+
+/*
+ * GetName
+ */
+TEST_P(SupplicantP2pIfaceAidlTest, GetName) {
+    std::string name;
+    EXPECT_TRUE(p2p_iface_->getName(&name).isOk());
+    EXPECT_NE(name.size(), 0);
+}
+
+/*
+ * GetType
+ */
+TEST_P(SupplicantP2pIfaceAidlTest, GetType) {
+    IfaceType type;
+    EXPECT_TRUE(p2p_iface_->getType(&type).isOk());
+    EXPECT_EQ(type, IfaceType::P2P);
+}
+
+/*
+ * GetDeviceAddress
+ */
+TEST_P(SupplicantP2pIfaceAidlTest, GetDeviceAddress) {
+    std::vector<uint8_t> macAddr;
+    EXPECT_TRUE(p2p_iface_->getDeviceAddress(&macAddr).isOk());
+    EXPECT_EQ(macAddr.size(), 6);
+}
+
+/*
+ * GetSsid
+ */
+TEST_P(SupplicantP2pIfaceAidlTest, GetSsid) {
+    // This will fail with fake values.
+    std::vector<uint8_t> ssid;
+    EXPECT_FALSE(p2p_iface_->getSsid(kTestMacAddr, &ssid).isOk());
+}
+
+/*
+ * GetGroupCapability
+ */
+TEST_P(SupplicantP2pIfaceAidlTest, GetGroupCapability) {
+    // This will fail with fake values.
+    P2pGroupCapabilityMask cap;
+    EXPECT_FALSE(p2p_iface_->getGroupCapability(kTestMacAddr, &cap).isOk());
+}
+
+/*
+ * Set/Get Edmg
+ */
+TEST_P(SupplicantP2pIfaceAidlTest, SetGetEdmg) {
+    bool emdg = false;
+    EXPECT_TRUE(p2p_iface_->setEdmg(true).isOk());
+    EXPECT_TRUE(p2p_iface_->getEdmg(&emdg).isOk());
+    EXPECT_EQ(emdg, true);
+
+    EXPECT_TRUE(p2p_iface_->setEdmg(false).isOk());
+    EXPECT_TRUE(p2p_iface_->getEdmg(&emdg).isOk());
+    EXPECT_EQ(emdg, false);
+}
+
+/*
+ * SetWpsDeviceName
+ */
+TEST_P(SupplicantP2pIfaceAidlTest, SetWpsDeviceName) {
+    const std::string deviceName = "TestWpsDeviceName";
+    EXPECT_TRUE(p2p_iface_->setWpsDeviceName(deviceName).isOk());
+}
+
+/*
+ * SetWpsDeviceType
+ */
+TEST_P(SupplicantP2pIfaceAidlTest, SetWpsDeviceType) {
+    const std::vector<uint8_t> deviceType = std::vector<uint8_t>(8, 0x01);
+    EXPECT_TRUE(p2p_iface_->setWpsDeviceType(deviceType).isOk());
+}
+
+/*
+ * SetWpsManufacturer
+ */
+TEST_P(SupplicantP2pIfaceAidlTest, SetWpsManufacturer) {
+    const std::string deviceManufacturer = "TestManufacturer";
+    EXPECT_TRUE(p2p_iface_->setWpsManufacturer(deviceManufacturer).isOk());
+}
+
+/*
+ * SetWpsModelName
+ */
+TEST_P(SupplicantP2pIfaceAidlTest, SetWpsModelName) {
+    const std::string modelName = "TestModelName";
+    EXPECT_TRUE(p2p_iface_->setWpsModelName(modelName).isOk());
+}
+
+/*
+ * SetWpsModelNumber
+ */
+TEST_P(SupplicantP2pIfaceAidlTest, SetWpsModelNumber) {
+    const std::string modelNumber = "TestModelNumber";
+    EXPECT_TRUE(p2p_iface_->setWpsModelName(modelNumber).isOk());
+}
+
+/*
+ * SetWpsSerialNumber
+ */
+TEST_P(SupplicantP2pIfaceAidlTest, SetWpsSerialNumber) {
+    const std::string serialNumber = "TestSerialNumber";
+    EXPECT_TRUE(p2p_iface_->setWpsSerialNumber(serialNumber).isOk());
+}
+
+/*
+ * SetWpsConfigMethods
+ */
+TEST_P(SupplicantP2pIfaceAidlTest, SetWpsConfigMethods) {
+    const WpsConfigMethods config = WpsConfigMethods::DISPLAY;
+    EXPECT_TRUE(p2p_iface_->setWpsConfigMethods(config).isOk());
+}
+
+/*
+ * SetSsidPostfix
+ */
+TEST_P(SupplicantP2pIfaceAidlTest, SetSsidPostfix) {
+    const std::vector<uint8_t> ssidPostfix = {'t', 'e', 's', 't'};
+    EXPECT_TRUE(p2p_iface_->setSsidPostfix(ssidPostfix).isOk());
+}
+
+/*
+ * SetWfdDeviceInfo
+ */
+TEST_P(SupplicantP2pIfaceAidlTest, SetWfdDeviceInfo) {
+    const std::vector<uint8_t> wfdDeviceInfo = std::vector<uint8_t>(6, 0x01);
+    EXPECT_TRUE(p2p_iface_->setWfdDeviceInfo(wfdDeviceInfo).isOk());
+}
+
+/*
+ * SetWfdR2DeviceInfo
+ */
+TEST_P(SupplicantP2pIfaceAidlTest, SetWfdR2DeviceInfo) {
+    const std::vector<uint8_t> wfdR2DeviceInfo = std::vector<uint8_t>(4, 0x01);
+    EXPECT_TRUE(p2p_iface_->setWfdR2DeviceInfo(wfdR2DeviceInfo).isOk());
+}
+
+/*
+ * SetGroupIdle
+ */
+TEST_P(SupplicantP2pIfaceAidlTest, SetGroupIdle) {
+    // This will fail with fake values.
+    const uint32_t groupIdleTimeout = 8;
+    EXPECT_FALSE(
+        p2p_iface_->setGroupIdle(kTestGroupIfName, groupIdleTimeout).isOk());
+}
+
+/*
+ * SetPowerSave
+ */
+TEST_P(SupplicantP2pIfaceAidlTest, SetPowerSave) {
+    // This will fail with fake values.
+    EXPECT_FALSE(p2p_iface_->setPowerSave(kTestGroupIfName, true).isOk());
+    EXPECT_FALSE(p2p_iface_->setPowerSave(kTestGroupIfName, false).isOk());
+}
+
+/*
+ * SetMiracastMode
+ */
+TEST_P(SupplicantP2pIfaceAidlTest, SetMiracastMode) {
+    EXPECT_TRUE(p2p_iface_->setMiracastMode(MiracastMode::DISABLED).isOk());
+    EXPECT_TRUE(p2p_iface_->setMiracastMode(MiracastMode::SOURCE).isOk());
+    EXPECT_TRUE(p2p_iface_->setMiracastMode(MiracastMode::SINK).isOk());
+}
+
+/*
+ * SetDisallowedFrequencies
+ */
+TEST_P(SupplicantP2pIfaceAidlTest, SetDisallowedFrequencies) {
+    FreqRange range1;
+    range1.min = 2412;
+    range1.max = 2432;
+    const std::vector<FreqRange> ranges = {range1};
+    EXPECT_TRUE(p2p_iface_->setDisallowedFrequencies(ranges).isOk());
+}
+
+/*
+ * SetListenChannel
+ */
+TEST_P(SupplicantP2pIfaceAidlTest, SetListenChannel) {
+    const uint32_t testChannel = 1;
+    const uint32_t testOperatingClass = 81;
+    EXPECT_TRUE(
+        p2p_iface_->setListenChannel(testChannel, testOperatingClass).isOk());
+}
+
+/*
+ * SetMacRandomization
+ */
+TEST_P(SupplicantP2pIfaceAidlTest, EnableMacRandomization) {
+    // Enable twice
+    EXPECT_TRUE(p2p_iface_->setMacRandomization(true).isOk());
+    EXPECT_TRUE(p2p_iface_->setMacRandomization(true).isOk());
+
+    // Disable twice
+    EXPECT_TRUE(p2p_iface_->setMacRandomization(false).isOk());
+    EXPECT_TRUE(p2p_iface_->setMacRandomization(false).isOk());
+}
+
+/*
+ * AddGroup
+ */
+TEST_P(SupplicantP2pIfaceAidlTest, AddGroup) {
+    EXPECT_TRUE(p2p_iface_->addGroup(false, kTestNetworkId).isOk());
+}
+
+/*
+ * RemoveGroup
+ */
+TEST_P(SupplicantP2pIfaceAidlTest, RemoveGroup) {
+    // This will fail with fake values.
+    EXPECT_FALSE(p2p_iface_->removeGroup(kTestGroupIfName).isOk());
+}
+
+/*
+ * AddGroupWithConfig - success.
+ */
+TEST_P(SupplicantP2pIfaceAidlTest, AddGroupWithConfig_Success) {
+    EXPECT_TRUE(p2p_iface_
+                    ->addGroupWithConfig(kTestSsid, kTestPassphrase,
+                                         kTestGroupPersistent, kTestGroupFreq,
+                                         kTestZeroMacAddr, kTestGroupIsJoin)
+                    .isOk());
+}
+
+/*
+ * AddGroupWithConfig - failure due to invalid SSID.
+ */
+TEST_P(SupplicantP2pIfaceAidlTest, AddGroupWithConfig_FailureInvalidSsid) {
+    const std::vector<uint8_t> ssid;
+    EXPECT_FALSE(p2p_iface_
+                     ->addGroupWithConfig(ssid, kTestPassphrase,
+                                          kTestGroupPersistent, kTestGroupFreq,
+                                          kTestZeroMacAddr, kTestGroupIsJoin)
+                     .isOk());
+}
+
+/*
+ * AddGroupWithConfig - failure due to invalid passphrase.
+ */
+TEST_P(SupplicantP2pIfaceAidlTest,
+       AddGroupWithConfig_FailureInvalidPassphrase) {
+    const std::string passphrase = "1234";
+    EXPECT_FALSE(p2p_iface_
+                     ->addGroupWithConfig(kTestSsid, passphrase,
+                                          kTestGroupPersistent, kTestGroupFreq,
+                                          kTestZeroMacAddr, kTestGroupIsJoin)
+                     .isOk());
+}
+
+/*
+ * AddGroupWithConfig - failure due to invalid frequency.
+ */
+TEST_P(SupplicantP2pIfaceAidlTest, AddGroupWithConfig_FailureInvalidFrequency) {
+    const int freq = 9999;
+    EXPECT_FALSE(p2p_iface_
+                     ->addGroupWithConfig(kTestSsid, kTestPassphrase,
+                                          kTestGroupPersistent, freq,
+                                          kTestZeroMacAddr, kTestGroupIsJoin)
+                     .isOk());
+}
+
+/*
+ * Find
+ */
+TEST_P(SupplicantP2pIfaceAidlTest, Find) {
+    EXPECT_TRUE(p2p_iface_->find(kTestFindTimeout).isOk());
+}
+
+/*
+ * StopFind
+ */
+TEST_P(SupplicantP2pIfaceAidlTest, StopFind) {
+    EXPECT_TRUE(p2p_iface_->find(kTestFindTimeout).isOk());
+    EXPECT_TRUE(p2p_iface_->stopFind().isOk());
+}
+
+/*
+ * Flush
+ */
+TEST_P(SupplicantP2pIfaceAidlTest, Flush) {
+    EXPECT_TRUE(p2p_iface_->flush().isOk());
+}
+
+/*
+ * Connect
+ */
+TEST_P(SupplicantP2pIfaceAidlTest, Connect) {
+    /*
+     * Auto-join is not enabled before R. After enabling auto-join,
+     * this should always succeed.
+     */
+    std::string pin;
+    EXPECT_TRUE(p2p_iface_
+                    ->connect(kTestMacAddr, WpsProvisionMethod::PBC,
+                              kTestConnectPin, false, false,
+                              kTestConnectGoIntent, &pin)
+                    .isOk());
+}
+
+/*
+ * CancelConnect
+ */
+TEST_P(SupplicantP2pIfaceAidlTest, CancelConnect) {
+    std::string pin;
+    EXPECT_TRUE(p2p_iface_
+                    ->connect(kTestMacAddr, WpsProvisionMethod::PBC,
+                              kTestConnectPin, false, false,
+                              kTestConnectGoIntent, &pin)
+                    .isOk());
+    EXPECT_TRUE(p2p_iface_->cancelConnect().isOk());
+}
+
+/*
+ * ProvisionDiscovery
+ */
+TEST_P(SupplicantP2pIfaceAidlTest, ProvisionDiscovery) {
+    // This will fail with fake values.
+    EXPECT_FALSE(
+        p2p_iface_->provisionDiscovery(kTestMacAddr, WpsProvisionMethod::PBC)
+            .isOk());
+}
+
+/*
+ * Reject
+ */
+TEST_P(SupplicantP2pIfaceAidlTest, Reject) {
+    // This will fail with fake values.
+    ASSERT_FALSE(p2p_iface_->reject(kTestMacAddr).isOk());
+}
+
+/*
+ * Invite
+ */
+TEST_P(SupplicantP2pIfaceAidlTest, Invite) {
+    // This will fail with fake values.
+    EXPECT_FALSE(
+        p2p_iface_->invite(kTestGroupIfName, kTestMacAddr, kTestPeerMacAddr)
+            .isOk());
+}
+
+/*
+ * Reinvoke
+ */
+TEST_P(SupplicantP2pIfaceAidlTest, Reinvoke) {
+    // This will fail with fake values.
+    EXPECT_FALSE(p2p_iface_->reinvoke(kTestNetworkId, kTestMacAddr).isOk());
+}
+
+/*
+ * ConfigureExtListen
+ */
+TEST_P(SupplicantP2pIfaceAidlTest, ConfigureExtListen) {
+    const uint32_t extListenPeriod = 400;
+    const uint32_t extListenInterval = 400;
+    EXPECT_TRUE(
+        p2p_iface_->configureExtListen(extListenPeriod, extListenInterval)
+            .isOk());
+}
+
+/*
+ * FlushServices
+ */
+TEST_P(SupplicantP2pIfaceAidlTest, FlushServices) {
+    EXPECT_TRUE(p2p_iface_->flushServices().isOk());
+}
+
+/*
+ * EnableWfd
+ */
+TEST_P(SupplicantP2pIfaceAidlTest, EnableWfd) {
+    EXPECT_TRUE(p2p_iface_->enableWfd(true).isOk());
+    EXPECT_TRUE(p2p_iface_->enableWfd(false).isOk());
+}
+
+/*
+ * Add/Remove BonjourService
+ */
+TEST_P(SupplicantP2pIfaceAidlTest, AddAndRemoveBonjourService) {
+    const std::string serviceQueryStr = "testquery";
+    const std::string serviceResponseStr = "testresponse";
+    const std::vector<uint8_t> bonjourServiceQuery =
+        std::vector<uint8_t>(serviceQueryStr.begin(), serviceQueryStr.end());
+    const std::vector<uint8_t> bonjourServiceResponse = std::vector<uint8_t>(
+        serviceResponseStr.begin(), serviceResponseStr.end());
+
+    EXPECT_TRUE(
+        p2p_iface_
+            ->addBonjourService(bonjourServiceQuery, bonjourServiceResponse)
+            .isOk());
+    EXPECT_TRUE(p2p_iface_->removeBonjourService(bonjourServiceQuery).isOk());
+
+    // This will fail because the boujour service with
+    // bonjourServiceQuery was already removed.
+    EXPECT_FALSE(p2p_iface_->removeBonjourService(bonjourServiceQuery).isOk());
+}
+
+/*
+ * Add/Remove UpnpService
+ */
+TEST_P(SupplicantP2pIfaceAidlTest, AddAndRemoveUpnpService) {
+    const std::string upnpServiceName = "TestServiceName";
+    EXPECT_TRUE(
+        p2p_iface_->addUpnpService(0 /* version */, upnpServiceName).isOk());
+    EXPECT_TRUE(
+        p2p_iface_->removeUpnpService(0 /* version */, upnpServiceName).isOk());
+
+    // This will fail because Upnp service with
+    // upnpServiceName was already removed.
+    EXPECT_FALSE(
+        p2p_iface_->removeUpnpService(0 /* version */, upnpServiceName).isOk());
+}
+
+INSTANTIATE_TEST_SUITE_P(Supplicant, SupplicantP2pIfaceAidlTest,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(
+                             ISupplicant::descriptor)),
+                         android::PrintInstanceNameToString);
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    ProcessState::self()->setThreadPoolMaxThreadCount(1);
+    ProcessState::self()->startThreadPool();
+    return RUN_ALL_TESTS();
+}
diff --git a/wifi/supplicant/aidl/vts/functional/supplicant_sta_iface_aidl_test.cpp b/wifi/supplicant/aidl/vts/functional/supplicant_sta_iface_aidl_test.cpp
new file mode 100644
index 0000000..f51c07f
--- /dev/null
+++ b/wifi/supplicant/aidl/vts/functional/supplicant_sta_iface_aidl_test.cpp
@@ -0,0 +1,782 @@
+/*
+ * 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 <VtsCoreUtil.h>
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/wifi/supplicant/BnSupplicant.h>
+#include <aidl/android/hardware/wifi/supplicant/BnSupplicantStaIfaceCallback.h>
+#include <android/binder_manager.h>
+#include <android/binder_status.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+#include <cutils/properties.h>
+
+#include "supplicant_test_utils.h"
+
+using aidl::android::hardware::wifi::supplicant::AnqpInfoId;
+using aidl::android::hardware::wifi::supplicant::BnSupplicantStaIfaceCallback;
+using aidl::android::hardware::wifi::supplicant::BtCoexistenceMode;
+using aidl::android::hardware::wifi::supplicant::ConnectionCapabilities;
+using aidl::android::hardware::wifi::supplicant::DebugLevel;
+using aidl::android::hardware::wifi::supplicant::DppAkm;
+using aidl::android::hardware::wifi::supplicant::DppCurve;
+using aidl::android::hardware::wifi::supplicant::DppNetRole;
+using aidl::android::hardware::wifi::supplicant::DppResponderBootstrapInfo;
+using aidl::android::hardware::wifi::supplicant::Hs20AnqpSubtypes;
+using aidl::android::hardware::wifi::supplicant::IfaceType;
+using aidl::android::hardware::wifi::supplicant::ISupplicant;
+using aidl::android::hardware::wifi::supplicant::ISupplicantStaIface;
+using aidl::android::hardware::wifi::supplicant::ISupplicantStaNetwork;
+using aidl::android::hardware::wifi::supplicant::KeyMgmtMask;
+using aidl::android::hardware::wifi::supplicant::RxFilterType;
+using aidl::android::hardware::wifi::supplicant::WpaDriverCapabilitiesMask;
+using aidl::android::hardware::wifi::supplicant::WpsConfigMethods;
+using android::ProcessState;
+
+static constexpr int TIMEOUT_PERIOD = 60;
+class IfaceDppCallback;
+
+namespace {
+const std::vector<uint8_t> kTestMacAddr = {0x56, 0x67, 0x67, 0xf4, 0x56, 0x92};
+const std::string kTestUri =
+    "DPP:C:81/1,117/"
+    "40;M:48d6d5bd1de1;I:G1197843;K:MDkwEwYHKoZIzj0CAQYIKoZIzj"
+    "0DAQcDIgAD0edY4X3N//HhMFYsZfMbQJTiNFtNIWF/cIwMB/gzqOM=;;";
+}  // namespace
+
+class SupplicantStaIfaceCallback : public BnSupplicantStaIfaceCallback {
+   public:
+    SupplicantStaIfaceCallback() = default;
+
+    ::ndk::ScopedAStatus onAnqpQueryDone(
+        const std::vector<uint8_t>& /* bssid */,
+        const ::aidl::android::hardware::wifi::supplicant::AnqpData& /* data */,
+        const ::aidl::android::hardware::wifi::supplicant::
+            Hs20AnqpData& /* hs20Data */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onAssociationRejected(
+        const ::aidl::android::hardware::wifi::supplicant::
+            AssociationRejectionData& /* assocRejectData */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onAuthenticationTimeout(
+        const std::vector<uint8_t>& /* bssid */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onBssTmHandlingDone(
+        const ::aidl::android::hardware::wifi::supplicant::
+            BssTmData& /* tmData */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onBssidChanged(
+        ::aidl::android::hardware::wifi::supplicant::
+            BssidChangeReason /* reason */,
+        const std::vector<uint8_t>& /* bssid */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onDisconnected(
+        const std::vector<uint8_t>& /* bssid */, bool /* locallyGenerated */,
+        ::aidl::android::hardware::wifi::supplicant::
+            StaIfaceReasonCode /* reasonCode */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onDppFailure(
+        ::aidl::android::hardware::wifi::supplicant::DppFailureCode /* code */,
+        const std::string& /* ssid */, const std::string& /* channelList */,
+        const std::vector<char16_t>& /* bandList */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onDppProgress(
+        ::aidl::android::hardware::wifi::supplicant::DppProgressCode /* code */)
+        override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onDppSuccess(
+        ::aidl::android::hardware::wifi::supplicant::DppEventType /* type */)
+        override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onDppSuccessConfigReceived(
+        const std::vector<uint8_t>& /* ssid */,
+        const std::string& /* password */,
+        const std::vector<uint8_t>& /* psk */,
+        ::aidl::android::hardware::wifi::supplicant::DppAkm /* securityAkm */)
+        override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onDppSuccessConfigSent() override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onEapFailure(int32_t /* errorCode */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onExtRadioWorkStart(int32_t /* id */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onExtRadioWorkTimeout(int32_t /* id */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onHs20DeauthImminentNotice(
+        const std::vector<uint8_t>& /* bssid */, int32_t /* reasonCode */,
+        int32_t /* reAuthDelayInSec */, const std::string& /* url */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onHs20IconQueryDone(
+        const std::vector<uint8_t>& /* bssid */,
+        const std::string& /* fileName */,
+        const std::vector<uint8_t>& /* data */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onHs20SubscriptionRemediation(
+        const std::vector<uint8_t>& /* bssid */,
+        ::aidl::android::hardware::wifi::supplicant::OsuMethod /* osuMethod */,
+        const std::string& /* url */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus
+    onHs20TermsAndConditionsAcceptanceRequestedNotification(
+        const std::vector<uint8_t>& /* bssid */,
+        const std::string& /* url */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onNetworkAdded(int32_t /* id */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onNetworkNotFound(
+        const std::vector<uint8_t>& /* ssid */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onNetworkRemoved(int32_t /* id */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onPmkCacheAdded(
+        int64_t /* expirationTimeInSec */,
+        const std::vector<uint8_t>& /* serializedEntry */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onStateChanged(
+        ::aidl::android::hardware::wifi::supplicant::
+            StaIfaceCallbackState /* newState */,
+        const std::vector<uint8_t>& /* bssid */, int32_t /* id */,
+        const std::vector<uint8_t>& /* ssid */,
+        bool /* filsHlpSent */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onWpsEventFail(
+        const std::vector<uint8_t>& /* bssid */,
+        ::aidl::android::hardware::wifi::supplicant::
+            WpsConfigError /* configError */,
+        ::aidl::android::hardware::wifi::supplicant::
+            WpsErrorIndication /* errorInd */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onWpsEventPbcOverlap() override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onWpsEventSuccess() override {
+        return ndk::ScopedAStatus::ok();
+    }
+};
+
+class SupplicantStaIfaceAidlTest : public testing::TestWithParam<std::string> {
+   public:
+    void SetUp() override {
+        initializeService();
+        supplicant_ = ISupplicant::fromBinder(ndk::SpAIBinder(
+            AServiceManager_waitForService(GetParam().c_str())));
+        ASSERT_NE(supplicant_, nullptr);
+        ASSERT_TRUE(supplicant_
+                        ->setDebugParams(DebugLevel::EXCESSIVE,
+                                         true,  // show timestamps
+                                         true)
+                        .isOk());
+        EXPECT_TRUE(supplicant_->addStaInterface(getStaIfaceName(), &sta_iface_)
+                        .isOk());
+        ASSERT_NE(sta_iface_, nullptr);
+    }
+
+    void TearDown() override {
+        stopSupplicant();
+        startWifiFramework();
+    }
+
+    enum DppCallbackType {
+        ANY_CALLBACK = -2,
+        INVALID = -1,
+        EVENT_SUCCESS = 0,
+        EVENT_PROGRESS,
+        EVENT_FAILURE,
+    };
+
+    DppCallbackType dppCallbackType;
+    uint32_t code;
+
+    // Used as a mechanism to inform the test about data/event callback
+    inline void notify() {
+        std::unique_lock<std::mutex> lock(mtx_);
+        cv_.notify_one();
+    }
+
+    // Test code calls this function to wait for data/event callback
+    inline std::cv_status wait(DppCallbackType waitForCallbackType) {
+        std::unique_lock<std::mutex> lock(mtx_);
+        EXPECT_NE(INVALID, waitForCallbackType);  // can't ASSERT in a
+                                                  // non-void-returning method
+        auto now = std::chrono::system_clock::now();
+        std::cv_status status =
+            cv_.wait_until(lock, now + std::chrono::seconds(TIMEOUT_PERIOD));
+        return status;
+    }
+
+   protected:
+    std::shared_ptr<ISupplicant> supplicant_;
+    std::shared_ptr<ISupplicantStaIface> sta_iface_;
+
+   private:
+    // synchronization objects
+    std::mutex mtx_;
+    std::condition_variable cv_;
+};
+
+/*
+ * RegisterCallback
+ */
+TEST_P(SupplicantStaIfaceAidlTest, RegisterCallback) {
+    std::shared_ptr<SupplicantStaIfaceCallback> callback =
+        ndk::SharedRefBase::make<SupplicantStaIfaceCallback>();
+    ASSERT_NE(callback, nullptr);
+    EXPECT_TRUE(sta_iface_->registerCallback(callback).isOk());
+}
+
+/*
+ * GetConnectionCapabilities
+ */
+TEST_P(SupplicantStaIfaceAidlTest, GetConnectionCapabilities) {
+    ConnectionCapabilities cap;
+    EXPECT_TRUE(sta_iface_->getConnectionCapabilities(&cap).isOk());
+}
+
+/*
+ * GetWpaDriverCapabilities
+ */
+TEST_P(SupplicantStaIfaceAidlTest, GetWpaDriverCapabilities) {
+    WpaDriverCapabilitiesMask cap;
+    EXPECT_TRUE(sta_iface_->getWpaDriverCapabilities(&cap).isOk());
+}
+
+/*
+ * GetKeyMgmtCapabilities
+ */
+TEST_P(SupplicantStaIfaceAidlTest, GetKeyMgmtCapabilities) {
+    KeyMgmtMask cap;
+    EXPECT_TRUE(sta_iface_->getKeyMgmtCapabilities(&cap).isOk());
+
+    // Even though capabilities vary, these two are always set.
+    EXPECT_TRUE(!!(static_cast<uint32_t>(cap) &
+                   static_cast<uint32_t>(KeyMgmtMask::NONE)));
+    EXPECT_TRUE(!!(static_cast<uint32_t>(cap) &
+                   static_cast<uint32_t>(KeyMgmtMask::IEEE8021X)));
+}
+
+/*
+ * GetName
+ */
+TEST_P(SupplicantStaIfaceAidlTest, GetName) {
+    std::string name;
+    EXPECT_TRUE(sta_iface_->getName(&name).isOk());
+    EXPECT_NE(name.size(), 0);
+}
+
+/*
+ * GetType
+ */
+TEST_P(SupplicantStaIfaceAidlTest, GetType) {
+    IfaceType type;
+    EXPECT_TRUE(sta_iface_->getType(&type).isOk());
+    EXPECT_EQ(type, IfaceType::STA);
+}
+
+/*
+ * GetMacAddress
+ */
+TEST_P(SupplicantStaIfaceAidlTest, GetMacAddress) {
+    std::vector<uint8_t> macAddr;
+    EXPECT_TRUE(sta_iface_->getMacAddress(&macAddr).isOk());
+    EXPECT_EQ(macAddr.size(), 6);
+}
+
+/*
+ * ListNetworks
+ */
+TEST_P(SupplicantStaIfaceAidlTest, ListNetworks) {
+    std::vector<int32_t> networks;
+    EXPECT_TRUE(sta_iface_->listNetworks(&networks).isOk());
+}
+
+/*
+ * SetBtCoexistenceMode
+ */
+TEST_P(SupplicantStaIfaceAidlTest, SetBtCoexistenceMode) {
+    EXPECT_TRUE(
+        sta_iface_->setBtCoexistenceMode(BtCoexistenceMode::ENABLED).isOk());
+    EXPECT_TRUE(
+        sta_iface_->setBtCoexistenceMode(BtCoexistenceMode::DISABLED).isOk());
+    EXPECT_TRUE(
+        sta_iface_->setBtCoexistenceMode(BtCoexistenceMode::SENSE).isOk());
+}
+
+/*
+ * SetBtCoexistenceScanModeEnabled
+ */
+TEST_P(SupplicantStaIfaceAidlTest, SetBtCoexistenceScanModeEnabled) {
+    EXPECT_TRUE(sta_iface_->setBtCoexistenceScanModeEnabled(true).isOk());
+    EXPECT_TRUE(sta_iface_->setBtCoexistenceScanModeEnabled(false).isOk());
+}
+
+/*
+ * SetSuspendModeEnabled
+ */
+TEST_P(SupplicantStaIfaceAidlTest, SetSuspendModeEnabled) {
+    EXPECT_TRUE(sta_iface_->setSuspendModeEnabled(true).isOk());
+    EXPECT_TRUE(sta_iface_->setSuspendModeEnabled(false).isOk());
+}
+
+/*
+ * SetCountryCode
+ */
+TEST_P(SupplicantStaIfaceAidlTest, SetCountryCode) {
+    const std::vector<uint8_t> countryCode = {'M', 'X'};
+    EXPECT_TRUE(sta_iface_->setCountryCode(countryCode).isOk());
+}
+
+/*
+ * SetWpsDeviceName
+ */
+TEST_P(SupplicantStaIfaceAidlTest, SetWpsDeviceName) {
+    const std::string deviceName = "TestWpsDeviceName";
+    EXPECT_TRUE(sta_iface_->setWpsDeviceName(deviceName).isOk());
+}
+
+/*
+ * SetWpsDeviceType
+ */
+TEST_P(SupplicantStaIfaceAidlTest, SetWpsDeviceType) {
+    const std::vector<uint8_t> deviceType = {8, 0x1};
+    EXPECT_TRUE(sta_iface_->setWpsDeviceType(deviceType).isOk());
+}
+
+/*
+ * SetWpsManufacturer
+ */
+TEST_P(SupplicantStaIfaceAidlTest, SetWpsManufacturer) {
+    const std::string wpsManufacturer = "TestManufacturer";
+    EXPECT_TRUE(sta_iface_->setWpsManufacturer(wpsManufacturer).isOk());
+}
+
+/*
+ * SetWpsModelName
+ */
+TEST_P(SupplicantStaIfaceAidlTest, SetWpsModelName) {
+    const std::string modelName = "TestModelName";
+    EXPECT_TRUE(sta_iface_->setWpsModelName(modelName).isOk());
+}
+
+/*
+ * SetWpsModelNumber
+ */
+TEST_P(SupplicantStaIfaceAidlTest, SetWpsModelNumber) {
+    const std::string modelNumber = "TestModelNumber";
+    EXPECT_TRUE(sta_iface_->setWpsModelNumber(modelNumber).isOk());
+}
+
+/*
+ * SetWpsSerialNumber
+ */
+TEST_P(SupplicantStaIfaceAidlTest, SetWpsSerialNumber) {
+    const std::string serialNumber = "TestSerialNumber";
+    EXPECT_TRUE(sta_iface_->setWpsSerialNumber(serialNumber).isOk());
+}
+
+/*
+ * SetWpsConfigMethods
+ */
+TEST_P(SupplicantStaIfaceAidlTest, SetWpsConfigMethods) {
+    const WpsConfigMethods configMethods = WpsConfigMethods::KEYPAD;
+    EXPECT_TRUE(sta_iface_->setWpsConfigMethods(configMethods).isOk());
+}
+
+/*
+ * SetExternalSim
+ */
+TEST_P(SupplicantStaIfaceAidlTest, SetExternalSim) {
+    EXPECT_TRUE(sta_iface_->setExternalSim(true).isOk());
+    EXPECT_TRUE(sta_iface_->setExternalSim(false).isOk());
+}
+
+/*
+ * SetMboCellularDataStatus
+ */
+TEST_P(SupplicantStaIfaceAidlTest, SetMboCellularDataStatus) {
+    WpaDriverCapabilitiesMask cap;
+    EXPECT_TRUE(sta_iface_->getWpaDriverCapabilities(&cap).isOk());
+
+    // Operation should succeed if MBO is supported, or fail if it's not.
+    bool mboSupported =
+        !!(static_cast<uint32_t>(cap) &
+           static_cast<uint32_t>(WpaDriverCapabilitiesMask::MBO));
+    EXPECT_EQ(mboSupported, sta_iface_->setMboCellularDataStatus(true).isOk());
+}
+
+/*
+ * InitiateTdlsDiscover
+ */
+TEST_P(SupplicantStaIfaceAidlTest, InitiateTdlsDiscover) {
+    EXPECT_TRUE(sta_iface_->initiateTdlsDiscover(kTestMacAddr).isOk());
+}
+
+/*
+ * InitiateTdlsSetup
+ */
+TEST_P(SupplicantStaIfaceAidlTest, InitiateTdlsSetup) {
+    EXPECT_TRUE(sta_iface_->initiateTdlsSetup(kTestMacAddr).isOk());
+}
+
+/*
+ * InitiateTdlsTeardown
+ */
+TEST_P(SupplicantStaIfaceAidlTest, InitiateTdlsTeardown) {
+    EXPECT_TRUE(sta_iface_->initiateTdlsTeardown(kTestMacAddr).isOk());
+}
+
+/*
+ * InitiateAnqpQuery
+ */
+TEST_P(SupplicantStaIfaceAidlTest, InitiateAnqpQuery) {
+    const std::vector<AnqpInfoId> anqpIds = {
+        AnqpInfoId::VENUE_NAME, AnqpInfoId::NAI_REALM, AnqpInfoId::DOMAIN_NAME};
+    const std::vector<Hs20AnqpSubtypes> hsTypes = {
+        Hs20AnqpSubtypes::WAN_METRICS,
+        Hs20AnqpSubtypes::OPERATOR_FRIENDLY_NAME};
+
+    // Request should fail since the BSSID mentioned
+    // is not present in the scan results
+    EXPECT_FALSE(
+        sta_iface_->initiateAnqpQuery(kTestMacAddr, anqpIds, hsTypes).isOk());
+}
+
+/*
+ * InitiateHs20IconQuery
+ */
+TEST_P(SupplicantStaIfaceAidlTest, InitiateHs20IconQuery) {
+    // Request should fail since the BSSID mentioned
+    // is not present in the scan results
+    const std::string hs20IconFile = "TestFile";
+    EXPECT_FALSE(
+        sta_iface_->initiateHs20IconQuery(kTestMacAddr, hs20IconFile).isOk());
+}
+
+/*
+ * InitiateVenueUrlAnqpQuery.
+ */
+TEST_P(SupplicantStaIfaceAidlTest, InitiateVenueUrlAnqpQuery) {
+    // Request should fail since the BSSID mentioned
+    // is not present in the scan results
+    EXPECT_FALSE(sta_iface_->initiateVenueUrlAnqpQuery(kTestMacAddr).isOk());
+}
+
+/*
+ * Reassociate
+ */
+TEST_P(SupplicantStaIfaceAidlTest, Reassociate) {
+    EXPECT_TRUE(sta_iface_->reassociate().isOk());
+}
+
+/*
+ * Reconnect
+ */
+TEST_P(SupplicantStaIfaceAidlTest, Reconnect) {
+    EXPECT_FALSE(sta_iface_->reconnect().isOk());
+}
+
+/*
+ * Disconnect
+ */
+TEST_P(SupplicantStaIfaceAidlTest, Disconnect) {
+    EXPECT_TRUE(sta_iface_->disconnect().isOk());
+}
+
+/*
+ * SetPowerSave
+ */
+TEST_P(SupplicantStaIfaceAidlTest, SetPowerSave) {
+    EXPECT_TRUE(sta_iface_->setPowerSave(true).isOk());
+    EXPECT_TRUE(sta_iface_->setPowerSave(false).isOk());
+}
+
+/*
+ * StartRxFilter
+ */
+TEST_P(SupplicantStaIfaceAidlTest, StartRxFilter) {
+    EXPECT_TRUE(sta_iface_->startRxFilter().isOk());
+}
+
+/*
+ * StopRxFilter
+ */
+TEST_P(SupplicantStaIfaceAidlTest, StopRxFilter) {
+    EXPECT_TRUE(sta_iface_->stopRxFilter().isOk());
+}
+
+/*
+ * AddRxFilter
+ */
+TEST_P(SupplicantStaIfaceAidlTest, AddRxFilter) {
+    EXPECT_TRUE(sta_iface_->addRxFilter(RxFilterType::V4_MULTICAST).isOk());
+    EXPECT_TRUE(sta_iface_->addRxFilter(RxFilterType::V6_MULTICAST).isOk());
+}
+
+/*
+ * RemoveRxFilter
+ */
+TEST_P(SupplicantStaIfaceAidlTest, RemoveRxFilter) {
+    EXPECT_TRUE(sta_iface_->removeRxFilter(RxFilterType::V4_MULTICAST).isOk());
+    EXPECT_TRUE(sta_iface_->removeRxFilter(RxFilterType::V6_MULTICAST).isOk());
+}
+
+/*
+ * AddExtRadioWork
+ */
+TEST_P(SupplicantStaIfaceAidlTest, AddExtRadioWork) {
+    const std::string radioWorkName = "TestRadioWork";
+    const int32_t radioWorkFreq = 2412;
+    const int32_t radioWorkTimeout = 8;
+    int32_t radioWorkId;
+    EXPECT_TRUE(sta_iface_
+                    ->addExtRadioWork(radioWorkName, radioWorkFreq,
+                                      radioWorkTimeout, &radioWorkId)
+                    .isOk());
+    // removeExtRadio only succeeds if the added radio work hasn't started yet,
+    // so there is no guaranteed result from calling removeExtRadioWork here.
+    // Given that, we can't currently test removeExtRadioWork following
+    // a call to addExtRadioWork.
+}
+
+/*
+ * RemoveExtRadioWork
+ */
+TEST_P(SupplicantStaIfaceAidlTest, RemoveExtRadioWork) {
+    // This fails because there is no ongoing radio work with radioWorkId
+    const int32_t radioWorkId = 16;
+    EXPECT_FALSE(sta_iface_->removeExtRadioWork(radioWorkId).isOk());
+}
+
+/*
+ * Add/Remove DppPeerUri
+ */
+TEST_P(SupplicantStaIfaceAidlTest, AddRemoveDppPeerUri) {
+    if (!keyMgmtSupported(sta_iface_, KeyMgmtMask::DPP)) {
+        GTEST_SKIP() << "Missing DPP support";
+    }
+    // Add a peer URI and then remove it.
+    int32_t peerId;
+    EXPECT_TRUE(sta_iface_->addDppPeerUri(kTestUri, &peerId).isOk());
+    EXPECT_TRUE(sta_iface_->removeDppUri(peerId).isOk());
+}
+
+/*
+ * FilsHlpAddRequest
+ */
+TEST_P(SupplicantStaIfaceAidlTest, FilsHlpAddRequest) {
+    if (!isFilsSupported(sta_iface_)) {
+        GTEST_SKIP()
+            << "Skipping test since driver/supplicant doesn't support FILS";
+    }
+    const std::vector<uint8_t> destMacAddr = {0x00, 0x11, 0x22,
+                                              0x33, 0x44, 0x55};
+    const std::vector<uint8_t> pktBuffer = std::vector<uint8_t>(300, 0x3a);
+    EXPECT_TRUE(sta_iface_->filsHlpAddRequest(destMacAddr, pktBuffer).isOk());
+}
+
+/*
+ * FilsHlpFlushRequest
+ */
+TEST_P(SupplicantStaIfaceAidlTest, FilsHlpFlushRequest) {
+    if (!isFilsSupported(sta_iface_)) {
+        GTEST_SKIP()
+            << "Skipping test since driver/supplicant doesn't support FILS";
+    }
+    EXPECT_TRUE(sta_iface_->filsHlpFlushRequest().isOk());
+}
+
+/*
+ * StartDppEnrolleeResponder
+ */
+TEST_P(SupplicantStaIfaceAidlTest, StartDppEnrolleeResponder) {
+    if (!keyMgmtSupported(sta_iface_, KeyMgmtMask::DPP)) {
+        GTEST_SKIP() << "Missing DPP support";
+    }
+
+    const std::string deviceInfo = "DPP_Responder_Mode_VTS_Test";
+    const std::vector<uint8_t> mac_address = {0x22, 0x33, 0x44,
+                                              0x55, 0x66, 0x77};
+
+    // Generate DPP bootstrap information.
+    DppResponderBootstrapInfo bootstrapInfo;
+    EXPECT_TRUE(
+        sta_iface_
+            ->generateDppBootstrapInfoForResponder(
+                mac_address, deviceInfo, DppCurve::PRIME256V1, &bootstrapInfo)
+            .isOk());
+    EXPECT_NE(-1, bootstrapInfo.bootstrapId);
+    EXPECT_NE(0, bootstrapInfo.bootstrapId);
+    EXPECT_NE(0, bootstrapInfo.listenChannel);
+    const uint32_t bootstrap_id = bootstrapInfo.bootstrapId;
+    const uint32_t listen_channel = bootstrapInfo.listenChannel;
+
+    // Start DPP as Enrollee-Responder.
+    EXPECT_TRUE(sta_iface_->startDppEnrolleeResponder(listen_channel).isOk());
+
+    // Stop DPP Enrollee-Responder mode, ie remove the URI and stop listen.
+    EXPECT_TRUE(sta_iface_->stopDppResponder(bootstrap_id).isOk());
+}
+
+class IfaceDppCallback : public SupplicantStaIfaceCallback {
+    SupplicantStaIfaceAidlTest& parent_;
+    ::ndk::ScopedAStatus onDppSuccess(
+        ::aidl::android::hardware::wifi::supplicant::DppEventType event)
+        override {
+        parent_.code = (uint32_t)event;
+        parent_.dppCallbackType =
+            SupplicantStaIfaceAidlTest::DppCallbackType::EVENT_SUCCESS;
+        parent_.notify();
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onDppProgress(
+        aidl::android::hardware::wifi::supplicant::DppProgressCode code)
+        override {
+        parent_.code = (uint32_t)code;
+        parent_.dppCallbackType =
+            SupplicantStaIfaceAidlTest::DppCallbackType::EVENT_PROGRESS;
+        parent_.notify();
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onDppFailure(
+        aidl::android::hardware::wifi::supplicant::DppFailureCode code,
+        const std::string& ssid __attribute__((unused)),
+        const std::string& channelList __attribute__((unused)),
+        const std::vector<char16_t>& bandList
+        __attribute__((unused))) override {
+        parent_.code = (uint32_t)code;
+        parent_.dppCallbackType =
+            SupplicantStaIfaceAidlTest::DppCallbackType::EVENT_FAILURE;
+        parent_.notify();
+        return ndk::ScopedAStatus::ok();
+    }
+
+   public:
+    IfaceDppCallback(SupplicantStaIfaceAidlTest& parent) : parent_(parent){};
+};
+
+/*
+ * StartDppEnrolleeInitiator
+ */
+TEST_P(SupplicantStaIfaceAidlTest, StartDppEnrolleeInitiator) {
+    if (!keyMgmtSupported(sta_iface_, KeyMgmtMask::DPP)) {
+        GTEST_SKIP() << "Missing DPP support";
+    }
+
+    // Register callback
+    std::shared_ptr<IfaceDppCallback> callback =
+        ndk::SharedRefBase::make<IfaceDppCallback>(*this);
+    EXPECT_NE(callback, nullptr);
+    EXPECT_TRUE(sta_iface_->registerCallback(callback).isOk());
+
+    // Add a peer URI
+    int32_t peer_id = 0;
+    EXPECT_TRUE(sta_iface_->addDppPeerUri(kTestUri, &peer_id).isOk());
+    EXPECT_NE(0, peer_id);
+    EXPECT_NE(-1, peer_id);
+
+    // Start DPP as Enrollee-Initiator. Since this operation requires two
+    // devices, we start the operation and expect a timeout.
+    EXPECT_TRUE(sta_iface_->startDppEnrolleeInitiator(peer_id, 0).isOk());
+
+    // Wait for the timeout callback
+    EXPECT_EQ(std::cv_status::no_timeout,
+              wait(SupplicantStaIfaceAidlTest::DppCallbackType::EVENT_FAILURE));
+    EXPECT_EQ(SupplicantStaIfaceAidlTest::DppCallbackType::EVENT_FAILURE,
+              dppCallbackType);
+
+    // ...and then remove the peer URI.
+    EXPECT_TRUE(sta_iface_->removeDppUri(peer_id).isOk());
+}
+
+/*
+ * StartDppConfiguratorInitiator
+ */
+TEST_P(SupplicantStaIfaceAidlTest, StartDppConfiguratorInitiator) {
+    if (!keyMgmtSupported(sta_iface_, KeyMgmtMask::DPP)) {
+        GTEST_SKIP() << "Missing DPP support";
+    }
+
+    // Register callback
+    std::shared_ptr<IfaceDppCallback> callback =
+        ndk::SharedRefBase::make<IfaceDppCallback>(*this);
+    EXPECT_NE(callback, nullptr);
+    EXPECT_TRUE(sta_iface_->registerCallback(callback).isOk());
+
+    // Add a peer URI
+    int32_t peer_id = 0;
+    EXPECT_TRUE(sta_iface_->addDppPeerUri(kTestUri, &peer_id).isOk());
+    EXPECT_NE(0, peer_id);
+    EXPECT_NE(-1, peer_id);
+
+    const std::string ssid =
+        "6D795F746573745F73736964";  // 'my_test_ssid' encoded in hex
+    const std::string password =
+        "746F70736563726574";  // 'topsecret' encoded in hex
+
+    // Start DPP as Configurator-Initiator. Since this operation requires two
+    // devices, we start the operation and expect a timeout.
+    EXPECT_TRUE(sta_iface_
+                    ->startDppConfiguratorInitiator(peer_id, 0, ssid, password,
+                                                    "", DppNetRole::STA,
+                                                    DppAkm::PSK)
+                    .isOk());
+
+    // Wait for the timeout callback
+    ASSERT_EQ(std::cv_status::no_timeout,
+              wait(SupplicantStaIfaceAidlTest::DppCallbackType::EVENT_FAILURE));
+    ASSERT_EQ(SupplicantStaIfaceAidlTest::DppCallbackType::EVENT_FAILURE,
+              dppCallbackType);
+
+    // ...and then remove the peer URI.
+    EXPECT_TRUE(sta_iface_->removeDppUri(peer_id).isOk());
+}
+
+INSTANTIATE_TEST_SUITE_P(Supplicant, SupplicantStaIfaceAidlTest,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(
+                             ISupplicant::descriptor)),
+                         android::PrintInstanceNameToString);
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    ProcessState::self()->setThreadPoolMaxThreadCount(1);
+    ProcessState::self()->startThreadPool();
+    return RUN_ALL_TESTS();
+}
diff --git a/wifi/supplicant/aidl/vts/functional/supplicant_sta_network_aidl_test.cpp b/wifi/supplicant/aidl/vts/functional/supplicant_sta_network_aidl_test.cpp
new file mode 100644
index 0000000..66c8807
--- /dev/null
+++ b/wifi/supplicant/aidl/vts/functional/supplicant_sta_network_aidl_test.cpp
@@ -0,0 +1,791 @@
+/*
+ * 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 <VtsCoreUtil.h>
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/wifi/supplicant/BnSupplicant.h>
+#include <aidl/android/hardware/wifi/supplicant/BnSupplicantStaNetworkCallback.h>
+#include <android/binder_manager.h>
+#include <android/binder_status.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+#include <cutils/properties.h>
+
+#include "supplicant_test_utils.h"
+
+using aidl::android::hardware::wifi::supplicant::AuthAlgMask;
+using aidl::android::hardware::wifi::supplicant::BnSupplicantStaNetworkCallback;
+using aidl::android::hardware::wifi::supplicant::DebugLevel;
+using aidl::android::hardware::wifi::supplicant::EapMethod;
+using aidl::android::hardware::wifi::supplicant::EapPhase2Method;
+using aidl::android::hardware::wifi::supplicant::GroupCipherMask;
+using aidl::android::hardware::wifi::supplicant::GroupMgmtCipherMask;
+using aidl::android::hardware::wifi::supplicant::IfaceType;
+using aidl::android::hardware::wifi::supplicant::ISupplicant;
+using aidl::android::hardware::wifi::supplicant::ISupplicantStaIface;
+using aidl::android::hardware::wifi::supplicant::ISupplicantStaNetwork;
+using aidl::android::hardware::wifi::supplicant::KeyMgmtMask;
+using aidl::android::hardware::wifi::supplicant::
+    NetworkRequestEapSimGsmAuthParams;
+using aidl::android::hardware::wifi::supplicant::
+    NetworkRequestEapSimUmtsAuthParams;
+using aidl::android::hardware::wifi::supplicant::
+    NetworkResponseEapSimGsmAuthParams;
+using aidl::android::hardware::wifi::supplicant::
+    NetworkResponseEapSimUmtsAuthParams;
+using aidl::android::hardware::wifi::supplicant::OcspType;
+using aidl::android::hardware::wifi::supplicant::PairwiseCipherMask;
+using aidl::android::hardware::wifi::supplicant::ProtoMask;
+using aidl::android::hardware::wifi::supplicant::SaeH2eMode;
+using aidl::android::hardware::wifi::supplicant::TransitionDisableIndication;
+using aidl::android::hardware::wifi::supplicant::WpaDriverCapabilitiesMask;
+using android::ProcessState;
+
+namespace {
+const std::vector<uint8_t> kTestIdentity = {0x45, 0x67, 0x98, 0x67, 0x56};
+const std::vector<uint8_t> kTestEncryptedIdentity = {0x35, 0x37, 0x58, 0x57,
+                                                     0x26};
+const std::string kTestSsidStr = "TestSsid1234";
+const std::vector<uint8_t> kTestSsid =
+    std::vector<uint8_t>(kTestSsidStr.begin(), kTestSsidStr.end());
+const std::vector<uint8_t> kTestBssid = {0x56, 0x67, 0x67, 0xf4, 0x56, 0x92};
+const std::string kTestPskPassphrase =
+    "\"123456780abcdef0123456780abcdef0deadbeef\"";
+const std::string kTestEapCert = "keystore://CERT";
+const std::string kTestEapMatch = "match";
+const KeyMgmtMask kTestKeyMgmt =
+    static_cast<KeyMgmtMask>(static_cast<uint32_t>(KeyMgmtMask::WPA_PSK) |
+                             static_cast<uint32_t>(KeyMgmtMask::WPA_EAP));
+
+}  // namespace
+
+class SupplicantStaNetworkCallback : public BnSupplicantStaNetworkCallback {
+   public:
+    SupplicantStaNetworkCallback() = default;
+
+    ::ndk::ScopedAStatus onNetworkEapIdentityRequest() override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onNetworkEapSimGsmAuthRequest(
+        const NetworkRequestEapSimGsmAuthParams& /* params */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onNetworkEapSimUmtsAuthRequest(
+        const NetworkRequestEapSimUmtsAuthParams& /* params */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onTransitionDisable(
+        TransitionDisableIndication /* ind */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+};
+
+class SupplicantStaNetworkAidlTest
+    : public testing::TestWithParam<std::string> {
+   public:
+    void SetUp() override {
+        initializeService();
+        supplicant_ = ISupplicant::fromBinder(ndk::SpAIBinder(
+            AServiceManager_waitForService(GetParam().c_str())));
+        ASSERT_NE(supplicant_, nullptr);
+        ASSERT_TRUE(supplicant_
+                        ->setDebugParams(DebugLevel::EXCESSIVE,
+                                         true,  // show timestamps
+                                         true)
+                        .isOk());
+        EXPECT_TRUE(supplicant_->addStaInterface(getStaIfaceName(), &sta_iface_)
+                        .isOk());
+        ASSERT_NE(sta_iface_, nullptr);
+        EXPECT_TRUE(sta_iface_->addNetwork(&sta_network_).isOk());
+        ASSERT_NE(sta_network_, nullptr);
+    }
+
+    void TearDown() override {
+        stopSupplicant();
+        startWifiFramework();
+    }
+
+   protected:
+    std::shared_ptr<ISupplicant> supplicant_;
+    std::shared_ptr<ISupplicantStaIface> sta_iface_;
+    std::shared_ptr<ISupplicantStaNetwork> sta_network_;
+
+    void removeNetwork() {
+        ASSERT_NE(sta_iface_, nullptr);
+        int32_t net_id;
+        EXPECT_TRUE(sta_network_->getId(&net_id).isOk());
+        EXPECT_TRUE(sta_iface_->removeNetwork(net_id).isOk());
+    }
+};
+
+/*
+ * RegisterCallback
+ */
+TEST_P(SupplicantStaNetworkAidlTest, RegisterCallback) {
+    std::shared_ptr<SupplicantStaNetworkCallback> callback =
+        ndk::SharedRefBase::make<SupplicantStaNetworkCallback>();
+    ASSERT_NE(callback, nullptr);
+    EXPECT_TRUE(sta_network_->registerCallback(callback).isOk());
+}
+
+/*
+ * GetInterfaceName
+ */
+TEST_P(SupplicantStaNetworkAidlTest, GetInterfaceName) {
+    std::string name;
+    EXPECT_TRUE(sta_network_->getInterfaceName(&name).isOk());
+    EXPECT_NE(name.size(), 0);
+}
+
+/*
+ * GetType
+ */
+TEST_P(SupplicantStaNetworkAidlTest, GetType) {
+    IfaceType type;
+    EXPECT_TRUE(sta_network_->getType(&type).isOk());
+    EXPECT_EQ(type, IfaceType::STA);
+}
+
+/*
+ * Set/Get ScanSsid
+ */
+TEST_P(SupplicantStaNetworkAidlTest, SetGetScanSsid) {
+    bool scanSsid = false;
+    EXPECT_TRUE(sta_network_->setScanSsid(true).isOk());
+    EXPECT_TRUE(sta_network_->getScanSsid(&scanSsid).isOk());
+    EXPECT_TRUE(scanSsid);
+}
+
+/*
+ * Set/Get RequirePmf
+ */
+TEST_P(SupplicantStaNetworkAidlTest, SetGetRequirePmf) {
+    bool requirePmf = false;
+    EXPECT_TRUE(sta_network_->setRequirePmf(true).isOk());
+    EXPECT_TRUE(sta_network_->getRequirePmf(&requirePmf).isOk());
+    EXPECT_TRUE(requirePmf);
+}
+
+/*
+ * Set/Get IdStr
+ */
+TEST_P(SupplicantStaNetworkAidlTest, SetGetIdStr) {
+    const std::string savedIdStr = "TestIdstr";
+    EXPECT_TRUE(sta_network_->setIdStr(savedIdStr).isOk());
+
+    std::string retrievedIdStr;
+    EXPECT_TRUE(sta_network_->getIdStr(&retrievedIdStr).isOk());
+    EXPECT_EQ(retrievedIdStr, savedIdStr);
+}
+
+/*
+ * Set/Get EapMethod
+ */
+TEST_P(SupplicantStaNetworkAidlTest, SetGetEapMethod) {
+    const EapMethod savedMethod = EapMethod::PEAP;
+    EXPECT_TRUE(sta_network_->setEapMethod(savedMethod).isOk());
+
+    EapMethod retrievedMethod;
+    EXPECT_TRUE(sta_network_->getEapMethod(&retrievedMethod).isOk());
+    EXPECT_EQ(retrievedMethod, savedMethod);
+}
+
+/*
+ * Set/Get EapPhase2Method
+ */
+TEST_P(SupplicantStaNetworkAidlTest, SetGetEapPhase2Method) {
+    const EapMethod savedEapMethod = EapMethod::PEAP;
+    EXPECT_TRUE(sta_network_->setEapMethod(savedEapMethod).isOk());
+
+    const EapPhase2Method savedPhase2Method = EapPhase2Method::NONE;
+    EXPECT_TRUE(sta_network_->setEapPhase2Method(savedPhase2Method).isOk());
+
+    EapPhase2Method retrievedMethod;
+    EXPECT_TRUE(sta_network_->getEapPhase2Method(&retrievedMethod).isOk());
+    EXPECT_EQ(retrievedMethod, savedPhase2Method);
+}
+
+/*
+ * Set/Get EapIdentity
+ */
+TEST_P(SupplicantStaNetworkAidlTest, SetGetEapIdentity) {
+    EXPECT_TRUE(sta_network_->setEapIdentity(kTestIdentity).isOk());
+
+    std::vector<uint8_t> retrievedIdentity;
+    EXPECT_TRUE(sta_network_->getEapIdentity(&retrievedIdentity).isOk());
+    EXPECT_EQ(retrievedIdentity, kTestIdentity);
+}
+
+/*
+ * Set/Get EapAnonymousIdentity
+ */
+TEST_P(SupplicantStaNetworkAidlTest, SetGetEapAnonymousIdentity) {
+    EXPECT_TRUE(sta_network_->setEapAnonymousIdentity(kTestIdentity).isOk());
+
+    std::vector<uint8_t> retrievedIdentity;
+    EXPECT_TRUE(
+        sta_network_->getEapAnonymousIdentity(&retrievedIdentity).isOk());
+    EXPECT_EQ(retrievedIdentity, kTestIdentity);
+}
+
+/*
+ * Set/Get EapPassword
+ */
+TEST_P(SupplicantStaNetworkAidlTest, SetGetEapPassword) {
+    const std::string eapPasswdStr = "TestEapPasswd1234";
+    const std::vector<uint8_t> savedEapPasswd =
+        std::vector<uint8_t>(eapPasswdStr.begin(), eapPasswdStr.end());
+    ASSERT_TRUE(sta_network_->setEapPassword(savedEapPasswd).isOk());
+
+    std::vector<uint8_t> retrievedEapPasswd;
+    ASSERT_TRUE(sta_network_->getEapPassword(&retrievedEapPasswd).isOk());
+    ASSERT_EQ(retrievedEapPasswd, savedEapPasswd);
+}
+
+/*
+ * Set/Get EapCACert
+ */
+TEST_P(SupplicantStaNetworkAidlTest, SetGetEapCACert) {
+    EXPECT_TRUE(sta_network_->setEapCACert(kTestEapCert).isOk());
+
+    std::string retrievedCert;
+    EXPECT_TRUE(sta_network_->getEapCACert(&retrievedCert).isOk());
+    EXPECT_EQ(retrievedCert, kTestEapCert);
+}
+
+/*
+ * Set/Get EapCAPath
+ */
+TEST_P(SupplicantStaNetworkAidlTest, SetGetEapCAPath) {
+    EXPECT_TRUE(sta_network_->setEapCAPath(kTestEapCert).isOk());
+
+    std::string retrievedCert;
+    EXPECT_TRUE(sta_network_->getEapCAPath(&retrievedCert).isOk());
+    EXPECT_EQ(retrievedCert, kTestEapCert);
+}
+
+/*
+ * Set/Get EapClientCert
+ */
+TEST_P(SupplicantStaNetworkAidlTest, SetGetEapClientCert) {
+    EXPECT_TRUE(sta_network_->setEapClientCert(kTestEapCert).isOk());
+
+    std::string retrievedCert;
+    EXPECT_TRUE(sta_network_->getEapClientCert(&retrievedCert).isOk());
+    EXPECT_EQ(retrievedCert, kTestEapCert);
+}
+
+/*
+ * Set/Get EapPrivateKeyId
+ */
+TEST_P(SupplicantStaNetworkAidlTest, SetGetEapPrivateKeyId) {
+    std::string savedKeyId = "key_id";
+    EXPECT_TRUE(sta_network_->setEapPrivateKeyId(savedKeyId).isOk());
+
+    std::string retrievedKeyId;
+    EXPECT_TRUE(sta_network_->getEapPrivateKeyId(&retrievedKeyId).isOk());
+    EXPECT_EQ(retrievedKeyId, savedKeyId);
+}
+
+/*
+ * Set/Get EapAltSubjectMatch
+ */
+TEST_P(SupplicantStaNetworkAidlTest, SetGetEapAltSubjectMatch) {
+    EXPECT_TRUE(sta_network_->setEapAltSubjectMatch(kTestEapMatch).isOk());
+
+    std::string retrievedMatch;
+    EXPECT_TRUE(sta_network_->getEapAltSubjectMatch(&retrievedMatch).isOk());
+    EXPECT_EQ(retrievedMatch, kTestEapMatch);
+}
+
+/*
+ * Set/Get EapSubjectMatch
+ */
+TEST_P(SupplicantStaNetworkAidlTest, SetGetEapSubjectMatch) {
+    EXPECT_TRUE(sta_network_->setEapSubjectMatch(kTestEapMatch).isOk());
+
+    std::string retrievedMatch;
+    EXPECT_TRUE(sta_network_->getEapSubjectMatch(&retrievedMatch).isOk());
+    EXPECT_EQ(retrievedMatch, kTestEapMatch);
+}
+
+/*
+ * Set/Get EapDomainSuffixMatch
+ */
+TEST_P(SupplicantStaNetworkAidlTest, SetGetEapDomainSuffixMatch) {
+    EXPECT_TRUE(sta_network_->setEapDomainSuffixMatch(kTestEapMatch).isOk());
+
+    std::string retrievedMatch;
+    EXPECT_TRUE(sta_network_->getEapDomainSuffixMatch(&retrievedMatch).isOk());
+    EXPECT_EQ(retrievedMatch, kTestEapMatch);
+}
+
+/*
+ * Set/Get EapEngine
+ */
+TEST_P(SupplicantStaNetworkAidlTest, SetGetEapEngine) {
+    bool retrievedEapEngine = false;
+    EXPECT_TRUE(sta_network_->setEapEngine(true).isOk());
+    EXPECT_TRUE(sta_network_->getEapEngine(&retrievedEapEngine).isOk());
+    EXPECT_TRUE(retrievedEapEngine);
+}
+
+/*
+ * Set/Get EapEngineID
+ */
+TEST_P(SupplicantStaNetworkAidlTest, SetGetEapEngineId) {
+    const std::string savedEngineId = "engine_id";
+    EXPECT_TRUE(sta_network_->setEapEngineID(savedEngineId).isOk());
+
+    std::string retrievedId;
+    EXPECT_TRUE(sta_network_->getEapEngineId(&retrievedId).isOk());
+    EXPECT_EQ(retrievedId, savedEngineId);
+}
+
+/*
+ * Set/Get Ocsp
+ */
+TEST_P(SupplicantStaNetworkAidlTest, SetGetOcsp) {
+    const OcspType savedOcspType = OcspType::REQUEST_CERT_STATUS;
+    EXPECT_TRUE(sta_network_->setOcsp(savedOcspType).isOk());
+
+    const OcspType invalidOcspType = static_cast<OcspType>(-1);
+    EXPECT_FALSE(sta_network_->setOcsp(invalidOcspType).isOk());
+
+    OcspType retrievedOcspType;
+    EXPECT_TRUE(sta_network_->getOcsp(&retrievedOcspType).isOk());
+    EXPECT_EQ(retrievedOcspType, savedOcspType);
+}
+
+/*
+ * Set/Get KeyMgmt
+ */
+TEST_P(SupplicantStaNetworkAidlTest, SetGetKeyMgmt) {
+    KeyMgmtMask savedKeyMgmt = KeyMgmtMask::WAPI_PSK;
+    EXPECT_TRUE(sta_network_->setKeyMgmt(savedKeyMgmt).isOk());
+
+    KeyMgmtMask retrievedKeyMgmt;
+    EXPECT_TRUE(sta_network_->getKeyMgmt(&retrievedKeyMgmt).isOk());
+    EXPECT_EQ(retrievedKeyMgmt, savedKeyMgmt);
+
+    savedKeyMgmt = KeyMgmtMask::WAPI_CERT;
+    EXPECT_TRUE(sta_network_->setKeyMgmt(savedKeyMgmt).isOk());
+
+    EXPECT_TRUE(sta_network_->getKeyMgmt(&retrievedKeyMgmt).isOk());
+    EXPECT_EQ(retrievedKeyMgmt, savedKeyMgmt);
+}
+
+/*
+ * Set/Get Proto
+ */
+TEST_P(SupplicantStaNetworkAidlTest, SetGetProto) {
+    const ProtoMask savedProto = ProtoMask::WAPI;
+    EXPECT_TRUE(sta_network_->setProto(savedProto).isOk());
+
+    ProtoMask retrievedProto;
+    EXPECT_TRUE(sta_network_->getProto(&retrievedProto).isOk());
+    EXPECT_EQ(retrievedProto, savedProto);
+}
+
+/*
+ * Set/Get GroupCipher
+ */
+TEST_P(SupplicantStaNetworkAidlTest, SetGetGroupCipher) {
+    const GroupCipherMask savedCipher = GroupCipherMask::SMS4;
+    EXPECT_TRUE(sta_network_->setGroupCipher(savedCipher).isOk());
+
+    GroupCipherMask retrievedCipher;
+    EXPECT_TRUE(sta_network_->getGroupCipher(&retrievedCipher).isOk());
+    EXPECT_EQ(retrievedCipher, savedCipher);
+}
+
+/*
+ * Set/Get PairwiseCipher
+ */
+TEST_P(SupplicantStaNetworkAidlTest, SetGetPairwiseCipher) {
+    const PairwiseCipherMask savedCipher = PairwiseCipherMask::SMS4;
+    EXPECT_TRUE(sta_network_->setPairwiseCipher(savedCipher).isOk());
+
+    PairwiseCipherMask retrievedCipher;
+    EXPECT_TRUE(sta_network_->getPairwiseCipher(&retrievedCipher).isOk());
+    EXPECT_EQ(retrievedCipher, savedCipher);
+}
+
+/*
+ * Set/Get WapiCertSuite
+ */
+TEST_P(SupplicantStaNetworkAidlTest, SetGetWapiCertSuite) {
+    if (!keyMgmtSupported(sta_iface_, KeyMgmtMask::WAPI_PSK)) {
+        GTEST_SKIP() << "Skipping test since WAPI is not supported.";
+    }
+
+    const std::string savedCertSuite = "suite";
+    EXPECT_TRUE(sta_network_->setWapiCertSuite(savedCertSuite).isOk());
+
+    std::string retrievedCertSuite;
+    EXPECT_TRUE(sta_network_->getWapiCertSuite(&retrievedCertSuite).isOk());
+    EXPECT_EQ(retrievedCertSuite, savedCertSuite);
+}
+
+/*
+ * Set/Get WapiPsk
+ */
+TEST_P(SupplicantStaNetworkAidlTest, SetGetWapiPsk) {
+    if (!keyMgmtSupported(sta_iface_, KeyMgmtMask::WAPI_PSK)) {
+        GTEST_SKIP() << "Skipping test since WAPI is not supported.";
+    }
+
+    EXPECT_TRUE(sta_network_->setKeyMgmt(KeyMgmtMask::WAPI_PSK).isOk());
+    EXPECT_TRUE(sta_network_->setPskPassphrase(kTestPskPassphrase).isOk());
+
+    std::string retrievedPassphrase;
+    EXPECT_TRUE(sta_network_->getPskPassphrase(&retrievedPassphrase).isOk());
+    EXPECT_EQ(retrievedPassphrase, kTestPskPassphrase);
+
+    const std::string pskHex = "12345678";
+    EXPECT_TRUE(sta_network_->setPskPassphrase(pskHex).isOk());
+
+    EXPECT_TRUE(sta_network_->getPskPassphrase(&retrievedPassphrase).isOk());
+    EXPECT_EQ(retrievedPassphrase, pskHex);
+}
+
+/*
+ * Set/Get SaePassword
+ */
+TEST_P(SupplicantStaNetworkAidlTest, SetGetSaePassword) {
+    const std::string savedPassword = "topsecret";
+    EXPECT_TRUE(sta_network_->setSaePassword(savedPassword).isOk());
+
+    std::string retrievedPassword;
+    EXPECT_TRUE(sta_network_->getSaePassword(&retrievedPassword).isOk());
+    EXPECT_EQ(retrievedPassword, savedPassword);
+}
+
+/*
+ * Set/Get SaePasswordId
+ */
+TEST_P(SupplicantStaNetworkAidlTest, SetGetSaePasswordId) {
+    const std::string savedPasswdId = "id1";
+    EXPECT_TRUE(sta_network_->setSaePasswordId(savedPasswdId).isOk());
+
+    std::string retrievedPasswdId;
+    EXPECT_TRUE(sta_network_->getSaePasswordId(&retrievedPasswdId).isOk());
+    EXPECT_EQ(retrievedPasswdId, savedPasswdId);
+}
+
+/*
+ * Set/Get GroupMgmtCipher
+ */
+TEST_P(SupplicantStaNetworkAidlTest, SetGetGroupMgmtCipher) {
+    const GroupMgmtCipherMask savedCipher = GroupMgmtCipherMask::BIP_GMAC_256;
+    EXPECT_TRUE(sta_network_->setGroupMgmtCipher(savedCipher).isOk());
+
+    GroupMgmtCipherMask retrievedCipher;
+    EXPECT_TRUE(sta_network_->getGroupMgmtCipher(&retrievedCipher).isOk());
+    EXPECT_EQ(retrievedCipher, savedCipher);
+}
+
+/*
+ * Set/Get Ssid
+ */
+TEST_P(SupplicantStaNetworkAidlTest, SetGetSsid) {
+    EXPECT_TRUE(sta_network_->setSsid(kTestSsid).isOk());
+
+    std::vector<uint8_t> retrievedSsid;
+    EXPECT_TRUE(sta_network_->getSsid(&retrievedSsid).isOk());
+    EXPECT_EQ(retrievedSsid, kTestSsid);
+}
+
+/*
+ * Set/Get Bssid
+ */
+TEST_P(SupplicantStaNetworkAidlTest, SetGetBssid) {
+    EXPECT_TRUE(sta_network_->setBssid(kTestBssid).isOk());
+
+    std::vector<uint8_t> retrievedBssid;
+    EXPECT_TRUE(sta_network_->getBssid(&retrievedBssid).isOk());
+    EXPECT_EQ(retrievedBssid, kTestBssid);
+}
+
+/*
+ * Set/Get KeyAuthAlg
+ */
+TEST_P(SupplicantStaNetworkAidlTest, SetGetAuthAlg) {
+    const AuthAlgMask savedAlg =
+        static_cast<AuthAlgMask>(static_cast<uint32_t>(AuthAlgMask::OPEN) |
+                                 static_cast<uint32_t>(AuthAlgMask::SHARED));
+    EXPECT_TRUE(sta_network_->setAuthAlg(savedAlg).isOk());
+
+    AuthAlgMask retrievedAlg;
+    EXPECT_TRUE(sta_network_->getAuthAlg(&retrievedAlg).isOk());
+    EXPECT_EQ(retrievedAlg, savedAlg);
+}
+
+/*
+ * Set/Get WepTxKeyIdx
+ */
+TEST_P(SupplicantStaNetworkAidlTest, SetGetWepTxKeyIdx) {
+    const int32_t savedKeyIdx = 2;
+    EXPECT_TRUE(sta_network_->setWepTxKeyIdx(savedKeyIdx).isOk());
+
+    int32_t retrievedKeyIdx;
+    EXPECT_TRUE(sta_network_->getWepTxKeyIdx(&retrievedKeyIdx).isOk());
+    EXPECT_EQ(retrievedKeyIdx, savedKeyIdx);
+}
+
+/*
+ * Set SAE H2E (Hash-to-Element) mode
+ */
+TEST_P(SupplicantStaNetworkAidlTest, SetSaeH2eMode) {
+    EXPECT_TRUE(sta_network_->setSaeH2eMode(SaeH2eMode::DISABLED).isOk());
+    EXPECT_TRUE(sta_network_->setSaeH2eMode(SaeH2eMode::H2E_MANDATORY).isOk());
+    EXPECT_TRUE(sta_network_->setSaeH2eMode(SaeH2eMode::H2E_OPTIONAL).isOk());
+}
+
+/*
+ * Set/Get Psk
+ */
+TEST_P(SupplicantStaNetworkAidlTest, SetGetPsk) {
+    const std::vector<uint8_t> savedPsk = std::vector<uint8_t>(32, 0x12);
+    EXPECT_TRUE(sta_network_->setPsk(savedPsk).isOk());
+
+    std::vector<uint8_t> retrievedPsk;
+    EXPECT_TRUE(sta_network_->getPsk(&retrievedPsk).isOk());
+    EXPECT_EQ(retrievedPsk, savedPsk);
+}
+
+/*
+ * Set/Get WepKeys
+ */
+TEST_P(SupplicantStaNetworkAidlTest, SetGetWepKeys) {
+    const uint32_t maxKeys = 4;
+    const std::vector<uint8_t> testWepKey = {0x56, 0x67, 0x67, 0xf4, 0x56};
+
+    for (uint32_t i = 0; i < maxKeys; i++) {
+        std::vector<uint8_t> retrievedKey;
+        EXPECT_TRUE(sta_network_->setWepKey(i, testWepKey).isOk());
+        EXPECT_TRUE(sta_network_->getWepKey(i, &retrievedKey).isOk());
+        EXPECT_EQ(retrievedKey, testWepKey);
+    }
+}
+
+/*
+ * SetPmkCacheEntry
+ */
+TEST_P(SupplicantStaNetworkAidlTest, SetPmkCache) {
+    const std::vector<uint8_t> serializedEntry(128, 0);
+    EXPECT_TRUE(sta_network_->setPmkCache(serializedEntry).isOk());
+}
+
+/*
+ * SetEapErp
+ */
+TEST_P(SupplicantStaNetworkAidlTest, SetEapErp) {
+    if (!isFilsSupported(sta_iface_)) {
+        GTEST_SKIP()
+            << "Skipping test since driver/supplicant doesn't support FILS";
+    }
+    EXPECT_TRUE(sta_network_->setEapErp(true).isOk());
+}
+
+/*
+ * SetUpdateIdentifier
+ */
+TEST_P(SupplicantStaNetworkAidlTest, SetUpdateIdentifier) {
+    const uint32_t updateIdentifier = 21;
+    EXPECT_TRUE(sta_network_->setUpdateIdentifier(updateIdentifier).isOk());
+}
+
+/*
+ * SetProactiveKeyCaching
+ */
+TEST_P(SupplicantStaNetworkAidlTest, SetProactiveKeyCaching) {
+    EXPECT_TRUE(sta_network_->setProactiveKeyCaching(true).isOk());
+    EXPECT_TRUE(sta_network_->setProactiveKeyCaching(false).isOk());
+}
+
+/*
+ * EnableSuiteBEapOpenSslCiphers
+ */
+TEST_P(SupplicantStaNetworkAidlTest, EnableSuiteBEapOpenSslCiphers) {
+    EXPECT_TRUE(sta_network_->enableSuiteBEapOpenSslCiphers().isOk());
+}
+
+/*
+ * EnableTlsSuiteBEapPhase1Param
+ */
+TEST_P(SupplicantStaNetworkAidlTest, EnableTlsSuiteBEapPhase1Param) {
+    EXPECT_TRUE(sta_network_->enableTlsSuiteBEapPhase1Param(true).isOk());
+    EXPECT_TRUE(sta_network_->enableTlsSuiteBEapPhase1Param(false).isOk());
+}
+
+/*
+ * SetEapEncryptedImsiIdentity
+ */
+TEST_P(SupplicantStaNetworkAidlTest, SetEapEncryptedImsiIdentity) {
+    EXPECT_TRUE(
+        sta_network_->setEapEncryptedImsiIdentity(kTestEncryptedIdentity)
+            .isOk());
+}
+
+/*
+ * SendNetworkEapIdentityResponse
+ */
+TEST_P(SupplicantStaNetworkAidlTest, SendNetworkEapIdentityResponse) {
+    EXPECT_TRUE(sta_network_
+                    ->sendNetworkEapIdentityResponse(kTestIdentity,
+                                                     kTestEncryptedIdentity)
+                    .isOk());
+}
+
+/*
+ * Enable SAE PK only mode
+ */
+TEST_P(SupplicantStaNetworkAidlTest, EnableSaePkOnlyMode) {
+    // Check for SAE PK support
+    WpaDriverCapabilitiesMask caps;
+    EXPECT_TRUE(sta_iface_->getWpaDriverCapabilities(&caps).isOk());
+    const bool saePkSupported =
+        !!(static_cast<uint32_t>(caps) &
+           static_cast<uint32_t>(WpaDriverCapabilitiesMask::SAE_PK));
+    LOG(INFO) << "SAE-PK Supported: " << saePkSupported;
+
+    // Operation will succeed if SAE PK is supported, or fail otherwise.
+    EXPECT_EQ(sta_network_->enableSaePkOnlyMode(true).isOk(), saePkSupported);
+    EXPECT_EQ(sta_network_->enableSaePkOnlyMode(false).isOk(), saePkSupported);
+}
+
+/*
+ * Enable
+ */
+TEST_P(SupplicantStaNetworkAidlTest, Enable) {
+    // wpa_supplicant won't perform any connection initiation
+    // unless at least the SSID and key mgmt params are set.
+    EXPECT_TRUE(sta_network_->setSsid(kTestSsid).isOk());
+    EXPECT_TRUE(sta_network_->setKeyMgmt(kTestKeyMgmt).isOk());
+
+    EXPECT_TRUE(sta_network_->enable(false).isOk());
+    EXPECT_TRUE(sta_network_->enable(true).isOk());
+
+    // Now remove the network and ensure that the call fails.
+    removeNetwork();
+    ASSERT_FALSE(sta_network_->enable(true).isOk());
+}
+
+/*
+ * Disable
+ */
+TEST_P(SupplicantStaNetworkAidlTest, Disable) {
+    // wpa_supplicant won't perform any connection initiation
+    // unless at least the SSID and key mgmt params are set.
+    EXPECT_TRUE(sta_network_->setSsid(kTestSsid).isOk());
+    EXPECT_TRUE(sta_network_->setKeyMgmt(kTestKeyMgmt).isOk());
+
+    EXPECT_TRUE(sta_network_->disable().isOk());
+
+    // Now remove the network and ensure that the call fails.
+    removeNetwork();
+    EXPECT_FALSE(sta_network_->disable().isOk());
+}
+
+/*
+ * Select
+ */
+TEST_P(SupplicantStaNetworkAidlTest, Select) {
+    // wpa_supplicant won't perform any connection initiation
+    // unless at least the SSID and key mgmt params are set.
+    EXPECT_TRUE(sta_network_->setSsid(kTestSsid).isOk());
+    EXPECT_TRUE(sta_network_->setKeyMgmt(kTestKeyMgmt).isOk());
+
+    EXPECT_TRUE(sta_network_->select().isOk());
+
+    // Now remove the network and ensure that the call fails.
+    removeNetwork();
+    EXPECT_FALSE(sta_network_->select().isOk());
+}
+
+/*
+ * SendNetworkEapSimGsmAuthResponse
+ */
+TEST_P(SupplicantStaNetworkAidlTest, SendNetworkEapSimGsmAuthResponse) {
+    NetworkResponseEapSimGsmAuthParams param;
+    param.kc =
+        std::vector<uint8_t>({0x56, 0x67, 0x67, 0xf4, 0x76, 0x87, 0x98, 0x12});
+    param.sres = std::vector<uint8_t>({0x56, 0x67, 0x67, 0xf4});
+    const std::vector<NetworkResponseEapSimGsmAuthParams> params = {param};
+    EXPECT_TRUE(sta_network_->sendNetworkEapSimGsmAuthResponse(params).isOk());
+}
+
+/*
+ * SendNetworkEapSimGsmAuthFailure
+ */
+TEST_P(SupplicantStaNetworkAidlTest, SendNetworkEapSimGsmAuthFailure) {
+    EXPECT_TRUE(sta_network_->sendNetworkEapSimGsmAuthFailure().isOk());
+}
+
+/*
+ * SendNetworkEapSimUmtsAuthResponse
+ */
+TEST_P(SupplicantStaNetworkAidlTest, SendNetworkEapSimUmtsAuthResponse) {
+    NetworkResponseEapSimUmtsAuthParams params;
+    params.res = std::vector<uint8_t>({0x56, 0x67, 0x67, 0xf4, 0x67});
+    params.ik = std::vector<uint8_t>(16, 0x65);
+    params.ck = std::vector<uint8_t>(16, 0x45);
+    EXPECT_TRUE(sta_network_->sendNetworkEapSimUmtsAuthResponse(params).isOk());
+}
+
+/*
+ * SendNetworkEapSimUmtsAuthFailure
+ */
+TEST_P(SupplicantStaNetworkAidlTest, SendNetworkEapSimUmtsAuthFailure) {
+    EXPECT_TRUE(sta_network_->sendNetworkEapSimUmtsAuthFailure().isOk());
+}
+
+/*
+ * SendNetworkEapSimUmtsAutsResponse
+ */
+TEST_P(SupplicantStaNetworkAidlTest, SendNetworkEapSimUmtsAutsResponse) {
+    const std::vector<uint8_t> testAutParam = std::vector<uint8_t>(14, 0xe1);
+    EXPECT_TRUE(
+        sta_network_->sendNetworkEapSimUmtsAutsResponse(testAutParam).isOk());
+}
+
+/*
+ * GetWpsNfcConfigurationToken
+ */
+TEST_P(SupplicantStaNetworkAidlTest, GetWpsNfcConfigurationToken) {
+    EXPECT_TRUE(sta_network_->setSsid(kTestSsid).isOk());
+    EXPECT_TRUE(sta_network_->setKeyMgmt(kTestKeyMgmt).isOk());
+    EXPECT_TRUE(sta_network_->setPskPassphrase(kTestPskPassphrase).isOk());
+
+    std::vector<uint8_t> retrievedToken;
+    EXPECT_TRUE(
+        sta_network_->getWpsNfcConfigurationToken(&retrievedToken).isOk());
+    EXPECT_NE(retrievedToken.size(), 0);
+}
+
+INSTANTIATE_TEST_SUITE_P(Supplicant, SupplicantStaNetworkAidlTest,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(
+                             ISupplicant::descriptor)),
+                         android::PrintInstanceNameToString);
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    ProcessState::self()->setThreadPoolMaxThreadCount(1);
+    ProcessState::self()->startThreadPool();
+    return RUN_ALL_TESTS();
+}
diff --git a/wifi/supplicant/aidl/vts/functional/supplicant_test_utils.h b/wifi/supplicant/aidl/vts/functional/supplicant_test_utils.h
new file mode 100644
index 0000000..b7e1a80
--- /dev/null
+++ b/wifi/supplicant/aidl/vts/functional/supplicant_test_utils.h
@@ -0,0 +1,112 @@
+/*
+ * 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 SUPPLICANT_TEST_UTILS_H
+#define SUPPLICANT_TEST_UTILS_H
+
+#include <VtsCoreUtil.h>
+#include <android-base/logging.h>
+#include <wifi_system/supplicant_manager.h>
+
+using aidl::android::hardware::wifi::supplicant::ISupplicantStaIface;
+using aidl::android::hardware::wifi::supplicant::KeyMgmtMask;
+using android::wifi_system::SupplicantManager;
+
+std::string getStaIfaceName() {
+    std::array<char, PROPERTY_VALUE_MAX> buffer;
+    property_get("wifi.interface", buffer.data(), "wlan0");
+    return std::string(buffer.data());
+}
+
+std::string getP2pIfaceName() {
+    std::array<char, PROPERTY_VALUE_MAX> buffer;
+    property_get("wifi.direct.interface", buffer.data(), "p2p0");
+    return std::string(buffer.data());
+}
+
+bool keyMgmtSupported(std::shared_ptr<ISupplicantStaIface> iface,
+                      KeyMgmtMask expected) {
+    KeyMgmtMask caps;
+    if (!iface->getKeyMgmtCapabilities(&caps).isOk()) {
+        return false;
+    }
+    return !!(static_cast<uint32_t>(caps) & static_cast<uint32_t>(expected));
+}
+
+bool isFilsSupported(std::shared_ptr<ISupplicantStaIface> iface) {
+    KeyMgmtMask filsMask = static_cast<KeyMgmtMask>(
+        static_cast<uint32_t>(KeyMgmtMask::FILS_SHA256) |
+        static_cast<uint32_t>(KeyMgmtMask::FILS_SHA384));
+    return keyMgmtSupported(iface, filsMask);
+}
+
+bool waitForSupplicantState(bool is_running) {
+    SupplicantManager supplicant_manager;
+    int count = 50; /* wait at most 5 seconds for completion */
+    while (count-- > 0) {
+        if (supplicant_manager.IsSupplicantRunning() == is_running) {
+            return true;
+        }
+        usleep(100000);
+    }
+    LOG(ERROR) << "Supplicant not " << (is_running ? "running" : "stopped");
+    return false;
+}
+
+bool waitForFrameworkReady() {
+    int waitCount = 15;
+    do {
+        // Check whether package service is ready or not.
+        if (!testing::checkSubstringInCommandOutput(
+                "/system/bin/service check package", ": not found")) {
+            return true;
+        }
+        LOG(INFO) << "Framework is not ready";
+        sleep(1);
+    } while (waitCount-- > 0);
+    return false;
+}
+
+bool waitForSupplicantStart() { return waitForSupplicantState(true); }
+
+bool waitForSupplicantStop() { return waitForSupplicantState(false); }
+
+void stopSupplicant() {
+    SupplicantManager supplicant_manager;
+    ASSERT_TRUE(supplicant_manager.StopSupplicant());
+    ASSERT_FALSE(supplicant_manager.IsSupplicantRunning());
+}
+
+bool startWifiFramework() {
+    std::system("svc wifi enable");
+    std::system("cmd wifi set-scan-always-available enabled");
+    return waitForSupplicantStart();
+}
+
+bool stopWifiFramework() {
+    std::system("svc wifi disable");
+    std::system("cmd wifi set-scan-always-available disabled");
+    return waitForSupplicantStop();
+}
+
+void initializeService() {
+    ASSERT_TRUE(stopWifiFramework());
+    std::system("/system/bin/start");
+    ASSERT_TRUE(waitForFrameworkReady());
+    stopSupplicant();
+}
+
+#endif  // SUPPLICANT_TEST_UTILS_H
\ No newline at end of file