Merge "Enable LnbCallback in hidl/aidl default tuner implementation"
diff --git a/audio/policy/1.0/xml/api/current.txt b/audio/policy/1.0/xml/api/current.txt
index 29a9cd4..1478381 100644
--- a/audio/policy/1.0/xml/api/current.txt
+++ b/audio/policy/1.0/xml/api/current.txt
@@ -232,8 +232,10 @@
 
   public class ValueType {
     ctor public ValueType();
+    method public int getAndroid_type();
     method public String getLiteral();
     method public int getNumerical();
+    method public void setAndroid_type(int);
     method public void setLiteral(String);
     method public void setNumerical(int);
   }
diff --git a/audio/policy/1.0/xml/audio_policy_engine_configuration.xsd b/audio/policy/1.0/xml/audio_policy_engine_configuration.xsd
index 842e724..852ea77 100644
--- a/audio/policy/1.0/xml/audio_policy_engine_configuration.xsd
+++ b/audio/policy/1.0/xml/audio_policy_engine_configuration.xsd
@@ -190,6 +190,7 @@
     <xs:complexType name="valueType">
         <xs:attribute name="literal" type="xs:string" use="required"/>
         <xs:attribute name="numerical" type="xs:int" use="required"/>
+        <xs:attribute name="android_type" type="xs:int" use="optional"/>
     </xs:complexType>
 
     <xs:complexType name="attributesRefType">
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/can/1.0/tools/libprotocan/Android.bp b/automotive/can/1.0/tools/libprotocan/Android.bp
new file mode 100644
index 0000000..4c23fad
--- /dev/null
+++ b/automotive/can/1.0/tools/libprotocan/Android.bp
@@ -0,0 +1,42 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_interfaces_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_library_static {
+    name: "libprotocan",
+    defaults: ["android.hardware.automotive.can@defaults"],
+    vendor: true,
+    srcs: [
+        "Checksum.cpp",
+        "MessageCounter.cpp",
+        "MessageDef.cpp",
+        "MessageInjector.cpp",
+        "Signal.cpp",
+    ],
+    export_include_dirs: ["include"],
+
+    shared_libs: [
+        "android.hardware.automotive.can@1.0",
+    ],
+}
diff --git a/automotive/can/1.0/tools/libprotocan/Checksum.cpp b/automotive/can/1.0/tools/libprotocan/Checksum.cpp
new file mode 100644
index 0000000..72fb0af
--- /dev/null
+++ b/automotive/can/1.0/tools/libprotocan/Checksum.cpp
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <libprotocan/Checksum.h>
+
+namespace android::hardware::automotive::protocan {
+
+Checksum::Checksum(Signal signal, formula f) : mSignal(signal), mFormula(f) {}
+
+void Checksum::update(can::V1_0::CanMessage& msg) const {
+  mSignal.set(msg, 0);
+  mSignal.set(msg, mFormula(msg) % (mSignal.maxValue + 1));
+}
+
+}  // namespace android::hardware::automotive::protocan
diff --git a/automotive/can/1.0/tools/libprotocan/MessageCounter.cpp b/automotive/can/1.0/tools/libprotocan/MessageCounter.cpp
new file mode 100644
index 0000000..ef9882f
--- /dev/null
+++ b/automotive/can/1.0/tools/libprotocan/MessageCounter.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <libprotocan/MessageCounter.h>
+
+#include <android-base/logging.h>
+
+namespace android::hardware::automotive::protocan {
+
+/** Whether to log counter state messages. */
+static constexpr bool kSuperVerbose = false;
+
+MessageCounter::MessageCounter(Signal signal) : upperBound(signal.maxValue + 1), mSignal(signal) {}
+
+Signal::value MessageCounter::next() const {
+  CHECK(mCurrent.has_value()) << "Counter not initialized. Did you call isReady?";
+  return (*mCurrent + 1) % upperBound;
+}
+
+void MessageCounter::read(const can::V1_0::CanMessage& msg) {
+    auto val = mSignal.get(msg);
+
+    if (!mCurrent.has_value()) {
+        LOG(VERBOSE) << "Got first counter val of " << val;
+        mCurrent = val;
+        return;
+    }
+
+    auto nextVal = next();
+    if (nextVal == val) {
+        if constexpr (kSuperVerbose) {
+            LOG(VERBOSE) << "Got next counter val of " << nextVal;
+        }
+        mCurrent = nextVal;
+    } else {
+        LOG(DEBUG) << "Ignoring next counter val of " << val << ", waiting for " << nextVal;
+    }
+}
+
+bool MessageCounter::isReady() const { return mCurrent.has_value(); }
+
+void MessageCounter::increment(can::V1_0::CanMessage& msg) {
+  auto newVal = next();
+  mCurrent = newVal;
+  mSignal.set(msg, newVal);
+}
+
+}  // namespace android::hardware::automotive::protocan
diff --git a/automotive/can/1.0/tools/libprotocan/MessageDef.cpp b/automotive/can/1.0/tools/libprotocan/MessageDef.cpp
new file mode 100644
index 0000000..23ce1df
--- /dev/null
+++ b/automotive/can/1.0/tools/libprotocan/MessageDef.cpp
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <libprotocan/MessageDef.h>
+
+#include <android-base/logging.h>
+
+namespace android::hardware::automotive::protocan {
+
+using can::V1_0::CanMessage;
+using can::V1_0::CanMessageId;
+
+MessageDef::MessageDef(CanMessageId id, uint16_t len, std::map<std::string, Signal> signals,
+                       std::optional<Signal> counter, std::optional<Checksum> checksum)
+    : id(id), kLen(len), kSignals(std::move(signals)), kCounter(counter), kChecksum(checksum) {}
+
+const Signal& MessageDef::operator[](const std::string& signalName) const {
+  auto it = kSignals.find(signalName);
+  CHECK(it != kSignals.end()) << "Signal " << signalName << " doesn't exist";
+  return it->second;
+}
+
+CanMessage MessageDef::makeDefault() const {
+  CanMessage msg = {};
+  msg.id = id;
+  msg.payload.resize(kLen);
+
+  for (auto const& [name, signal] : kSignals) {
+    signal.setDefault(msg);
+  }
+
+  return msg;
+}
+
+MessageCounter MessageDef::makeCounter() const {
+  CHECK(kCounter.has_value()) << "Can't build a counter for message without such signal";
+  return MessageCounter(*kCounter);
+}
+
+void MessageDef::updateChecksum(can::V1_0::CanMessage& msg) const {
+  if (!kChecksum.has_value()) return;
+  kChecksum->update(msg);
+}
+
+bool MessageDef::validate(const can::V1_0::CanMessage& msg) const {
+    return msg.payload.size() >= kLen;
+}
+
+}  // namespace android::hardware::automotive::protocan
diff --git a/automotive/can/1.0/tools/libprotocan/MessageInjector.cpp b/automotive/can/1.0/tools/libprotocan/MessageInjector.cpp
new file mode 100644
index 0000000..7c45eaa
--- /dev/null
+++ b/automotive/can/1.0/tools/libprotocan/MessageInjector.cpp
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <libprotocan/MessageInjector.h>
+
+#include <android-base/logging.h>
+
+#include <thread>
+
+namespace android::hardware::automotive::protocan {
+
+/** Whether to log injected messages. */
+static constexpr bool kSuperVerbose = true;
+
+using namespace std::literals::chrono_literals;
+
+using can::V1_0::CanMessage;
+using can::V1_0::CanMessageId;
+using can::V1_0::ICanBus;
+using can::V1_0::Result;
+
+MessageInjector::MessageInjector(MessageDef msgDef,
+                                 std::optional<std::chrono::milliseconds> interMessageDelay)
+    : kMsgDef(std::move(msgDef)),
+      kInterMessageDelay(interMessageDelay),
+      mCounter(msgDef.makeCounter()) {}
+
+void MessageInjector::inject(const CanMessage& msg) { inject({msg}); }
+
+void MessageInjector::inject(const std::initializer_list<can::V1_0::CanMessage> msgs) {
+  std::lock_guard<std::mutex> lock(mMessagesGuard);
+  for (const auto& msg : msgs) {
+    if constexpr (kSuperVerbose) {
+      LOG(VERBOSE) << "Message scheduled for injection: " << toString(msg);
+    }
+
+    mMessages.push(msg);
+  }
+}
+
+void MessageInjector::processQueueLocked(can::V1_0::ICanBus& bus) {
+  if (mMessages.empty() || !mCounter.isReady()) return;
+
+  auto paddingMessagesCount = mCounter.upperBound - (mMessages.size() % mCounter.upperBound);
+  auto padMessage = kMsgDef.makeDefault();
+  for (unsigned i = 0; i < paddingMessagesCount; i++) {
+    mMessages.push(padMessage);
+  }
+
+  while (!mMessages.empty()) {
+    auto&& outMsg = mMessages.front();
+
+    mCounter.increment(outMsg);
+    kMsgDef.updateChecksum(outMsg);
+
+    if constexpr (kSuperVerbose) {
+      LOG(VERBOSE) << "Injecting message: " << toString(outMsg);
+    }
+    auto result = bus.send(outMsg);
+    if (result != Result::OK) {
+      LOG(ERROR) << "Message injection failed: " << toString(result);
+    }
+
+    mMessages.pop();
+
+    // This would block onReceive, but the class is not supposed to be used in production anyway
+    // (see MessageInjector docstring).
+    if (kInterMessageDelay.has_value()) {
+      std::this_thread::sleep_for(*kInterMessageDelay);
+    }
+  }
+}
+
+void MessageInjector::onReceive(ICanBus& bus, const CanMessage& msg) {
+    if (!kMsgDef.validate(msg)) return;
+
+    std::lock_guard<std::mutex> lock(mMessagesGuard);
+
+    mCounter.read(msg);
+    processQueueLocked(bus);
+}
+
+MessageInjectorManager::MessageInjectorManager(
+    std::initializer_list<std::shared_ptr<MessageInjector>> injectors) {
+  std::transform(injectors.begin(), injectors.end(), std::inserter(mInjectors, mInjectors.end()),
+                 [](const std::shared_ptr<MessageInjector>& injector) {
+                   return std::make_pair(injector->kMsgDef.id, std::move(injector));
+                 });
+}
+
+void MessageInjectorManager::onReceive(sp<ICanBus> bus, const CanMessage& msg) {
+  auto it = mInjectors.find(msg.id);
+  if (it == mInjectors.end()) return;
+  it->second->onReceive(*bus, msg);
+}
+
+}  // namespace android::hardware::automotive::protocan
diff --git a/automotive/can/1.0/tools/libprotocan/Signal.cpp b/automotive/can/1.0/tools/libprotocan/Signal.cpp
new file mode 100644
index 0000000..bc3e070
--- /dev/null
+++ b/automotive/can/1.0/tools/libprotocan/Signal.cpp
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <libprotocan/Signal.h>
+
+#include <android-base/logging.h>
+
+namespace android::hardware::automotive::protocan {
+
+static uint8_t calculateLastByteMask(uint16_t start, uint8_t length) {
+  unsigned lastByteBits = (start + length) % 8;
+  unsigned lastBytePadding = (8 - lastByteBits) % 8;
+  return 0xFF >> lastBytePadding;
+}
+
+static uint8_t calculateFirstByteMask(uint16_t firstByte, uint8_t firstBit, uint16_t lastByte,
+                                      uint8_t lastMask) {
+  uint8_t firstMask = 0xFF << firstBit;
+  if (firstByte == lastByte) firstMask &= lastMask;
+  return firstMask;
+}
+
+Signal::Signal(uint16_t start, uint8_t length, value defVal)
+    : maxValue((1u << length) - 1),
+      kFirstByte(start / 8),
+      kFirstBit(start % 8),
+      kFirstByteBits(8 - kFirstBit),
+      kLastByte((start + length - 1) / 8),
+      kLastMask(calculateLastByteMask(start, length)),
+      kFirstMask(calculateFirstByteMask(kFirstByte, kFirstBit, kLastByte, kLastMask)),
+      kDefVal(defVal) {
+  CHECK(length > 0) << "Signal length must not be zero";
+}
+
+Signal::value Signal::get(const can::V1_0::CanMessage& msg) const {
+    CHECK(msg.payload.size() > kLastByte)
+            << "Message is too short. Did you call MessageDef::validate?";
+
+    Signal::value v = 0;
+    if (kLastByte != kFirstByte) v = kLastMask & msg.payload[kLastByte];
+
+    for (int i = kLastByte - 1; i > kFirstByte; i--) {
+        v = (v << 8) | msg.payload[i];
+    }
+
+    return (v << kFirstByteBits) | ((msg.payload[kFirstByte] & kFirstMask) >> kFirstBit);
+}
+
+void Signal::set(can::V1_0::CanMessage& msg, Signal::value val) const {
+  CHECK(msg.payload.size() > kLastByte)
+      << "Signal requires message of length " << (kLastByte + 1)
+      << " which is beyond message length of " << msg.payload.size();
+
+  uint8_t firstByte = val << kFirstBit;
+  val >>= kFirstByteBits;
+
+  msg.payload[kFirstByte] = (msg.payload[kFirstByte] & ~kFirstMask) | (firstByte & kFirstMask);
+
+  for (int i = kFirstByte + 1; i < kLastByte; i++) {
+    msg.payload[i] = val & 0xFF;
+    val >>= 8;
+  }
+
+  if (kLastByte != kFirstByte) {
+    msg.payload[kLastByte] = (msg.payload[kLastByte] & ~kLastMask) | (val & kLastMask);
+  }
+}
+
+void Signal::setDefault(can::V1_0::CanMessage& msg) const { set(msg, kDefVal); }
+
+}  // namespace android::hardware::automotive::protocan
diff --git a/automotive/can/1.0/tools/libprotocan/include/libprotocan/Checksum.h b/automotive/can/1.0/tools/libprotocan/include/libprotocan/Checksum.h
new file mode 100644
index 0000000..ff1dc91
--- /dev/null
+++ b/automotive/can/1.0/tools/libprotocan/include/libprotocan/Checksum.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/hardware/automotive/can/1.0/types.h>
+#include <libprotocan/Signal.h>
+
+namespace android::hardware::automotive::protocan {
+
+class Checksum {
+ public:
+  using formula = std::function<Signal::value(const can::V1_0::CanMessage&)>;
+
+  Checksum(Signal signal, formula f);
+
+  void update(can::V1_0::CanMessage& msg) const;
+
+ private:
+  const Signal mSignal;
+  const formula mFormula;
+};
+
+}  // namespace android::hardware::automotive::protocan
diff --git a/automotive/can/1.0/tools/libprotocan/include/libprotocan/MessageCounter.h b/automotive/can/1.0/tools/libprotocan/include/libprotocan/MessageCounter.h
new file mode 100644
index 0000000..56113be
--- /dev/null
+++ b/automotive/can/1.0/tools/libprotocan/include/libprotocan/MessageCounter.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/hardware/automotive/can/1.0/types.h>
+#include <libprotocan/Signal.h>
+
+namespace android::hardware::automotive::protocan {
+
+class MessageCounter {
+ public:
+  const Signal::value upperBound;
+
+  MessageCounter(Signal signal);
+
+  /**
+   * Parse CAN message sent by external ECU to determine current counter value.
+   */
+  void read(const can::V1_0::CanMessage& msg);
+
+  /**
+   * States whether current counter value is determined.
+   */
+  bool isReady() const;
+
+  /**
+   * Increment current counter value and set it in a new message.
+   *
+   * Caller must check isReady() at least once before calling this method.
+   */
+  void increment(can::V1_0::CanMessage& msg);
+
+ private:
+  const Signal mSignal;
+
+  std::optional<Signal::value> mCurrent = std::nullopt;
+
+  Signal::value next() const;
+};
+
+}  // namespace android::hardware::automotive::protocan
diff --git a/automotive/can/1.0/tools/libprotocan/include/libprotocan/MessageDef.h b/automotive/can/1.0/tools/libprotocan/include/libprotocan/MessageDef.h
new file mode 100644
index 0000000..79b21e1
--- /dev/null
+++ b/automotive/can/1.0/tools/libprotocan/include/libprotocan/MessageDef.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/hardware/automotive/can/1.0/types.h>
+#include <libprotocan/Checksum.h>
+#include <libprotocan/MessageCounter.h>
+#include <libprotocan/Signal.h>
+
+namespace android::hardware::automotive::protocan {
+
+/**
+ * CAN message definition (not the actual message data).
+ *
+ * Describes static message properties (message ID, signals etc).
+ */
+class MessageDef {
+ public:
+  const can::V1_0::CanMessageId id;
+
+  /**
+   * Create message definition.
+   *
+   * Currently only constant length messages are supported.
+   *
+   * \param id CAN message ID
+   * \param len CAN message length
+   * \param signals CAN signal definitions
+   * \param counter Designated CAN signal definition for message counter, if the message has one
+   * \param checksum Designated CAN signal definition for payload checksum, if the message has one
+   */
+  MessageDef(can::V1_0::CanMessageId id, uint16_t len, std::map<std::string, Signal> signals,
+             std::optional<Signal> counter = std::nullopt,
+             std::optional<Checksum> checksum = std::nullopt);
+
+  const Signal& operator[](const std::string& signalName) const;
+
+  can::V1_0::CanMessage makeDefault() const;
+  MessageCounter makeCounter() const;
+
+  void updateChecksum(can::V1_0::CanMessage& msg) const;
+
+  /**
+   * Validate the message payload is large enough to hold all the signals.
+   */
+  bool validate(const can::V1_0::CanMessage& msg) const;
+
+private:
+  const uint16_t kLen;
+  const std::map<std::string, Signal> kSignals;
+  const std::optional<Signal> kCounter;
+  const std::optional<Checksum> kChecksum;
+};
+
+}  // namespace android::hardware::automotive::protocan
diff --git a/automotive/can/1.0/tools/libprotocan/include/libprotocan/MessageInjector.h b/automotive/can/1.0/tools/libprotocan/include/libprotocan/MessageInjector.h
new file mode 100644
index 0000000..b0ea260
--- /dev/null
+++ b/automotive/can/1.0/tools/libprotocan/include/libprotocan/MessageInjector.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android-base/macros.h>
+#include <android/hardware/automotive/can/1.0/ICanBus.h>
+#include <libprotocan/MessageCounter.h>
+#include <libprotocan/MessageDef.h>
+#include <utils/Mutex.h>
+
+#include <queue>
+
+namespace android::hardware::automotive::protocan {
+
+class MessageInjectorManager;
+
+/**
+ * Injects CAN messages with a counter to an existing system.
+ *
+ * This class is NOT meant to use in production - there should be no need to inject counted CAN
+ * messages where the other sender is also broadcasting them. If this is the case, it may be a sign
+ * your CAN network needs a redesign. This tool is intended for use for testing and demo purposes.
+ */
+class MessageInjector {
+ public:
+  MessageInjector(MessageDef msgDef, std::optional<std::chrono::milliseconds> interMessageDelay);
+
+  void inject(const can::V1_0::CanMessage& msg);
+  void inject(const std::initializer_list<can::V1_0::CanMessage> msgs);
+
+ private:
+  const MessageDef kMsgDef;
+  const std::optional<std::chrono::milliseconds> kInterMessageDelay;
+  MessageCounter mCounter;
+
+  mutable std::mutex mMessagesGuard;
+  std::queue<can::V1_0::CanMessage> mMessages GUARDED_BY(mMessagesGuard);
+
+  void onReceive(can::V1_0::ICanBus& bus, const can::V1_0::CanMessage& msg);
+  void processQueueLocked(can::V1_0::ICanBus& bus);
+
+  friend class MessageInjectorManager;
+
+  DISALLOW_COPY_AND_ASSIGN(MessageInjector);
+};
+
+/**
+ * Routes intercepted messages to MessageInjector instances configured to handle specific CAN
+ * message (CAN message ID). Intercepted messages from other nodes in CAN network are used to read
+ * current counter value in order to spoof the next packet.
+ */
+class MessageInjectorManager {
+ public:
+  MessageInjectorManager(std::initializer_list<std::shared_ptr<MessageInjector>> injectors);
+
+  void onReceive(sp<can::V1_0::ICanBus> bus, const can::V1_0::CanMessage& msg);
+
+ private:
+  std::map<can::V1_0::CanMessageId, std::shared_ptr<MessageInjector>> mInjectors;
+
+  DISALLOW_COPY_AND_ASSIGN(MessageInjectorManager);
+};
+
+}  // namespace android::hardware::automotive::protocan
diff --git a/automotive/can/1.0/tools/libprotocan/include/libprotocan/Signal.h b/automotive/can/1.0/tools/libprotocan/include/libprotocan/Signal.h
new file mode 100644
index 0000000..7c0f119
--- /dev/null
+++ b/automotive/can/1.0/tools/libprotocan/include/libprotocan/Signal.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android-base/macros.h>
+#include <android/hardware/automotive/can/1.0/types.h>
+
+namespace android::hardware::automotive::protocan {
+
+/**
+ * TODO(twasilczyk): right now, only Little Endian signals are supported.
+ */
+class Signal {
+ public:
+  using value = uint64_t;
+
+  const value maxValue;
+
+  Signal(uint16_t start, uint8_t length, value defVal = 0);
+
+  value get(const can::V1_0::CanMessage& msg) const;
+  void set(can::V1_0::CanMessage& msg, value val) const;
+  void setDefault(can::V1_0::CanMessage& msg) const;
+
+ private:
+  const uint16_t kFirstByte;     ///< Index of first byte that holds the signal
+  const uint8_t kFirstBit;       ///< Index of first bit within first byte
+  const uint8_t kFirstByteBits;  ///< How many bits of the first byte belong to the signal
+  const uint16_t kLastByte;      ///< Index of last byte that holds the signal
+  const uint8_t kLastMask;       ///< Bits of the last byte that belong to the signal
+  const uint8_t kFirstMask;      ///< Bits of the first byte that belong to the signal
+
+  const value kDefVal;
+};
+
+}  // namespace android::hardware::automotive::protocan
diff --git a/automotive/can/1.0/tools/libprotocan/tests/Android.bp b/automotive/can/1.0/tools/libprotocan/tests/Android.bp
new file mode 100644
index 0000000..251cc06
--- /dev/null
+++ b/automotive/can/1.0/tools/libprotocan/tests/Android.bp
@@ -0,0 +1,39 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+    // 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: "libprotocan_signal_test",
+    defaults: ["android.hardware.automotive.can@defaults"],
+    vendor: true,
+    gtest: true,
+    srcs: ["libprotocan_signal_test.cpp"],
+    static_libs: [
+        "libprotocan",
+    ],
+    shared_libs: [
+        "android.hardware.automotive.can@1.0",
+        "libhidlbase",
+    ],
+}
diff --git a/automotive/can/1.0/tools/libprotocan/tests/libprotocan_signal_test.cpp b/automotive/can/1.0/tools/libprotocan/tests/libprotocan_signal_test.cpp
new file mode 100644
index 0000000..19c1209
--- /dev/null
+++ b/automotive/can/1.0/tools/libprotocan/tests/libprotocan_signal_test.cpp
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <libprotocan/Signal.h>
+
+#include <gtest/gtest.h>
+
+namespace android::hardware::automotive::protocan::unittest {
+
+TEST(SignalTest, TestGetSingleBytes) {
+  can::V1_0::CanMessage msg = {};
+  msg.payload = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+  for (unsigned i = 0; i < msg.payload.size(); i++) {
+    Signal signal(8 * i, 8);
+    ASSERT_EQ(i, signal.get(msg));
+  }
+}
+
+TEST(SignalTest, TestSetSingleBytes) {
+  std::vector<can::V1_0::CanMessage> msgs = {{}, {}, {}};
+  msgs[0].payload = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+  msgs[1].payload = {0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB};
+  msgs[2].payload = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+  for (unsigned i = 0; i < msgs[0].payload.size(); i++) {
+    Signal signal(8 * i, 8);
+
+    for (auto&& msgOriginal : msgs) {
+      auto msgModified = msgOriginal;
+      signal.set(msgModified, 0xBA);
+
+      auto msgExpected = msgOriginal;
+      msgExpected.payload[i] = 0xBA;
+
+      ASSERT_EQ(msgExpected, msgModified) << "i=" << i;
+    }
+  }
+}
+
+TEST(SignalTest, TestGetStart4) {
+  /* Data generated with Python3:
+   *
+   * from cantools.database.can import *
+   * hex(Message(1, 'm', 4, [Signal('s', 4, 16, byte_order='little_endian')]).
+   *     decode(b'\xde\xad\xbe\xef')['s'])
+   */
+
+  can::V1_0::CanMessage msg = {};
+  msg.payload = {0xDE, 0xAD, 0xBE, 0xEF};
+  can::V1_0::CanMessage msg2 = {};
+  msg2.payload = {0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD};
+
+  Signal s0_4(0, 4);
+  Signal s4_4(4, 4);
+  Signal s4_8(4, 8);
+  Signal s4_16(4, 16);
+  Signal s4_28(4, 28);
+  Signal s12_8(12, 8);
+  Signal s12_12(12, 12);
+  Signal s12_16(12, 16);
+  Signal s12_20(12, 20);
+  Signal s12_32(12, 32);
+
+  ASSERT_EQ(0xEu, s0_4.get(msg));
+  ASSERT_EQ(0xDu, s4_4.get(msg));
+  ASSERT_EQ(0xDDu, s4_8.get(msg));
+  ASSERT_EQ(0xEADDu, s4_16.get(msg));
+  ASSERT_EQ(0xEFBEADDu, s4_28.get(msg));
+  ASSERT_EQ(0xEAu, s12_8.get(msg));
+  ASSERT_EQ(0xBEAu, s12_12.get(msg));
+  ASSERT_EQ(0xFBEAu, s12_16.get(msg));
+  ASSERT_EQ(0xEFBEAu, s12_20.get(msg));
+  ASSERT_EQ(0xDDEEFBEAu, s12_32.get(msg2));
+}
+
+TEST(SignalTest, TestGet64) {
+  /* Data generated with Python3:
+   *
+   * from cantools.database.can import *
+   * hex(Message(1, 'm', 9, [Signal('s', 4, 64, byte_order='little_endian')]).
+   *     decode(b'\xde\xad\xbe\xef\xab\xbc\xcd\xde\xef')['s'])
+   */
+
+  can::V1_0::CanMessage msg = {};
+  msg.payload = {0xDE, 0xAD, 0xBE, 0xEF, 0xAB, 0xBC, 0xCD, 0xDE, 0xEF};
+
+  Signal s0_64(0, 64);
+  Signal s8_64(8, 64);
+  Signal s4_64(4, 64);
+  Signal s1_64(1, 64);
+
+  ASSERT_EQ(0xDECDBCABEFBEADDEu, s0_64.get(msg));
+  ASSERT_EQ(0xEFDECDBCABEFBEADu, s8_64.get(msg));
+  ASSERT_EQ(0xFDECDBCABEFBEADDu, s4_64.get(msg));
+  ASSERT_EQ(0xEF66DE55F7DF56EFu, s1_64.get(msg));
+}
+
+TEST(SignalTest, TestGetAllStarts) {
+  /* Data generated with Python3:
+   *
+   * from cantools.database.can import *
+   * hex(Message(1, 'm', 6, [Signal('s', 0, 20, byte_order='little_endian')]).
+   *     decode(b'\xde\xad\xbe\xef\xde\xad')['s'])
+   */
+
+  std::map<int, Signal::value> shifts = {
+      {0, 0xEADDEu}, {1, 0xF56EFu}, {2, 0xFAB77u}, {3, 0x7D5BBu}, {4, 0xBEADDu},  {5, 0xDF56Eu},
+      {6, 0xEFAB7u}, {7, 0xF7D5Bu}, {8, 0xFBEADu}, {9, 0x7DF56u}, {10, 0xBEFABu}, {11, 0xDF7D5u},
+  };
+
+  can::V1_0::CanMessage msg = {};
+  msg.payload = {0xDE, 0xAD, 0xBE, 0xEF, 0xCC, 0xCC};
+
+  for (auto const& [start, expected] : shifts) {
+    Signal s(start, 20);
+    ASSERT_EQ(expected, s.get(msg)) << "shift of " << start << " failed";
+  }
+}
+
+TEST(SignalTest, TestSetStart4) {
+  /* Data generated with Python3:
+   *
+   * from cantools.database.can import *
+   * so=4 ; sl=8
+   * md = Message(1, 'm', 4, [Signal('a1', 0, so), Signal('a2', so+sl, 32-so-sl),
+   *     Signal('s', so, sl, byte_order='little_endian')])
+   * m = md.decode(b'\xcc\xcc\xcc\xcc')
+   * m['s'] = 0xDE
+   * binascii.hexlify(md.encode(m)).upper()
+   */
+  typedef struct {
+    int start;
+    int length;
+    Signal::value setValue;
+    hidl_vec<uint8_t> payload;
+  } case_t;
+
+  std::vector<case_t> cases = {
+      {0, 4, 0xDu, {0xCD, 0xCC, 0xCC, 0xCC}},       {4, 4, 0xDu, {0xDC, 0xCC, 0xCC, 0xCC}},
+      {4, 8, 0xDEu, {0xEC, 0xCD, 0xCC, 0xCC}},      {4, 16, 0xDEADu, {0xDC, 0xEA, 0xCD, 0xCC}},
+      {4, 24, 0xDEADBEu, {0xEC, 0xDB, 0xEA, 0xCD}}, {4, 28, 0xDEADBEEu, {0xEC, 0xBE, 0xAD, 0xDE}},
+      {12, 8, 0xDEu, {0xCC, 0xEC, 0xCD, 0xCC}},     {12, 12, 0xDEAu, {0xCC, 0xAC, 0xDE, 0xCC}},
+      {12, 16, 0xDEADu, {0xCC, 0xDC, 0xEA, 0xCD}},  {12, 20, 0xDEADBu, {0xCC, 0xBC, 0xAD, 0xDE}},
+  };
+
+  can::V1_0::CanMessage msg = {};
+  msg.payload = {0xCC, 0xCC, 0xCC, 0xCC};
+
+  for (auto const& tcase : cases) {
+    Signal s(tcase.start, tcase.length);
+
+    can::V1_0::CanMessage expectedMsg = {};
+    expectedMsg.payload = tcase.payload;
+
+    can::V1_0::CanMessage editedMsg = msg;
+    s.set(editedMsg, tcase.setValue);
+
+    ASSERT_EQ(expectedMsg, editedMsg) << " set(" << tcase.start << ", " << tcase.length << ")";
+  }
+}
+
+TEST(SignalTest, TestSetAllStarts) {
+  /* Data generated with Python3:
+   * from cantools.database.can import *
+   * import binascii
+   * import textwrap
+   *
+   * length = 20
+   * for start in range(0, 32 - length):
+   *     signals = [Signal('s', start, length, byte_order='little_endian')]
+   *     if start > 0: signals.append(Signal('a', 0, start, byte_order='little_endian'))
+   *     signals.append(Signal('b', start + length, 32 - start - length,
+   *         byte_order='little_endian'))
+   *
+   *     md = Message(1, 'm', 4, signals)
+   *     m = md.decode(b'\xcc\xcc\xcc\xcc')
+   *     m['s'] = 0xDEADB
+   *     out = binascii.hexlify(md.encode(m)).decode('ascii').upper()
+   *     out = ', '.join(['0x{}'.format(v) for v in textwrap.wrap(out, 2)])
+   *     print('{{ {:d}, {{ {:s} }}}},'.format(start, out))
+   */
+
+  std::map<int, hidl_vec<uint8_t>> shifts = {
+      {0, {0xDB, 0xEA, 0xCD, 0xCC}}, {1, {0xB6, 0xD5, 0xDB, 0xCC}},  {2, {0x6C, 0xAB, 0xF7, 0xCC}},
+      {3, {0xDC, 0x56, 0xEF, 0xCC}}, {4, {0xBC, 0xAD, 0xDE, 0xCC}},  {5, {0x6C, 0x5B, 0xBD, 0xCD}},
+      {6, {0xCC, 0xB6, 0x7A, 0xCF}}, {7, {0xCC, 0x6D, 0xF5, 0xCE}},  {8, {0xCC, 0xDB, 0xEA, 0xCD}},
+      {9, {0xCC, 0xB6, 0xD5, 0xDB}}, {10, {0xCC, 0x6C, 0xAB, 0xF7}}, {11, {0xCC, 0xDC, 0x56, 0xEF}},
+  };
+
+  can::V1_0::CanMessage msg = {};
+  msg.payload = {0xCC, 0xCC, 0xCC, 0xCC};
+
+  for (auto const& [start, expectedPayload] : shifts) {
+    Signal s(start, 20);
+
+    can::V1_0::CanMessage expectedMsg = {};
+    expectedMsg.payload = expectedPayload;
+
+    can::V1_0::CanMessage editedMsg = msg;
+    s.set(editedMsg, 0xDEADB);
+
+    ASSERT_EQ(expectedMsg, editedMsg) << "shift of " << start << " failed";
+  }
+}
+
+}  // namespace android::hardware::automotive::protocan::unittest
diff --git a/automotive/evs/OWNERS b/automotive/evs/OWNERS
index 6fc5024..b973e91 100644
--- a/automotive/evs/OWNERS
+++ b/automotive/evs/OWNERS
@@ -1,3 +1,3 @@
+ankitarora@google.com
 changyeon@google.com
-garysungang@google.com
-haoxiangl@google.com
+jwhpryor@google.com
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/VehicleUtils.h b/automotive/vehicle/aidl/impl/utils/common/include/VehicleUtils.h
index 63eb747..49b33d5 100644
--- a/automotive/vehicle/aidl/impl/utils/common/include/VehicleUtils.h
+++ b/automotive/vehicle/aidl/impl/utils/common/include/VehicleUtils.h
@@ -213,7 +213,7 @@
 ::ndk::ScopedAStatus toScopedAStatus(
         const ::android::base::Result<T>& result,
         ::aidl::android::hardware::automotive::vehicle::StatusCode status,
-        std::string additionalErrorMsg) {
+        const std::string& additionalErrorMsg) {
     if (result.ok()) {
         return ::ndk::ScopedAStatus::ok();
     }
@@ -236,10 +236,50 @@
 
 template <class T>
 ::ndk::ScopedAStatus toScopedAStatus(const ::android::base::Result<T>& result,
-                                     std::string additionalErrorMsg) {
+                                     const std::string& additionalErrorMsg) {
     return toScopedAStatus(result, getErrorCode(result), additionalErrorMsg);
 }
 
+// Check whether the value is valid according to config.
+// We check for the following:
+// *  If the type is INT32, {@code value.int32Values} must contain one element.
+// *  If the type is INT32_VEC, {@code value.int32Values} must contain at least one element.
+// *  If the type is INT64, {@code value.int64Values} must contain one element.
+// *  If the type is INT64_VEC, {@code value.int64Values} must contain at least one element.
+// *  If the type is FLOAT, {@code value.floatValues} must contain one element.
+// *  If the type is FLOAT_VEC, {@code value.floatValues} must contain at least one element.
+// *  If the type is MIXED, see checkVendorMixedPropValue.
+::android::base::Result<void> checkPropValue(
+        const ::aidl::android::hardware::automotive::vehicle::VehiclePropValue& value,
+        const ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig* config);
+
+// Check whether the Mixed type value is valid according to config.
+// We check for the following:
+// *  configArray[1] + configArray[2] + configArray[3] must be equal to the number of
+//    {@code value.int32Values} elements.
+// *  configArray[4] + configArray[5] must be equal to the number of {@code value.int64Values}
+//    elements.
+// *  configArray[6] + configArray[7] must be equal to the number of {@code value.floatValues}
+//    elements.
+// *  configArray[8] must be equal to the number of {@code value.byteValues} elements.
+::android::base::Result<void> checkVendorMixedPropValue(
+        const ::aidl::android::hardware::automotive::vehicle::VehiclePropValue& value,
+        const ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig* config);
+
+// Check whether the value is within the configured range.
+// We check for the following types:
+// *  If type is INT32 or INT32_VEC, all {@code value.int32Values} elements must be within
+//    {@code minInt32Value} and {@code maxInt32Value} if either of them is not 0.
+// *  If type is INT64 or INT64_VEC, all {@code value.int64Values} elements must be within
+//    {@code minInt64Value} and {@code maxInt64Value} if either of them is not 0.
+// *  If type is FLOAT or FLOAT_VEC, all {@code value.floatValues} elements must be within
+//    {@code minFloatValues} and {@code maxFloatValues} if either of them is not 0.
+// We don't check other types. If more checks are required, they should be added in VehicleHardware
+// implementation.
+::android::base::Result<void> checkValueRange(
+        const ::aidl::android::hardware::automotive::vehicle::VehiclePropValue& value,
+        const ::aidl::android::hardware::automotive::vehicle::VehicleAreaConfig* config);
+
 }  // namespace vehicle
 }  // namespace automotive
 }  // namespace hardware
diff --git a/automotive/vehicle/aidl/impl/utils/common/src/VehicleUtils.cpp b/automotive/vehicle/aidl/impl/utils/common/src/VehicleUtils.cpp
new file mode 100644
index 0000000..5abde8d
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/utils/common/src/VehicleUtils.cpp
@@ -0,0 +1,210 @@
+/*
+ * 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 "VehicleUtils.h"
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+
+using ::aidl::android::hardware::automotive::vehicle::VehicleAreaConfig;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyGroup;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyType;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropValue;
+using ::android::base::Error;
+using ::android::base::Result;
+using ::ndk::ScopedAStatus;
+
+Result<void> checkPropValue(const VehiclePropValue& value, const VehiclePropConfig* config) {
+    int32_t property = value.prop;
+    VehiclePropertyType type = getPropType(property);
+    switch (type) {
+        case VehiclePropertyType::BOOLEAN:
+            [[fallthrough]];
+        case VehiclePropertyType::INT32:
+            if (value.value.int32Values.size() != 1) {
+                return Error() << "expect 1 int32Values for INT32 type";
+            }
+            break;
+        case VehiclePropertyType::INT32_VEC:
+            if (value.value.int32Values.size() < 1) {
+                return Error() << "expect >=1 int32Values for INT32_VEC type";
+            }
+            break;
+        case VehiclePropertyType::INT64:
+            if (value.value.int64Values.size() != 1) {
+                return Error() << "expect 1 int64Values for INT64 type";
+            }
+            break;
+        case VehiclePropertyType::INT64_VEC:
+            if (value.value.int64Values.size() < 1) {
+                return Error() << "expect >=1 int64Values for INT64_VEC type";
+            }
+            break;
+        case VehiclePropertyType::FLOAT:
+            if (value.value.floatValues.size() != 1) {
+                return Error() << "expect 1 floatValues for FLOAT type";
+            }
+            break;
+        case VehiclePropertyType::FLOAT_VEC:
+            if (value.value.floatValues.size() < 1) {
+                return Error() << "expect >=1 floatValues for FLOAT_VEC type";
+            }
+            break;
+        case VehiclePropertyType::BYTES:
+            // We allow setting an empty bytes array.
+            break;
+        case VehiclePropertyType::STRING:
+            // We allow setting an empty string.
+            break;
+        case VehiclePropertyType::MIXED:
+            if (getPropGroup(property) == VehiclePropertyGroup::VENDOR) {
+                // We only checks vendor mixed properties.
+                return checkVendorMixedPropValue(value, config);
+            }
+            break;
+        default:
+            return Error() << "unknown property type: " << toInt(type);
+    }
+    return {};
+}
+
+Result<void> checkVendorMixedPropValue(const VehiclePropValue& value,
+                                       const VehiclePropConfig* config) {
+    auto configArray = config->configArray;
+    // configArray[0], 1 indicates the property has a String value, we allow the string value to
+    // be empty.
+
+    size_t int32Count = 0;
+    // configArray[1], 1 indicates the property has a Boolean value.
+    if (configArray[1] == 1) {
+        int32Count++;
+    }
+    // configArray[2], 1 indicates the property has an Integer value.
+    if (configArray[2] == 1) {
+        int32Count++;
+    }
+    // configArray[3], the number indicates the size of Integer[] in the property.
+    int32Count += static_cast<size_t>(configArray[3]);
+    size_t int32Size = value.value.int32Values.size();
+    if (int32Size != int32Count) {
+        return Error() << "invalid mixed property, got " << int32Size << " int32Values, expect "
+                       << int32Count;
+    }
+
+    size_t int64Count = 0;
+    // configArray[4], 1 indicates the property has a Long value.
+    if (configArray[4] == 1) {
+        int64Count++;
+    }
+    // configArray[5], the number indicates the size of Long[] in the property.
+    int64Count += static_cast<size_t>(configArray[5]);
+    size_t int64Size = value.value.int64Values.size();
+    if (int64Size != int64Count) {
+        return Error() << "invalid mixed property, got " << int64Size << " int64Values, expect "
+                       << int64Count;
+    }
+
+    size_t floatCount = 0;
+    // configArray[6], 1 indicates the property has a Float value.
+    if (configArray[6] == 1) {
+        floatCount++;
+    }
+    // configArray[7], the number indicates the size of Float[] in the property.
+    floatCount += static_cast<size_t>(configArray[7]);
+    size_t floatSize = value.value.floatValues.size();
+    if (floatSize != floatCount) {
+        return Error() << "invalid mixed property, got " << floatSize << " floatValues, expect "
+                       << floatCount;
+    }
+
+    // configArray[8], the number indicates the size of byte[] in the property.
+    size_t byteSize = value.value.byteValues.size();
+    size_t byteCount = static_cast<size_t>(configArray[8]);
+    if (byteCount != 0 && byteSize != byteCount) {
+        return Error() << "invalid mixed property, got " << byteSize << " byteValues, expect "
+                       << byteCount;
+    }
+    return {};
+}
+
+Result<void> checkValueRange(const VehiclePropValue& value, const VehicleAreaConfig* areaConfig) {
+    if (areaConfig == nullptr) {
+        return {};
+    }
+    int32_t property = value.prop;
+    VehiclePropertyType type = getPropType(property);
+    switch (type) {
+        case VehiclePropertyType::INT32:
+            [[fallthrough]];
+        case VehiclePropertyType::INT32_VEC:
+            if (areaConfig->minInt32Value == 0 && areaConfig->maxInt32Value == 0) {
+                break;
+            }
+            for (int32_t int32Value : value.value.int32Values) {
+                if (int32Value < areaConfig->minInt32Value ||
+                    int32Value > areaConfig->maxInt32Value) {
+                    return Error() << "int32Value: " << int32Value
+                                   << " out of range, min: " << areaConfig->minInt32Value
+                                   << " max: " << areaConfig->maxInt32Value;
+                }
+            }
+            break;
+        case VehiclePropertyType::INT64:
+            [[fallthrough]];
+        case VehiclePropertyType::INT64_VEC:
+            if (areaConfig->minInt64Value == 0 && areaConfig->maxInt64Value == 0) {
+                break;
+            }
+            for (int64_t int64Value : value.value.int64Values) {
+                if (int64Value < areaConfig->minInt64Value ||
+                    int64Value > areaConfig->maxInt64Value) {
+                    return Error() << "int64Value: " << int64Value
+                                   << " out of range, min: " << areaConfig->minInt64Value
+                                   << " max: " << areaConfig->maxInt64Value;
+                }
+            }
+            break;
+        case VehiclePropertyType::FLOAT:
+            [[fallthrough]];
+        case VehiclePropertyType::FLOAT_VEC:
+            if (areaConfig->minFloatValue == 0.f && areaConfig->maxFloatValue == 0.f) {
+                break;
+            }
+            for (float floatValue : value.value.floatValues) {
+                if (floatValue < areaConfig->minFloatValue ||
+                    floatValue > areaConfig->maxFloatValue) {
+                    return Error() << "floatValue: " << floatValue
+                                   << " out of range, min: " << areaConfig->minFloatValue
+                                   << " max: " << areaConfig->maxFloatValue;
+                }
+            }
+            break;
+        default:
+            // We don't check the rest of property types. Additional logic needs to be added if
+            // required in VehicleHardware, e.g. you might want to check the range for mixed
+            // property.
+            break;
+    }
+    return {};
+}
+
+}  // namespace vehicle
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
diff --git a/automotive/vehicle/aidl/impl/utils/common/test/Android.bp b/automotive/vehicle/aidl/impl/utils/common/test/Android.bp
index dd43712..250b331 100644
--- a/automotive/vehicle/aidl/impl/utils/common/test/Android.bp
+++ b/automotive/vehicle/aidl/impl/utils/common/test/Android.bp
@@ -27,6 +27,7 @@
         "libgtest",
         "libgmock",
     ],
+    header_libs: ["VehicleHalTestUtilHeaders"],
     defaults: ["VehicleHalDefaults"],
     test_suites: ["device-tests"],
 }
diff --git a/automotive/vehicle/aidl/impl/utils/common/test/VehicleUtilsTest.cpp b/automotive/vehicle/aidl/impl/utils/common/test/VehicleUtilsTest.cpp
index 131eb3b..de8b26d 100644
--- a/automotive/vehicle/aidl/impl/utils/common/test/VehicleUtilsTest.cpp
+++ b/automotive/vehicle/aidl/impl/utils/common/test/VehicleUtilsTest.cpp
@@ -16,6 +16,7 @@
 
 #include <ConcurrentQueue.h>
 #include <PropertyUtils.h>
+#include <TestPropertyUtils.h>
 #include <VehicleUtils.h>
 
 #include <gtest/gtest.h>
@@ -29,6 +30,8 @@
 namespace automotive {
 namespace vehicle {
 
+namespace {
+
 using ::aidl::android::hardware::automotive::vehicle::VehicleArea;
 using ::aidl::android::hardware::automotive::vehicle::VehicleAreaConfig;
 using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig;
@@ -37,6 +40,427 @@
 using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyType;
 using ::aidl::android::hardware::automotive::vehicle::VehiclePropValue;
 
+struct InvalidPropValueTestCase {
+    std::string name;
+    VehiclePropValue value;
+    bool valid = false;
+    VehiclePropConfig config;
+};
+
+constexpr int32_t int32Prop = toInt(VehicleProperty::INFO_MODEL_YEAR);
+constexpr int32_t int32VecProp = toInt(VehicleProperty::INFO_FUEL_TYPE);
+constexpr int32_t int64Prop = toInt(VehicleProperty::ANDROID_EPOCH_TIME);
+constexpr int32_t int64VecProp = toInt(VehicleProperty::WHEEL_TICK);
+constexpr int32_t floatProp = toInt(VehicleProperty::ENV_OUTSIDE_TEMPERATURE);
+constexpr int32_t floatVecProp = toInt(VehicleProperty::HVAC_TEMPERATURE_VALUE_SUGGESTION);
+
+std::vector<InvalidPropValueTestCase> getInvalidPropValuesTestCases() {
+    return std::vector<InvalidPropValueTestCase>(
+            {
+                    InvalidPropValueTestCase{
+                            .name = "int32_normal",
+                            .value =
+                                    {
+                                            .prop = int32Prop,
+                                            .value.int32Values = {0},
+                                    },
+                            .valid = true,
+                    },
+                    InvalidPropValueTestCase{
+                            .name = "int32_no_value",
+                            .value =
+                                    {
+                                            .prop = int32Prop,
+                                    },
+                    },
+                    InvalidPropValueTestCase{
+                            .name = "int32_more_than_one_value",
+                            .value =
+                                    {
+                                            .prop = int32Prop,
+                                            .value.int32Values = {0, 1},
+                                    },
+                    },
+                    InvalidPropValueTestCase{
+                            .name = "int32_vec_normal",
+                            .value =
+                                    {
+                                            .prop = int32VecProp,
+                                            .value.int32Values = {0, 1},
+                                    },
+                            .valid = true,
+                    },
+                    InvalidPropValueTestCase{
+                            .name = "int32_vec_no_value",
+                            .value =
+                                    {
+                                            .prop = int32VecProp,
+                                    },
+                    },
+                    InvalidPropValueTestCase{
+                            .name = "int64_normal",
+                            .value =
+                                    {
+                                            .prop = int64Prop,
+                                            .value.int64Values = {0},
+                                    },
+                            .valid = true,
+                    },
+                    InvalidPropValueTestCase{
+                            .name = "int64_no_value",
+                            .value =
+                                    {
+                                            .prop = int64Prop,
+                                    },
+                    },
+                    InvalidPropValueTestCase{
+                            .name = "int64_more_than_one_value",
+                            .value =
+                                    {
+                                            .prop = int64Prop,
+                                            .value.int64Values = {0, 1},
+                                    },
+                    },
+                    InvalidPropValueTestCase{
+                            .name = "int64_vec_normal",
+                            .value =
+                                    {
+                                            .prop = int64VecProp,
+                                            .value.int64Values = {0, 1},
+                                    },
+                            .valid = true,
+                    },
+                    InvalidPropValueTestCase{
+                            .name = "int64_vec_no_value",
+                            .value =
+                                    {
+                                            .prop = int64VecProp,
+                                    },
+                    },
+                    InvalidPropValueTestCase{
+                            .name = "float_normal",
+                            .value =
+                                    {
+                                            .prop = floatProp,
+                                            .value.floatValues = {0.0},
+                                    },
+                            .valid = true,
+                    },
+                    InvalidPropValueTestCase{
+                            .name = "float_no_value",
+                            .value =
+                                    {
+                                            .prop = floatProp,
+                                    },
+                    },
+                    InvalidPropValueTestCase{
+                            .name = "float_more_than_one_value",
+                            .value =
+                                    {
+                                            .prop = floatProp,
+                                            .value.floatValues = {0.0, 1.0},
+                                    },
+                    },
+                    InvalidPropValueTestCase{
+                            .name = "float_vec_normal",
+                            .value =
+                                    {
+                                            .prop = floatVecProp,
+                                            .value.floatValues = {0.0, 1.0},
+                                    },
+                            .valid = true,
+                    },
+                    InvalidPropValueTestCase{
+                            .name = "float_vec_no_value",
+                            .value =
+                                    {
+                                            .prop = floatVecProp,
+                                    },
+                    },
+                    InvalidPropValueTestCase{
+                            .name = "mixed_normal",
+                            .value =
+                                    {
+                                            .prop = kMixedTypePropertyForTest,
+                                            // Expect 3 values.
+                                            .value.int32Values = {0, 1, 2},
+                                            // Expect 2 values.
+                                            .value.int64Values = {0, 1},
+                                            // Expect 2 values.
+                                            .value.floatValues = {0.0, 1.0},
+                                            // Expect 1 value.
+                                            .value.byteValues = {static_cast<uint8_t>(0)},
+                                    },
+                            .config =
+                                    {
+                                            .prop = kMixedTypePropertyForTest,
+                                            .configArray = {0, 1, 1, 1, 1, 1, 1, 1, 1},
+                                    },
+                            .valid = true,
+                    },
+                    InvalidPropValueTestCase{
+                            .name = "mixed_mismatch_int32_values_count",
+                            .value =
+                                    {
+                                            .prop = kMixedTypePropertyForTest,
+                                            // Expect 3 values.
+                                            .value.int32Values = {0, 1},
+                                            // Expect 2 values.
+                                            .value.int64Values = {0, 1},
+                                            // Expect 2 values.
+                                            .value.floatValues = {0.0, 1.0},
+                                            // Expect 1 value.
+                                            .value.byteValues = {static_cast<uint8_t>(0)},
+                                    },
+                            .config =
+                                    {
+                                            .prop = kMixedTypePropertyForTest,
+                                            .configArray = {0, 1, 1, 1, 1, 1, 1, 1, 1},
+                                    },
+                    },
+                    InvalidPropValueTestCase{
+                            .name = "mixed_mismatch_int64_values_count",
+                            .value =
+                                    {
+                                            .prop = kMixedTypePropertyForTest,
+                                            // Expect 3 values.
+                                            .value.int32Values = {0, 1, 2},
+                                            // Expect 2 values.
+                                            .value.int64Values = {0},
+                                            // Expect 2 values.
+                                            .value.floatValues = {0.0, 1.0},
+                                            // Expect 1 value.
+                                            .value.byteValues = {static_cast<uint8_t>(0)},
+                                    },
+                            .config =
+                                    {
+                                            .prop = kMixedTypePropertyForTest,
+                                            .configArray = {0, 1, 1, 1, 1, 1, 1, 1, 1},
+                                    },
+                    },
+                    InvalidPropValueTestCase{
+                            .name = "mixed_mismatch_float_values_count",
+                            .value =
+                                    {
+                                            .prop = kMixedTypePropertyForTest,
+                                            // Expect 3 values.
+                                            .value.int32Values = {0, 1, 2},
+                                            // Expect 2 values.
+                                            .value.int64Values = {0, 1},
+                                            // Expect 2 values.
+                                            .value.floatValues = {0.0},
+                                            // Expect 1 value.
+                                            .value.byteValues = {static_cast<uint8_t>(0)},
+                                    },
+                            .config =
+                                    {
+                                            .prop = kMixedTypePropertyForTest,
+                                            .configArray = {0, 1, 1, 1, 1, 1, 1, 1, 1},
+                                    },
+                    },
+                    InvalidPropValueTestCase{
+                            .name = "mixed_mismatch_byte_values_count",
+                            .value =
+                                    {
+                                            .prop = kMixedTypePropertyForTest,
+                                            // Expect 3 values.
+                                            .value.int32Values = {0, 1, 2},
+                                            // Expect 2 values.
+                                            .value.int64Values = {0, 1},
+                                            // Expect 2 values.
+                                            .value.floatValues = {0.0, 1.0},
+                                            // Expect 1 value.
+                                            .value.byteValues = {static_cast<uint8_t>(0),
+                                                                 static_cast<uint8_t>(1)},
+                                    },
+                            .config =
+                                    {
+                                            .prop = kMixedTypePropertyForTest,
+                                            .configArray = {0, 1, 1, 1, 1, 1, 1, 1, 1},
+                                    },
+                    },
+            });
+}
+
+struct InvalidValueRangeTestCase {
+    std::string name;
+    VehiclePropValue value;
+    bool valid = false;
+    VehicleAreaConfig config;
+};
+
+std::vector<InvalidValueRangeTestCase> getInvalidValueRangeTestCases() {
+    return std::vector<InvalidValueRangeTestCase>({{
+            InvalidValueRangeTestCase{
+                    .name = "int32_normal",
+                    .value =
+                            {
+                                    .prop = int32Prop,
+                                    .value.int32Values = {0},
+                            },
+                    .valid = true,
+                    .config =
+                            {
+                                    .minInt32Value = 0,
+                                    .maxInt32Value = 10,
+                            },
+            },
+            InvalidValueRangeTestCase{
+                    .name = "int32_vec_normal",
+                    .value =
+                            {
+                                    .prop = int32VecProp,
+                                    .value.int32Values = {0, 1},
+                            },
+                    .valid = true,
+                    .config =
+                            {
+                                    .minInt32Value = 0,
+                                    .maxInt32Value = 10,
+                            },
+            },
+            InvalidValueRangeTestCase{
+                    .name = "int32_vec_underflow",
+                    .value =
+                            {
+                                    .prop = int32VecProp,
+                                    .value.int32Values = {-1, 1},
+                            },
+
+                    .config =
+                            {
+                                    .minInt32Value = 0,
+                                    .maxInt32Value = 10,
+                            },
+            },
+            InvalidValueRangeTestCase{
+                    .name = "int32_vec_overflow",
+                    .value =
+                            {
+                                    .prop = int32VecProp,
+                                    .value.int32Values = {0, 100},
+                            },
+                    .config =
+                            {
+                                    .minInt32Value = 0,
+                                    .maxInt32Value = 10,
+                            },
+            },
+            InvalidValueRangeTestCase{
+                    .name = "int64_normal",
+                    .value =
+                            {
+                                    .prop = int64Prop,
+                                    .value.int64Values = {0},
+                            },
+                    .valid = true,
+                    .config =
+                            {
+                                    .minInt64Value = 0,
+                                    .maxInt64Value = 10,
+                            },
+            },
+            InvalidValueRangeTestCase{
+                    .name = "int64_vec_normal",
+                    .value =
+                            {
+                                    .prop = int64VecProp,
+                                    .value.int64Values = {0, 1},
+                            },
+                    .valid = true,
+                    .config =
+                            {
+                                    .minInt64Value = 0,
+                                    .maxInt64Value = 10,
+                            },
+            },
+            InvalidValueRangeTestCase{
+                    .name = "int64_vec_underflow",
+                    .value =
+                            {
+                                    .prop = int64VecProp,
+                                    .value.int64Values = {-1, 1},
+                            },
+
+                    .config =
+                            {
+                                    .minInt64Value = 0,
+                                    .maxInt64Value = 10,
+                            },
+            },
+            InvalidValueRangeTestCase{
+                    .name = "int64_vec_overflow",
+                    .value =
+                            {
+                                    .prop = int64VecProp,
+                                    .value.int64Values = {0, 100},
+                            },
+                    .config =
+                            {
+                                    .minInt64Value = 0,
+                                    .maxInt64Value = 10,
+                            },
+            },
+            InvalidValueRangeTestCase{
+                    .name = "float_normal",
+                    .value =
+                            {
+                                    .prop = floatProp,
+                                    .value.floatValues = {0.0},
+                            },
+                    .valid = true,
+                    .config =
+                            {
+                                    .minFloatValue = 0.0,
+                                    .maxFloatValue = 10.0,
+                            },
+            },
+            InvalidValueRangeTestCase{
+                    .name = "float_vec_normal",
+                    .value =
+                            {
+                                    .prop = floatVecProp,
+                                    .value.floatValues = {0.0, 10.0},
+                            },
+                    .valid = true,
+                    .config =
+                            {
+                                    .minFloatValue = 0.0,
+                                    .maxFloatValue = 10.0,
+                            },
+            },
+            InvalidValueRangeTestCase{
+                    .name = "float_vec_underflow",
+                    .value =
+                            {
+                                    .prop = floatVecProp,
+                                    .value.floatValues = {-0.1, 1.1},
+                            },
+
+                    .config =
+                            {
+                                    .minFloatValue = 0.0,
+                                    .maxFloatValue = 10.0,
+                            },
+            },
+            InvalidValueRangeTestCase{
+                    .name = "float_vec_overflow",
+                    .value =
+                            {
+                                    .prop = floatVecProp,
+                                    .value.floatValues = {0.0, 10.1},
+                            },
+                    .config =
+                            {
+                                    .minFloatValue = 0.0,
+                                    .maxFloatValue = 10.0,
+                            },
+            },
+    }});
+}
+
+}  // namespace
+
 TEST(VehicleUtilsTest, testToInt) {
     int areaGlobal = toInt(VehicleArea::GLOBAL);
 
@@ -335,6 +759,40 @@
     t.join();
 }
 
+class InvalidPropValueTest : public testing::TestWithParam<InvalidPropValueTestCase> {};
+
+INSTANTIATE_TEST_SUITE_P(InvalidPropValueTests, InvalidPropValueTest,
+                         testing::ValuesIn(getInvalidPropValuesTestCases()),
+                         [](const testing::TestParamInfo<InvalidPropValueTest::ParamType>& info) {
+                             return info.param.name;
+                         });
+
+TEST_P(InvalidPropValueTest, testCheckPropValue) {
+    InvalidPropValueTestCase tc = GetParam();
+
+    // Config is not used for non-mixed types.
+    auto result = checkPropValue(tc.value, &tc.config);
+
+    ASSERT_EQ(tc.valid, result.ok());
+}
+
+class InvalidValueRangeTest : public testing::TestWithParam<InvalidValueRangeTestCase> {};
+
+INSTANTIATE_TEST_SUITE_P(InvalidValueRangeTests, InvalidValueRangeTest,
+                         testing::ValuesIn(getInvalidValueRangeTestCases()),
+                         [](const testing::TestParamInfo<InvalidValueRangeTest::ParamType>& info) {
+                             return info.param.name;
+                         });
+
+TEST_P(InvalidValueRangeTest, testCheckValueRange) {
+    InvalidValueRangeTestCase tc = GetParam();
+
+    // Config is not used for non-mixed types.
+    auto result = checkValueRange(tc.value, &tc.config);
+
+    ASSERT_EQ(tc.valid, result.ok());
+}
+
 }  // namespace vehicle
 }  // namespace automotive
 }  // namespace hardware
diff --git a/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h b/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h
index 43bdca2..4ee3ee9 100644
--- a/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h
+++ b/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h
@@ -17,10 +17,14 @@
 #ifndef android_hardware_automotive_vehicle_aidl_impl_vhal_include_DefaultVehicleHal_H_
 #define android_hardware_automotive_vehicle_aidl_impl_vhal_include_DefaultVehicleHal_H_
 
+#include "ConnectedClient.h"
+#include "ParcelableUtils.h"
+
 #include <IVehicleHardware.h>
-#include <LargeParcelableBase.h>
 #include <VehicleUtils.h>
 #include <aidl/android/hardware/automotive/vehicle/BnVehicle.h>
+#include <android-base/expected.h>
+#include <android-base/thread_annotations.h>
 #include <android/binder_auto_utils.h>
 
 #include <memory>
@@ -37,59 +41,24 @@
 
 constexpr int INVALID_MEMORY_FD = -1;
 
-template <class T>
-::ndk::ScopedAStatus toScopedAStatus(
-        const ::android::base::Result<T>& result,
-        ::aidl::android::hardware::automotive::vehicle::StatusCode status) {
-    if (result.ok()) {
-        return ::ndk::ScopedAStatus::ok();
-    }
-    return ::ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(toInt(status),
-                                                                     getErrorMsg(result).c_str());
-}
-
-template <class T>
-::ndk::ScopedAStatus toScopedAStatus(const ::android::base::Result<T>& result) {
-    return toScopedAStatus(result, getErrorCode(result));
-}
-
-template <class T1, class T2>
-::ndk::ScopedAStatus vectorToStableLargeParcelable(std::vector<T1>& values, T2* output) {
-    auto result = ::android::automotive::car_binder_lib::LargeParcelableBase::
-            parcelableVectorToStableLargeParcelable(values);
-    if (!result.ok()) {
-        return toScopedAStatus(
-                result, ::aidl::android::hardware::automotive::vehicle::StatusCode::INTERNAL_ERROR);
-    }
-    auto& fd = result.value();
-    if (fd == nullptr) {
-        output->payloads = values;
-    } else {
-        // Move the returned ScopedFileDescriptor pointer to ScopedFileDescriptor value in
-        // 'sharedMemoryFd' field.
-        output->sharedMemoryFd.set(fd->get());
-        *(fd->getR()) = INVALID_MEMORY_FD;
-    }
-    return ::ndk::ScopedAStatus::ok();
-}
-
 }  // namespace defaultvehiclehal_impl
 
 class DefaultVehicleHal final : public ::aidl::android::hardware::automotive::vehicle::BnVehicle {
   public:
+    using CallbackType =
+            std::shared_ptr<::aidl::android::hardware::automotive::vehicle::IVehicleCallback>;
+
     explicit DefaultVehicleHal(std::unique_ptr<IVehicleHardware> hardware);
 
     ::ndk::ScopedAStatus getAllPropConfigs(
             ::aidl::android::hardware::automotive::vehicle::VehiclePropConfigs* returnConfigs)
             override;
     ::ndk::ScopedAStatus getValues(
-            const std::shared_ptr<::aidl::android::hardware::automotive::vehicle::IVehicleCallback>&
-                    callback,
+            const CallbackType& callback,
             const ::aidl::android::hardware::automotive::vehicle::GetValueRequests& requests)
             override;
     ::ndk::ScopedAStatus setValues(
-            const std::shared_ptr<::aidl::android::hardware::automotive::vehicle::IVehicleCallback>&
-                    callback,
+            const CallbackType& callback,
             const ::aidl::android::hardware::automotive::vehicle::SetValueRequests& requests)
             override;
     ::ndk::ScopedAStatus getPropConfigs(
@@ -97,27 +66,49 @@
             ::aidl::android::hardware::automotive::vehicle::VehiclePropConfigs* returnConfigs)
             override;
     ::ndk::ScopedAStatus subscribe(
-            const std::shared_ptr<::aidl::android::hardware::automotive::vehicle::IVehicleCallback>&
-                    callback,
+            const CallbackType& callback,
             const std::vector<::aidl::android::hardware::automotive::vehicle::SubscribeOptions>&
                     options,
             int32_t maxSharedMemoryFileCount) override;
-    ::ndk::ScopedAStatus unsubscribe(
-            const std::shared_ptr<::aidl::android::hardware::automotive::vehicle::IVehicleCallback>&
-                    callback,
-            const std::vector<int32_t>& propIds) override;
-    ::ndk::ScopedAStatus returnSharedMemory(
-            const std::shared_ptr<::aidl::android::hardware::automotive::vehicle::IVehicleCallback>&
-                    callback,
-            int64_t sharedMemoryId) override;
+    ::ndk::ScopedAStatus unsubscribe(const CallbackType& callback,
+                                     const std::vector<int32_t>& propIds) override;
+    ::ndk::ScopedAStatus returnSharedMemory(const CallbackType& callback,
+                                            int64_t sharedMemoryId) override;
 
     IVehicleHardware* getHardware();
 
   private:
+    // friend class for unit testing.
+    friend class DefaultVehicleHalTest;
+
+    using GetValuesClient =
+            GetSetValuesClient<::aidl::android::hardware::automotive::vehicle::GetValueResult,
+                               ::aidl::android::hardware::automotive::vehicle::GetValueResults>;
+    using SetValuesClient =
+            GetSetValuesClient<::aidl::android::hardware::automotive::vehicle::SetValueResult,
+                               ::aidl::android::hardware::automotive::vehicle::SetValueResults>;
+
     const std::unique_ptr<IVehicleHardware> mVehicleHardware;
+
+    // mConfigsByPropId and mConfigFile are only modified during initialization, so no need to
+    // lock guard them.
     std::unordered_map<int32_t, ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig>
             mConfigsByPropId;
     std::unique_ptr<::ndk::ScopedFileDescriptor> mConfigFile;
+
+    std::mutex mLock;
+    std::unordered_map<CallbackType, std::shared_ptr<GetValuesClient>> mGetValuesClients
+            GUARDED_BY(mLock);
+    std::unordered_map<CallbackType, std::shared_ptr<SetValuesClient>> mSetValuesClients
+            GUARDED_BY(mLock);
+
+    template <class T>
+    std::shared_ptr<T> getOrCreateClient(
+            std::unordered_map<CallbackType, std::shared_ptr<T>>* clients,
+            const CallbackType& callback) REQUIRES(mLock);
+
+    ::android::base::Result<void> checkProperty(
+            const ::aidl::android::hardware::automotive::vehicle::VehiclePropValue& propValue);
 };
 
 }  // namespace vehicle
diff --git a/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp b/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
index fd9e331..e98f021 100644
--- a/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
+++ b/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
@@ -21,6 +21,7 @@
 #include <LargeParcelableBase.h>
 #include <VehicleHalTypes.h>
 #include <VehicleUtils.h>
+
 #include <android-base/result.h>
 #include <utils/Log.h>
 
@@ -29,14 +30,24 @@
 namespace automotive {
 namespace vehicle {
 
+using ::aidl::android::hardware::automotive::vehicle::GetValueRequest;
 using ::aidl::android::hardware::automotive::vehicle::GetValueRequests;
+using ::aidl::android::hardware::automotive::vehicle::GetValueResult;
+using ::aidl::android::hardware::automotive::vehicle::GetValueResults;
 using ::aidl::android::hardware::automotive::vehicle::IVehicleCallback;
+using ::aidl::android::hardware::automotive::vehicle::SetValueRequest;
 using ::aidl::android::hardware::automotive::vehicle::SetValueRequests;
+using ::aidl::android::hardware::automotive::vehicle::SetValueResult;
+using ::aidl::android::hardware::automotive::vehicle::SetValueResults;
 using ::aidl::android::hardware::automotive::vehicle::StatusCode;
 using ::aidl::android::hardware::automotive::vehicle::SubscribeOptions;
+using ::aidl::android::hardware::automotive::vehicle::VehicleAreaConfig;
 using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig;
 using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfigs;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropValue;
 using ::android::automotive::car_binder_lib::LargeParcelableBase;
+using ::android::base::Error;
+using ::android::base::expected;
 using ::android::base::Result;
 using ::ndk::ScopedAStatus;
 
@@ -70,15 +81,141 @@
     return ScopedAStatus::ok();
 }
 
-ScopedAStatus DefaultVehicleHal::getValues(const std::shared_ptr<IVehicleCallback>&,
-                                           const GetValueRequests&) {
-    // TODO(b/200737967): implement this.
+template <class T>
+std::shared_ptr<T> DefaultVehicleHal::getOrCreateClient(
+        std::unordered_map<CallbackType, std::shared_ptr<T>>* clients,
+        const CallbackType& callback) {
+    if (clients->find(callback) == clients->end()) {
+        // TODO(b/204943359): Remove client from clients when linkToDeath is implemented.
+        (*clients)[callback] = std::make_shared<T>(callback);
+    }
+    return (*clients)[callback];
+}
+
+template std::shared_ptr<DefaultVehicleHal::GetValuesClient>
+DefaultVehicleHal::getOrCreateClient<DefaultVehicleHal::GetValuesClient>(
+        std::unordered_map<CallbackType, std::shared_ptr<GetValuesClient>>* clients,
+        const CallbackType& callback);
+
+template std::shared_ptr<DefaultVehicleHal::SetValuesClient>
+DefaultVehicleHal::getOrCreateClient<DefaultVehicleHal::SetValuesClient>(
+        std::unordered_map<CallbackType, std::shared_ptr<SetValuesClient>>* clients,
+        const CallbackType& callback);
+
+Result<void> DefaultVehicleHal::checkProperty(const VehiclePropValue& propValue) {
+    int32_t propId = propValue.prop;
+    auto it = mConfigsByPropId.find(propId);
+    if (it == mConfigsByPropId.end()) {
+        return Error() << "no config for property, ID: " << propId;
+    }
+    const VehiclePropConfig& config = it->second;
+    const VehicleAreaConfig* areaConfig = getAreaConfig(propValue, config);
+    if (!isGlobalProp(propId) && areaConfig == nullptr) {
+        // Ignore areaId for global property. For non global property, check whether areaId is
+        // allowed. areaId must appear in areaConfig.
+        return Error() << "invalid area ID: " << propValue.areaId << " for prop ID: " << propId
+                       << ", not listed in config";
+    }
+    if (auto result = checkPropValue(propValue, &config); !result.ok()) {
+        return Error() << "invalid property value: " << propValue.toString()
+                       << ", error: " << result.error().message();
+    }
+    if (auto result = checkValueRange(propValue, areaConfig); !result.ok()) {
+        return Error() << "property value out of range: " << propValue.toString()
+                       << ", error: " << result.error().message();
+    }
+    return {};
+}
+
+ScopedAStatus DefaultVehicleHal::getValues(const CallbackType& callback,
+                                           const GetValueRequests& requests) {
+    // TODO(b/203713317): check for duplicate properties and duplicate request IDs.
+
+    const std::vector<GetValueRequest>* getValueRequests;
+    // Define deserializedResults here because we need it to have the same lifetime as
+    // getValueRequests.
+    expected<std::vector<GetValueRequest>, ScopedAStatus> deserializedResults;
+    if (!requests.payloads.empty()) {
+        getValueRequests = &requests.payloads;
+    } else {
+        deserializedResults = stableLargeParcelableToVector<GetValueRequest>(requests);
+        if (!deserializedResults.ok()) {
+            ALOGE("failed to parse getValues requests");
+            return std::move(deserializedResults.error());
+        }
+        getValueRequests = &deserializedResults.value();
+    }
+
+    std::shared_ptr<GetValuesClient> client;
+    {
+        std::scoped_lock<std::mutex> lockGuard(mLock);
+        client = getOrCreateClient(&mGetValuesClients, callback);
+    }
+
+    if (StatusCode status =
+                mVehicleHardware->getValues(client->getResultCallback(), *getValueRequests);
+        status != StatusCode::OK) {
+        return ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                toInt(status), "failed to get value from VehicleHardware");
+    }
+
     return ScopedAStatus::ok();
 }
 
-ScopedAStatus DefaultVehicleHal::setValues(const std::shared_ptr<IVehicleCallback>&,
-                                           const SetValueRequests&) {
-    // TODO(b/200737967): implement this.
+ScopedAStatus DefaultVehicleHal::setValues(const CallbackType& callback,
+                                           const SetValueRequests& requests) {
+    // TODO(b/203713317): check for duplicate properties and duplicate request IDs.
+
+    const std::vector<SetValueRequest>* setValueRequests;
+    // Define deserializedResults here because we need it to have the same lifetime as
+    // setValueRequests.
+    expected<std::vector<SetValueRequest>, ScopedAStatus> deserializedResults;
+    if (!requests.payloads.empty()) {
+        setValueRequests = &requests.payloads;
+    } else {
+        deserializedResults = stableLargeParcelableToVector<SetValueRequest>(requests);
+        if (!deserializedResults.ok()) {
+            ALOGE("failed to parse setValues requests");
+            return std::move(deserializedResults.error());
+        }
+        setValueRequests = &deserializedResults.value();
+    }
+
+    // A list of failed result we already know before sending to hardware.
+    std::vector<SetValueResult> failedResults;
+    // The list of requests that we would send to hardware.
+    std::vector<SetValueRequest> hardwareRequests;
+
+    for (auto& request : *setValueRequests) {
+        int64_t requestId = request.requestId;
+        if (auto result = checkProperty(request.value); !result.ok()) {
+            ALOGW("property not valid: %s", result.error().message().c_str());
+            failedResults.push_back(SetValueResult{
+                    .requestId = requestId,
+                    .status = StatusCode::INVALID_ARG,
+            });
+            continue;
+        }
+        hardwareRequests.push_back(request);
+    }
+
+    std::shared_ptr<SetValuesClient> client;
+    {
+        std::scoped_lock<std::mutex> lockGuard(mLock);
+        client = getOrCreateClient(&mSetValuesClients, callback);
+    }
+
+    if (!failedResults.empty()) {
+        client->sendResults(failedResults);
+    }
+
+    if (StatusCode status =
+                mVehicleHardware->setValues(client->getResultCallback(), hardwareRequests);
+        status != StatusCode::OK) {
+        return ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                toInt(status), "failed to set value to VehicleHardware");
+    }
+
     return ScopedAStatus::ok();
 }
 
@@ -90,23 +227,21 @@
             configs.push_back(mConfigsByPropId[prop]);
         }
     }
-    return defaultvehiclehal_impl::vectorToStableLargeParcelable(configs, output);
+    return vectorToStableLargeParcelable(std::move(configs), output);
 }
 
-ScopedAStatus DefaultVehicleHal::subscribe(const std::shared_ptr<IVehicleCallback>&,
+ScopedAStatus DefaultVehicleHal::subscribe(const CallbackType&,
                                            const std::vector<SubscribeOptions>&, int32_t) {
     // TODO(b/200737967): implement this.
     return ScopedAStatus::ok();
 }
 
-ScopedAStatus DefaultVehicleHal::unsubscribe(const std::shared_ptr<IVehicleCallback>&,
-                                             const std::vector<int32_t>&) {
+ScopedAStatus DefaultVehicleHal::unsubscribe(const CallbackType&, const std::vector<int32_t>&) {
     // TODO(b/200737967): implement this.
     return ScopedAStatus::ok();
 }
 
-ScopedAStatus DefaultVehicleHal::returnSharedMemory(const std::shared_ptr<IVehicleCallback>&,
-                                                    int64_t) {
+ScopedAStatus DefaultVehicleHal::returnSharedMemory(const CallbackType&, int64_t) {
     // TODO(b/200737967): implement this.
     return ScopedAStatus::ok();
 }
diff --git a/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp b/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp
index 2b5ca70..8934a7b 100644
--- a/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp
+++ b/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp
@@ -15,17 +15,24 @@
  */
 
 #include "DefaultVehicleHal.h"
+#include "MockVehicleCallback.h"
 
 #include <IVehicleHardware.h>
 #include <LargeParcelableBase.h>
 #include <aidl/android/hardware/automotive/vehicle/IVehicle.h>
-#include <android-base/thread_annotations.h>
+#include <aidl/android/hardware/automotive/vehicle/IVehicleCallback.h>
 
+#include <android-base/thread_annotations.h>
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
+#include <utils/Log.h>
 
+#include <list>
 #include <memory>
+#include <mutex>
 #include <optional>
+#include <thread>
+#include <unordered_map>
 #include <vector>
 
 namespace android {
@@ -36,38 +43,77 @@
 namespace {
 
 using ::aidl::android::hardware::automotive::vehicle::GetValueRequest;
+using ::aidl::android::hardware::automotive::vehicle::GetValueRequests;
 using ::aidl::android::hardware::automotive::vehicle::GetValueResult;
+using ::aidl::android::hardware::automotive::vehicle::GetValueResults;
 using ::aidl::android::hardware::automotive::vehicle::IVehicle;
+using ::aidl::android::hardware::automotive::vehicle::IVehicleCallback;
 using ::aidl::android::hardware::automotive::vehicle::SetValueRequest;
+using ::aidl::android::hardware::automotive::vehicle::SetValueRequests;
 using ::aidl::android::hardware::automotive::vehicle::SetValueResult;
+using ::aidl::android::hardware::automotive::vehicle::SetValueResults;
 using ::aidl::android::hardware::automotive::vehicle::StatusCode;
+using ::aidl::android::hardware::automotive::vehicle::VehicleAreaWindow;
 using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig;
 using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfigs;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropErrors;
 using ::aidl::android::hardware::automotive::vehicle::VehiclePropValue;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropValues;
 
 using ::android::automotive::car_binder_lib::LargeParcelableBase;
 using ::android::base::Result;
 
+using ::ndk::ScopedAStatus;
+using ::ndk::ScopedFileDescriptor;
+
 using ::testing::Eq;
 using ::testing::WhenSortedBy;
 
+constexpr int32_t INVALID_PROP_ID = 0;
+// VehiclePropertyGroup:SYSTEM,VehicleArea:WINDOW,VehiclePropertyType:INT32
+constexpr int32_t INT32_WINDOW_PROP = 10001 + 0x10000000 + 0x03000000 + 0x00400000;
+
+template <class T>
+std::optional<T> pop(std::list<T>& items) {
+    if (items.size() > 0) {
+        auto item = std::move(items.front());
+        items.pop_front();
+        return item;
+    }
+    return std::nullopt;
+}
+
+int32_t testInt32VecProp(size_t i) {
+    // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
+    return static_cast<int32_t>(i) + 0x10000000 + 0x01000000 + 0x00410000;
+}
+
 class MockVehicleHardware final : public IVehicleHardware {
   public:
+    ~MockVehicleHardware() {
+        std::scoped_lock<std::mutex> lockGuard(mLock);
+        for (auto& thread : mThreads) {
+            thread.join();
+        }
+    }
+
     std::vector<VehiclePropConfig> getAllPropertyConfigs() const override {
         std::scoped_lock<std::mutex> lockGuard(mLock);
         return mPropertyConfigs;
     }
 
-    StatusCode setValues(std::shared_ptr<const SetValuesCallback>,
-                         const std::vector<SetValueRequest>&) override {
-        // TODO(b/200737967): mock this.
-        return StatusCode::OK;
+    StatusCode setValues(std::shared_ptr<const SetValuesCallback> callback,
+                         const std::vector<SetValueRequest>& requests) override {
+        std::scoped_lock<std::mutex> lockGuard(mLock);
+        return handleRequests(__func__, callback, requests, &mSetValueRequests,
+                              &mSetValueResponses);
     }
 
-    StatusCode getValues(std::shared_ptr<const GetValuesCallback>,
-                         const std::vector<GetValueRequest>&) const override {
-        // TODO(b/200737967): mock this.
-        return StatusCode::OK;
+    StatusCode getValues(std::shared_ptr<const GetValuesCallback> callback,
+                         const std::vector<GetValueRequest>& requests) const override {
+        std::scoped_lock<std::mutex> lockGuard(mLock);
+        return handleRequests(__func__, callback, requests, &mGetValueRequests,
+                              &mGetValueResponses);
     }
 
     DumpResult dump(const std::vector<std::string>&) override {
@@ -94,20 +140,316 @@
         mPropertyConfigs = configs;
     }
 
+    void addGetValueResponses(const std::vector<GetValueResult>& responses) {
+        std::scoped_lock<std::mutex> lockGuard(mLock);
+        mGetValueResponses.push_back(responses);
+    }
+
+    void addSetValueResponses(const std::vector<SetValueResult>& responses) {
+        std::scoped_lock<std::mutex> lockGuard(mLock);
+        mSetValueResponses.push_back(responses);
+    }
+
+    std::vector<GetValueRequest> nextGetValueRequests() {
+        std::scoped_lock<std::mutex> lockGuard(mLock);
+        std::optional<std::vector<GetValueRequest>> request = pop(mGetValueRequests);
+        if (!request.has_value()) {
+            return std::vector<GetValueRequest>();
+        }
+        return std::move(request.value());
+    }
+
+    std::vector<SetValueRequest> nextSetValueRequests() {
+        std::scoped_lock<std::mutex> lockGuard(mLock);
+        std::optional<std::vector<SetValueRequest>> request = pop(mSetValueRequests);
+        if (!request.has_value()) {
+            return std::vector<SetValueRequest>();
+        }
+        return std::move(request.value());
+    }
+
+    void setStatus(const char* functionName, StatusCode status) {
+        std::scoped_lock<std::mutex> lockGuard(mLock);
+        mStatusByFunctions[functionName] = status;
+    }
+
+    void setSleepTime(int64_t timeInNano) {
+        std::scoped_lock<std::mutex> lockGuard(mLock);
+        mSleepTime = timeInNano;
+    }
+
   private:
     mutable std::mutex mLock;
     std::vector<VehiclePropConfig> mPropertyConfigs GUARDED_BY(mLock);
+    mutable std::list<std::vector<GetValueRequest>> mGetValueRequests GUARDED_BY(mLock);
+    mutable std::list<std::vector<GetValueResult>> mGetValueResponses GUARDED_BY(mLock);
+    mutable std::list<std::vector<SetValueRequest>> mSetValueRequests GUARDED_BY(mLock);
+    mutable std::list<std::vector<SetValueResult>> mSetValueResponses GUARDED_BY(mLock);
+    std::unordered_map<const char*, StatusCode> mStatusByFunctions GUARDED_BY(mLock);
+    int64_t mSleepTime GUARDED_BY(mLock) = 0;
+    mutable std::vector<std::thread> mThreads GUARDED_BY(mLock);
+
+    template <class ResultType>
+    StatusCode returnResponse(
+            std::shared_ptr<const std::function<void(std::vector<ResultType>)>> callback,
+            std::list<std::vector<ResultType>>* storedResponses) const;
+
+    template <class RequestType, class ResultType>
+    StatusCode handleRequests(
+            const char* functionName,
+            std::shared_ptr<const std::function<void(std::vector<ResultType>)>> callback,
+            const std::vector<RequestType>& requests,
+            std::list<std::vector<RequestType>>* storedRequests,
+            std::list<std::vector<ResultType>>* storedResponses) const REQUIRES(mLock);
 };
 
+template <class ResultType>
+StatusCode MockVehicleHardware::returnResponse(
+        std::shared_ptr<const std::function<void(std::vector<ResultType>)>> callback,
+        std::list<std::vector<ResultType>>* storedResponses) const {
+    if (storedResponses->size() > 0) {
+        (*callback)(std::move(storedResponses->front()));
+        storedResponses->pop_front();
+        return StatusCode::OK;
+    } else {
+        ALOGE("no more response");
+        return StatusCode::INTERNAL_ERROR;
+    }
+}
+
+template StatusCode MockVehicleHardware::returnResponse<GetValueResult>(
+        std::shared_ptr<const std::function<void(std::vector<GetValueResult>)>> callback,
+        std::list<std::vector<GetValueResult>>* storedResponses) const;
+
+template StatusCode MockVehicleHardware::returnResponse<SetValueResult>(
+        std::shared_ptr<const std::function<void(std::vector<SetValueResult>)>> callback,
+        std::list<std::vector<SetValueResult>>* storedResponses) const;
+
+template <class RequestType, class ResultType>
+StatusCode MockVehicleHardware::handleRequests(
+        const char* functionName,
+        std::shared_ptr<const std::function<void(std::vector<ResultType>)>> callback,
+        const std::vector<RequestType>& requests,
+        std::list<std::vector<RequestType>>* storedRequests,
+        std::list<std::vector<ResultType>>* storedResponses) const {
+    storedRequests->push_back(requests);
+    if (auto it = mStatusByFunctions.find(functionName); it != mStatusByFunctions.end()) {
+        if (StatusCode status = it->second; status != StatusCode::OK) {
+            return status;
+        }
+    }
+
+    if (mSleepTime != 0) {
+        int64_t sleepTime = mSleepTime;
+        mThreads.emplace_back([this, callback, sleepTime, storedResponses]() {
+            std::this_thread::sleep_for(std::chrono::nanoseconds(sleepTime));
+            returnResponse(callback, storedResponses);
+        });
+        return StatusCode::OK;
+
+    } else {
+        return returnResponse(callback, storedResponses);
+    }
+}
+
+template StatusCode MockVehicleHardware::handleRequests<GetValueRequest, GetValueResult>(
+        const char* functionName,
+        std::shared_ptr<const std::function<void(std::vector<GetValueResult>)>> callback,
+        const std::vector<GetValueRequest>& requests,
+        std::list<std::vector<GetValueRequest>>* storedRequests,
+        std::list<std::vector<GetValueResult>>* storedResponses) const;
+
+template StatusCode MockVehicleHardware::handleRequests<SetValueRequest, SetValueResult>(
+        const char* functionName,
+        std::shared_ptr<const std::function<void(std::vector<SetValueResult>)>> callback,
+        const std::vector<SetValueRequest>& requests,
+        std::list<std::vector<SetValueRequest>>* storedRequests,
+        std::list<std::vector<SetValueResult>>* storedResponses) const;
+
 struct PropConfigCmp {
     bool operator()(const VehiclePropConfig& a, const VehiclePropConfig& b) const {
         return (a.prop < b.prop);
     }
 } propConfigCmp;
 
+struct SetValuesInvalidRequestTestCase {
+    std::string name;
+    VehiclePropValue request;
+    StatusCode expectedStatus;
+};
+
+std::vector<SetValuesInvalidRequestTestCase> getSetValuesInvalidRequestTestCases() {
+    return {{
+                    .name = "config_not_found",
+                    .request =
+                            {
+                                    // No config for INVALID_PROP_ID.
+                                    .prop = INVALID_PROP_ID,
+                            },
+                    .expectedStatus = StatusCode::INVALID_ARG,
+            },
+            {
+                    .name = "invalid_prop_value",
+                    .request =
+                            {
+                                    .prop = testInt32VecProp(0),
+                                    // No int32Values for INT32_VEC property.
+                                    .value.int32Values = {},
+                            },
+                    .expectedStatus = StatusCode::INVALID_ARG,
+            },
+            {
+                    .name = "value_out_of_range",
+                    .request =
+                            {
+                                    .prop = testInt32VecProp(0),
+                                    // We configured the range to be 0-100.
+                                    .value.int32Values = {0, -1},
+                            },
+                    .expectedStatus = StatusCode::INVALID_ARG,
+            },
+            {
+                    .name = "invalid_area",
+                    .request =
+                            {
+                                    .prop = INT32_WINDOW_PROP,
+                                    .value.int32Values = {0},
+                                    // Only ROW_1_LEFT is allowed.
+                                    .areaId = toInt(VehicleAreaWindow::ROW_1_RIGHT),
+                            },
+                    .expectedStatus = StatusCode::INVALID_ARG,
+            }};
+}
+
 }  // namespace
 
-TEST(DefaultVehicleHalTest, testGetAllPropConfigsSmall) {
+class DefaultVehicleHalTest : public ::testing::Test {
+  public:
+    void SetUp() override {
+        auto hardware = std::make_unique<MockVehicleHardware>();
+        std::vector<VehiclePropConfig> testConfigs;
+        for (size_t i = 0; i < 10000; i++) {
+            testConfigs.push_back(VehiclePropConfig{
+                    .prop = testInt32VecProp(i),
+                    .areaConfigs =
+                            {
+                                    {
+                                            .areaId = 0,
+                                            .minInt32Value = 0,
+                                            .maxInt32Value = 100,
+                                    },
+                            },
+            });
+        }
+        testConfigs.push_back(
+                VehiclePropConfig{.prop = INT32_WINDOW_PROP,
+                                  .areaConfigs = {{
+                                          .areaId = toInt(VehicleAreaWindow::ROW_1_LEFT),
+                                          .minInt32Value = 0,
+                                          .maxInt32Value = 100,
+                                  }}});
+        hardware->setPropertyConfigs(testConfigs);
+        mHardwarePtr = hardware.get();
+        mVhal = ndk::SharedRefBase::make<DefaultVehicleHal>(std::move(hardware));
+        mVhalClient = IVehicle::fromBinder(mVhal->asBinder());
+        mCallback = ndk::SharedRefBase::make<MockVehicleCallback>();
+        mCallbackClient = IVehicleCallback::fromBinder(mCallback->asBinder());
+    }
+
+    MockVehicleHardware* getHardware() { return mHardwarePtr; }
+
+    std::shared_ptr<IVehicle> getClient() { return mVhal; }
+
+    std::shared_ptr<IVehicleCallback> getCallbackClient() { return mCallbackClient; }
+
+    MockVehicleCallback* getCallback() { return mCallback.get(); }
+
+    static Result<void> getValuesTestCases(size_t size, GetValueRequests& requests,
+                                           std::vector<GetValueResult>& expectedResults,
+                                           std::vector<GetValueRequest>& expectedHardwareRequests) {
+        expectedHardwareRequests.clear();
+        for (size_t i = 0; i < size; i++) {
+            int64_t requestId = static_cast<int64_t>(i);
+            int32_t propId = testInt32VecProp(i);
+            expectedHardwareRequests.push_back(GetValueRequest{
+                    .prop =
+                            VehiclePropValue{
+                                    .prop = propId,
+                            },
+                    .requestId = requestId,
+            });
+            expectedResults.push_back(GetValueResult{
+                    .requestId = requestId,
+                    .status = StatusCode::OK,
+                    .prop =
+                            VehiclePropValue{
+                                    .prop = propId,
+                                    .value.int32Values = {1, 2, 3, 4},
+                            },
+            });
+        }
+
+        auto result = LargeParcelableBase::parcelableVectorToStableLargeParcelable(
+                expectedHardwareRequests);
+        if (!result.ok()) {
+            return result.error();
+        }
+        if (result.value() == nullptr) {
+            requests.payloads = expectedHardwareRequests;
+        } else {
+            requests.sharedMemoryFd = std::move(*result.value());
+        }
+        return {};
+    }
+
+    static Result<void> setValuesTestCases(size_t size, SetValueRequests& requests,
+                                           std::vector<SetValueResult>& expectedResults,
+                                           std::vector<SetValueRequest>& expectedHardwareRequests) {
+        expectedHardwareRequests.clear();
+        for (size_t i = 0; i < size; i++) {
+            int64_t requestId = static_cast<int64_t>(i);
+            int32_t propId = testInt32VecProp(i);
+            expectedHardwareRequests.push_back(SetValueRequest{
+                    .value =
+                            VehiclePropValue{
+                                    .prop = propId,
+                                    .value.int32Values = {1, 2, 3, 4},
+                            },
+                    .requestId = requestId,
+            });
+            expectedResults.push_back(SetValueResult{
+                    .requestId = requestId,
+                    .status = StatusCode::OK,
+            });
+        }
+
+        auto result = LargeParcelableBase::parcelableVectorToStableLargeParcelable(
+                expectedHardwareRequests);
+        if (!result.ok()) {
+            return result.error();
+        }
+        if (result.value() == nullptr) {
+            requests.payloads = expectedHardwareRequests;
+        } else {
+            requests.sharedMemoryFd = std::move(*result.value());
+        }
+        return {};
+    }
+
+    size_t countClients() {
+        std::scoped_lock<std::mutex> lockGuard(mVhal->mLock);
+        return mVhal->mGetValuesClients.size() + mVhal->mSetValuesClients.size();
+    }
+
+  private:
+    std::shared_ptr<DefaultVehicleHal> mVhal;
+    std::shared_ptr<IVehicle> mVhalClient;
+    MockVehicleHardware* mHardwarePtr;
+    std::shared_ptr<MockVehicleCallback> mCallback;
+    std::shared_ptr<IVehicleCallback> mCallbackClient;
+};
+
+TEST_F(DefaultVehicleHalTest, testGetAllPropConfigsSmall) {
     auto testConfigs = std::vector<VehiclePropConfig>({
             VehiclePropConfig{
                     .prop = 1,
@@ -125,14 +467,14 @@
     VehiclePropConfigs output;
     auto status = client->getAllPropConfigs(&output);
 
-    ASSERT_TRUE(status.isOk());
+    ASSERT_TRUE(status.isOk()) << "getAllPropConfigs failed: " << status.getMessage();
     ASSERT_THAT(output.payloads, WhenSortedBy(propConfigCmp, Eq(testConfigs)));
 }
 
-TEST(DefaultVehicleHalTest, testGetAllPropConfigsLarge) {
+TEST_F(DefaultVehicleHalTest, testGetAllPropConfigsLarge) {
     std::vector<VehiclePropConfig> testConfigs;
-    // 10000 VehiclePropConfig exceeds 4k memory limit, so it would be sent through shared memory.
-    for (size_t i = 0; i < 10000; i++) {
+    // 5000 VehiclePropConfig exceeds 4k memory limit, so it would be sent through shared memory.
+    for (size_t i = 0; i < 5000; i++) {
         testConfigs.push_back(VehiclePropConfig{
                 .prop = static_cast<int32_t>(i),
         });
@@ -146,16 +488,202 @@
     VehiclePropConfigs output;
     auto status = client->getAllPropConfigs(&output);
 
-    ASSERT_TRUE(status.isOk());
+    ASSERT_TRUE(status.isOk()) << "getAllPropConfigs failed: " << status.getMessage();
     ASSERT_TRUE(output.payloads.empty());
     Result<std::optional<std::vector<VehiclePropConfig>>> result =
             LargeParcelableBase::stableLargeParcelableToParcelableVector<VehiclePropConfig>(
                     output.sharedMemoryFd);
-    ASSERT_TRUE(result.ok());
-    ASSERT_TRUE(result.value().has_value());
+    ASSERT_TRUE(result.ok()) << "failed to parse result shared memory file: "
+                             << result.error().message();
+    ASSERT_TRUE(result.value().has_value()) << "empty parsed value";
     ASSERT_EQ(result.value().value(), testConfigs);
 }
 
+TEST_F(DefaultVehicleHalTest, testGetValuesSmall) {
+    GetValueRequests requests;
+    std::vector<GetValueResult> expectedResults;
+    std::vector<GetValueRequest> expectedHardwareRequests;
+
+    ASSERT_TRUE(getValuesTestCases(10, requests, expectedResults, expectedHardwareRequests).ok());
+
+    getHardware()->addGetValueResponses(expectedResults);
+
+    auto status = getClient()->getValues(getCallbackClient(), requests);
+
+    ASSERT_TRUE(status.isOk()) << "getValues failed: " << status.getMessage();
+
+    EXPECT_EQ(getHardware()->nextGetValueRequests(), expectedHardwareRequests)
+            << "requests to hardware mismatch";
+
+    auto maybeGetValueResults = getCallback()->nextGetValueResults();
+    ASSERT_TRUE(maybeGetValueResults.has_value()) << "no results in callback";
+    EXPECT_EQ(maybeGetValueResults.value().payloads, expectedResults) << "results mismatch";
+    EXPECT_EQ(countClients(), static_cast<size_t>(1));
+}
+
+TEST_F(DefaultVehicleHalTest, testGetValuesLarge) {
+    GetValueRequests requests;
+    std::vector<GetValueResult> expectedResults;
+    std::vector<GetValueRequest> expectedHardwareRequests;
+
+    ASSERT_TRUE(getValuesTestCases(5000, requests, expectedResults, expectedHardwareRequests).ok())
+            << "requests to hardware mismatch";
+    ;
+
+    getHardware()->addGetValueResponses(expectedResults);
+
+    auto status = getClient()->getValues(getCallbackClient(), requests);
+
+    ASSERT_TRUE(status.isOk()) << "getValues failed: " << status.getMessage();
+
+    EXPECT_EQ(getHardware()->nextGetValueRequests(), expectedHardwareRequests);
+
+    auto maybeGetValueResults = getCallback()->nextGetValueResults();
+    ASSERT_TRUE(maybeGetValueResults.has_value()) << "no results in callback";
+    const GetValueResults& getValueResults = maybeGetValueResults.value();
+    ASSERT_TRUE(getValueResults.payloads.empty())
+            << "payload should be empty, shared memory file should be used";
+
+    auto result = LargeParcelableBase::stableLargeParcelableToParcelableVector<GetValueResult>(
+            getValueResults.sharedMemoryFd);
+    ASSERT_TRUE(result.ok()) << "failed to parse shared memory file";
+    ASSERT_TRUE(result.value().has_value()) << "no parsed value";
+    ASSERT_EQ(result.value().value(), expectedResults) << "results mismatch";
+    EXPECT_EQ(countClients(), static_cast<size_t>(1));
+}
+
+TEST_F(DefaultVehicleHalTest, testGetValuesErrorFromHardware) {
+    GetValueRequests requests;
+    std::vector<GetValueResult> expectedResults;
+    std::vector<GetValueRequest> expectedHardwareRequests;
+
+    ASSERT_TRUE(getValuesTestCases(10, requests, expectedResults, expectedHardwareRequests).ok());
+
+    getHardware()->setStatus("getValues", StatusCode::INTERNAL_ERROR);
+
+    auto status = getClient()->getValues(getCallbackClient(), requests);
+
+    ASSERT_FALSE(status.isOk()) << "expect getValues to fail when hardware returns error";
+    ASSERT_EQ(status.getServiceSpecificError(), toInt(StatusCode::INTERNAL_ERROR));
+}
+
+TEST_F(DefaultVehicleHalTest, testGetValuesInvalidLargeParcelableInput) {
+    GetValueRequests requests;
+    requests.sharedMemoryFd = ScopedFileDescriptor(0);
+
+    auto status = getClient()->getValues(getCallbackClient(), requests);
+
+    ASSERT_FALSE(status.isOk()) << "expect getValues to fail when input parcelable is not valid";
+    ASSERT_EQ(status.getServiceSpecificError(), toInt(StatusCode::INVALID_ARG));
+}
+
+TEST_F(DefaultVehicleHalTest, testSetValuesSmall) {
+    SetValueRequests requests;
+    std::vector<SetValueResult> expectedResults;
+    std::vector<SetValueRequest> expectedHardwareRequests;
+
+    ASSERT_TRUE(setValuesTestCases(10, requests, expectedResults, expectedHardwareRequests).ok());
+
+    getHardware()->addSetValueResponses(expectedResults);
+
+    auto status = getClient()->setValues(getCallbackClient(), requests);
+
+    ASSERT_TRUE(status.isOk()) << "setValues failed: " << status.getMessage();
+
+    EXPECT_EQ(getHardware()->nextSetValueRequests(), expectedHardwareRequests)
+            << "requests to hardware mismatch";
+
+    auto maybeSetValueResults = getCallback()->nextSetValueResults();
+    ASSERT_TRUE(maybeSetValueResults.has_value()) << "no results in callback";
+    ASSERT_EQ(maybeSetValueResults.value().payloads, expectedResults) << "results mismatch";
+    EXPECT_EQ(countClients(), static_cast<size_t>(1));
+}
+
+TEST_F(DefaultVehicleHalTest, testSetValuesLarge) {
+    SetValueRequests requests;
+    std::vector<SetValueResult> expectedResults;
+    std::vector<SetValueRequest> expectedHardwareRequests;
+
+    ASSERT_TRUE(setValuesTestCases(5000, requests, expectedResults, expectedHardwareRequests).ok());
+
+    getHardware()->addSetValueResponses(expectedResults);
+
+    auto status = getClient()->setValues(getCallbackClient(), requests);
+
+    ASSERT_TRUE(status.isOk()) << "setValues failed: " << status.getMessage();
+
+    EXPECT_EQ(getHardware()->nextSetValueRequests(), expectedHardwareRequests)
+            << "requests to hardware mismatch";
+
+    auto maybeSetValueResults = getCallback()->nextSetValueResults();
+    ASSERT_TRUE(maybeSetValueResults.has_value()) << "no results in callback";
+    const SetValueResults& setValueResults = maybeSetValueResults.value();
+    ASSERT_TRUE(setValueResults.payloads.empty())
+            << "payload should be empty, shared memory file should be used";
+
+    auto result = LargeParcelableBase::stableLargeParcelableToParcelableVector<SetValueResult>(
+            setValueResults.sharedMemoryFd);
+    ASSERT_TRUE(result.ok()) << "failed to parse shared memory file";
+    ASSERT_TRUE(result.value().has_value()) << "no parsed value";
+    ASSERT_EQ(result.value().value(), expectedResults) << "results mismatch";
+    EXPECT_EQ(countClients(), static_cast<size_t>(1));
+}
+
+class SetValuesInvalidRequestTest
+    : public DefaultVehicleHalTest,
+      public testing::WithParamInterface<SetValuesInvalidRequestTestCase> {};
+
+INSTANTIATE_TEST_SUITE_P(
+        SetValuesInvalidRequestTests, SetValuesInvalidRequestTest,
+        ::testing::ValuesIn(getSetValuesInvalidRequestTestCases()),
+        [](const testing::TestParamInfo<SetValuesInvalidRequestTest::ParamType>& info) {
+            return info.param.name;
+        });
+
+TEST_P(SetValuesInvalidRequestTest, testSetValuesInvalidRequest) {
+    SetValuesInvalidRequestTestCase tc = GetParam();
+    std::vector<SetValueResult> expectedHardwareResults{
+            SetValueResult{
+                    .requestId = 1,
+                    .status = StatusCode::OK,
+            },
+    };
+    getHardware()->addSetValueResponses(expectedHardwareResults);
+
+    SetValueRequests requests;
+    SetValueRequest invalidRequest{
+            .requestId = 0,
+            .value = tc.request,
+    };
+    SetValueRequest normalRequest{.requestId = 1,
+                                  .value = {
+                                          .prop = testInt32VecProp(0),
+                                          .value.int32Values = {0},
+                                  }};
+    requests.payloads = {invalidRequest, normalRequest};
+    auto status = getClient()->setValues(getCallbackClient(), requests);
+
+    ASSERT_TRUE(status.isOk()) << "setValues failed: " << status.getMessage();
+
+    EXPECT_EQ(getHardware()->nextSetValueRequests(), std::vector<SetValueRequest>({normalRequest}))
+            << "requests to hardware mismatch";
+
+    auto maybeSetValueResults = getCallback()->nextSetValueResults();
+    ASSERT_TRUE(maybeSetValueResults.has_value()) << "no results in callback";
+    EXPECT_EQ(maybeSetValueResults.value().payloads, std::vector<SetValueResult>({
+                                                             {
+                                                                     .requestId = 0,
+                                                                     .status = tc.expectedStatus,
+                                                             },
+                                                     }))
+            << "invalid argument result mismatch";
+
+    maybeSetValueResults = getCallback()->nextSetValueResults();
+    ASSERT_TRUE(maybeSetValueResults.has_value()) << "no results from hardware in callback";
+    EXPECT_EQ(maybeSetValueResults.value().payloads, expectedHardwareResults)
+            << "results from hardware mismatch";
+}
+
 }  // namespace vehicle
 }  // namespace automotive
 }  // namespace hardware
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.1/Android.bp b/bluetooth/audio/2.1/Android.bp
index 822f5b3..1175fb3 100644
--- a/bluetooth/audio/2.1/Android.bp
+++ b/bluetooth/audio/2.1/Android.bp
@@ -25,7 +25,7 @@
     ],
     apex_available: [
         "//apex_available:platform",
-        "com.android.bluetooth.updatable",
+        "com.android.bluetooth",
     ],
     gen_java: false,
 }
diff --git a/bluetooth/audio/2.1/default/BluetoothAudioProvidersFactory.cpp b/bluetooth/audio/2.1/default/BluetoothAudioProvidersFactory.cpp
index b0d171a..6e8c1d7 100644
--- a/bluetooth/audio/2.1/default/BluetoothAudioProvidersFactory.cpp
+++ b/bluetooth/audio/2.1/default/BluetoothAudioProvidersFactory.cpp
@@ -41,12 +41,8 @@
     BluetoothAudioProvidersFactory::hearing_aid_provider_instance_;
 LeAudioOutputAudioProvider
     BluetoothAudioProvidersFactory::leaudio_output_provider_instance_;
-LeAudioOffloadOutputAudioProvider
-    BluetoothAudioProvidersFactory::leaudio_offload_output_provider_instance_;
 LeAudioInputAudioProvider
     BluetoothAudioProvidersFactory::leaudio_input_provider_instance_;
-LeAudioOffloadInputAudioProvider
-    BluetoothAudioProvidersFactory::leaudio_offload_input_provider_instance_;
 
 Return<void> BluetoothAudioProvidersFactory::openProvider(
     const V2_0::SessionType sessionType, openProvider_cb _hidl_cb) {
@@ -94,15 +90,9 @@
     case SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH:
       provider = &leaudio_output_provider_instance_;
       break;
-    case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
-      provider = &leaudio_offload_output_provider_instance_;
-      break;
     case SessionType::LE_AUDIO_SOFTWARE_DECODED_DATAPATH:
       provider = &leaudio_input_provider_instance_;
       break;
-    case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH:
-      provider = &leaudio_offload_input_provider_instance_;
-      break;
     default:
       status = BluetoothAudioStatus::FAILURE;
   }
@@ -157,7 +147,11 @@
         audio_capabilities[i].codecCapabilities(db_codec_capabilities[i]);
       }
     }
-  } else if (sessionType != SessionType::UNKNOWN) {
+  } else if (sessionType !=
+                 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
+             sessionType !=
+                 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH &&
+             sessionType != SessionType::UNKNOWN) {
     std::vector<PcmParameters> db_pcm_capabilities =
         android::bluetooth::audio::GetSoftwarePcmCapabilities_2_1();
     if (db_pcm_capabilities.size() == 1) {
diff --git a/bluetooth/audio/2.1/default/BluetoothAudioProvidersFactory.h b/bluetooth/audio/2.1/default/BluetoothAudioProvidersFactory.h
index f8f557e..714d738 100644
--- a/bluetooth/audio/2.1/default/BluetoothAudioProvidersFactory.h
+++ b/bluetooth/audio/2.1/default/BluetoothAudioProvidersFactory.h
@@ -56,8 +56,6 @@
   static HearingAidAudioProvider hearing_aid_provider_instance_;
   static LeAudioOutputAudioProvider leaudio_output_provider_instance_;
   static LeAudioInputAudioProvider leaudio_input_provider_instance_;
-  static LeAudioOffloadOutputAudioProvider leaudio_offload_output_provider_instance_;
-  static LeAudioOffloadInputAudioProvider leaudio_offload_input_provider_instance_;
 };
 
 extern "C" IBluetoothAudioProvidersFactory*
diff --git a/bluetooth/audio/2.2/Android.bp b/bluetooth/audio/2.2/Android.bp
index 8d52ce9..d66e84e 100644
--- a/bluetooth/audio/2.2/Android.bp
+++ b/bluetooth/audio/2.2/Android.bp
@@ -27,7 +27,7 @@
     ],
     apex_available: [
         "//apex_available:platform",
-        "com.android.bluetooth.updatable",
+        "com.android.bluetooth",
     ],
     gen_java: false,
 }
diff --git a/bluetooth/audio/2.2/IBluetoothAudioProvider.hal b/bluetooth/audio/2.2/IBluetoothAudioProvider.hal
index bc16b01..f577537 100644
--- a/bluetooth/audio/2.2/IBluetoothAudioProvider.hal
+++ b/bluetooth/audio/2.2/IBluetoothAudioProvider.hal
@@ -59,4 +59,14 @@
      */
     startSession_2_2(IBluetoothAudioPort hostIf, AudioConfiguration audioConfig)
                 generates (Status status, fmq_sync<uint8_t> dataMQ);
+
+    /**
+     * Called when the audio configuration of the stream has been changed.
+     *
+     * @param audioConfig The audio configuration negotiated with the remote
+     *    device. The PCM parameters are set if software based encoding,
+     *    otherwise the correct codec configuration is used for hardware
+     *    encoding.
+     */
+    updateAudioConfiguration(AudioConfiguration audioConfig);
 };
diff --git a/bluetooth/audio/2.2/IBluetoothAudioProvidersFactory.hal b/bluetooth/audio/2.2/IBluetoothAudioProvidersFactory.hal
index 7fb5b6c..ae9c598 100644
--- a/bluetooth/audio/2.2/IBluetoothAudioProvidersFactory.hal
+++ b/bluetooth/audio/2.2/IBluetoothAudioProvidersFactory.hal
@@ -48,4 +48,26 @@
      */
     openProvider_2_2(SessionType sessionType)
         generates (Status status, IBluetoothAudioProvider provider);
+
+    /**
+     * Gets a list of audio capabilities for a session type.
+     *
+     * For software encoding, the PCM capabilities are returned.
+     * For hardware encoding, the supported codecs and their capabilities are
+     * returned.
+     *
+     * @param sessionType The session type (e.g.
+     *    A2DP_SOFTWARE_ENCODING_DATAPATH).
+     * @return audioCapabilities A list containing all the capabilities
+     *    supported by the sesson type. The capabilities is a list of
+     *    available options when configuring the codec for the session.
+     *    For software encoding it is the PCM data rate.
+     *    For hardware encoding it is the list of supported codecs and their
+     *    capabilities.
+     *    If a provider isn't supported, an empty list should be returned.
+     *    Note: Only one entry should exist per codec when using hardware
+     *    encoding.
+     */
+     getProviderCapabilities_2_2(SessionType sessionType)
+         generates (vec<AudioCapabilities> audioCapabilities);
 };
diff --git a/bluetooth/audio/2.2/default/A2dpSoftwareAudioProvider.cpp b/bluetooth/audio/2.2/default/A2dpSoftwareAudioProvider.cpp
index ba31d39..eb87178 100644
--- a/bluetooth/audio/2.2/default/A2dpSoftwareAudioProvider.cpp
+++ b/bluetooth/audio/2.2/default/A2dpSoftwareAudioProvider.cpp
@@ -21,7 +21,7 @@
 #include <android-base/logging.h>
 
 #include "BluetoothAudioSessionReport_2_2.h"
-#include "BluetoothAudioSupportedCodecsDB_2_1.h"
+#include "BluetoothAudioSupportedCodecsDB_2_2.h"
 
 namespace android {
 namespace hardware {
diff --git a/bluetooth/audio/2.2/default/BluetoothAudioProvider.cpp b/bluetooth/audio/2.2/default/BluetoothAudioProvider.cpp
index 3c0ff42..202cfb9 100644
--- a/bluetooth/audio/2.2/default/BluetoothAudioProvider.cpp
+++ b/bluetooth/audio/2.2/default/BluetoothAudioProvider.cpp
@@ -22,7 +22,7 @@
 
 #include "AudioPort_2_0_to_2_2_Wrapper.h"
 #include "BluetoothAudioSessionReport_2_2.h"
-#include "BluetoothAudioSupportedCodecsDB_2_1.h"
+#include "BluetoothAudioSupportedCodecsDB_2_2.h"
 
 namespace android {
 namespace hardware {
@@ -186,6 +186,29 @@
   return Void();
 }
 
+Return<void> BluetoothAudioProvider::updateAudioConfiguration(
+    const AudioConfiguration& audioConfig) {
+  LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_);
+
+  if (stack_iface_ == nullptr) {
+    LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
+              << " has NO session";
+    return Void();
+  }
+
+  if (audioConfig.getDiscriminator() != audio_config_.getDiscriminator()) {
+    LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
+              << " audio config type is not match";
+    return Void();
+  }
+
+  audio_config_ = audioConfig;
+  BluetoothAudioSessionReport_2_2::ReportAudioConfigChanged(session_type_,
+                                                            audio_config_);
+
+  return Void();
+}
+
 }  // namespace implementation
 }  // namespace V2_2
 }  // namespace audio
diff --git a/bluetooth/audio/2.2/default/BluetoothAudioProvider.h b/bluetooth/audio/2.2/default/BluetoothAudioProvider.h
index 0f1f3c6..425ea3b 100644
--- a/bluetooth/audio/2.2/default/BluetoothAudioProvider.h
+++ b/bluetooth/audio/2.2/default/BluetoothAudioProvider.h
@@ -53,6 +53,8 @@
   Return<void> streamStarted(BluetoothAudioStatus status) override;
   Return<void> streamSuspended(BluetoothAudioStatus status) override;
   Return<void> endSession() override;
+  Return<void> updateAudioConfiguration(
+      const AudioConfiguration& audioConfig) override;
 
  protected:
   sp<BluetoothAudioDeathRecipient> death_recipient_;
diff --git a/bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.cpp b/bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.cpp
index 510833d..490a436 100644
--- a/bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.cpp
+++ b/bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.cpp
@@ -20,7 +20,7 @@
 
 #include <android-base/logging.h>
 
-#include "BluetoothAudioSupportedCodecsDB_2_1.h"
+#include "BluetoothAudioSupportedCodecsDB_2_2.h"
 
 namespace android {
 namespace hardware {
@@ -98,15 +98,9 @@
     case V2_1::SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH:
       provider = &leaudio_output_provider_instance_;
       break;
-    case V2_1::SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
-      provider = &leaudio_offload_output_provider_instance_;
-      break;
     case V2_1::SessionType::LE_AUDIO_SOFTWARE_DECODED_DATAPATH:
       provider = &leaudio_input_provider_instance_;
       break;
-    case V2_1::SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH:
-      provider = &leaudio_offload_input_provider_instance_;
-      break;
     default:
       status = BluetoothAudioStatus::FAILURE;
   }
@@ -221,6 +215,47 @@
   return Void();
 }
 
+Return<void> BluetoothAudioProvidersFactory::getProviderCapabilities_2_2(
+    const V2_1::SessionType sessionType,
+    getProviderCapabilities_2_2_cb _hidl_cb) {
+  hidl_vec<V2_2::AudioCapabilities> audio_capabilities =
+      hidl_vec<V2_2::AudioCapabilities>(0);
+  if (sessionType == V2_1::SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH) {
+    std::vector<CodecCapabilities> db_codec_capabilities =
+        android::bluetooth::audio::GetOffloadCodecCapabilities(sessionType);
+    if (db_codec_capabilities.size()) {
+      audio_capabilities.resize(db_codec_capabilities.size());
+      for (int i = 0; i < db_codec_capabilities.size(); ++i) {
+        audio_capabilities[i].codecCapabilities(db_codec_capabilities[i]);
+      }
+    }
+  } else if (sessionType == V2_1::SessionType::
+                                LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
+             sessionType == V2_1::SessionType::
+                                LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
+    std::vector<LeAudioCodecCapabilitiesSetting> db_codec_capabilities =
+        android::bluetooth::audio::GetLeAudioOffloadCodecCapabilities(
+            sessionType);
+    if (db_codec_capabilities.size()) {
+      audio_capabilities.resize(db_codec_capabilities.size());
+      for (int i = 0; i < db_codec_capabilities.size(); ++i) {
+        audio_capabilities[i].leAudioCapabilities(db_codec_capabilities[i]);
+      }
+    }
+  } else if (sessionType != V2_1::SessionType::UNKNOWN) {
+    std::vector<V2_1::PcmParameters> db_pcm_capabilities =
+        android::bluetooth::audio::GetSoftwarePcmCapabilities_2_1();
+    if (db_pcm_capabilities.size() == 1) {
+      audio_capabilities.resize(1);
+      audio_capabilities[0].pcmCapabilities(db_pcm_capabilities[0]);
+    }
+  }
+  LOG(INFO) << __func__ << " - SessionType=" << toString(sessionType)
+            << " supports " << audio_capabilities.size() << " codecs";
+  _hidl_cb(audio_capabilities);
+  return Void();
+}
+
 IBluetoothAudioProvidersFactory* HIDL_FETCH_IBluetoothAudioProvidersFactory(
     const char* /* name */) {
   return new BluetoothAudioProvidersFactory();
diff --git a/bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.h b/bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.h
index 658249b..4f549d9 100644
--- a/bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.h
+++ b/bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.h
@@ -53,6 +53,10 @@
       const V2_1::SessionType sessionType,
       getProviderCapabilities_2_1_cb _hidl_cb) override;
 
+  Return<void> getProviderCapabilities_2_2(
+      const V2_1::SessionType sessionType,
+      getProviderCapabilities_2_2_cb _hidl_cb) override;
+
  private:
   static A2dpSoftwareAudioProvider a2dp_software_provider_instance_;
   static A2dpOffloadAudioProvider a2dp_offload_provider_instance_;
diff --git a/bluetooth/audio/2.2/default/HearingAidAudioProvider.cpp b/bluetooth/audio/2.2/default/HearingAidAudioProvider.cpp
index 9b3294f..25e49a1 100644
--- a/bluetooth/audio/2.2/default/HearingAidAudioProvider.cpp
+++ b/bluetooth/audio/2.2/default/HearingAidAudioProvider.cpp
@@ -21,7 +21,7 @@
 #include <android-base/logging.h>
 
 #include "BluetoothAudioSessionReport_2_2.h"
-#include "BluetoothAudioSupportedCodecsDB_2_1.h"
+#include "BluetoothAudioSupportedCodecsDB_2_2.h"
 
 namespace android {
 namespace hardware {
diff --git a/bluetooth/audio/2.2/default/LeAudioAudioProvider.cpp b/bluetooth/audio/2.2/default/LeAudioAudioProvider.cpp
index 9ec1776..a7a0023 100644
--- a/bluetooth/audio/2.2/default/LeAudioAudioProvider.cpp
+++ b/bluetooth/audio/2.2/default/LeAudioAudioProvider.cpp
@@ -22,7 +22,7 @@
 
 #include "AudioPort_2_0_to_2_2_Wrapper.h"
 #include "BluetoothAudioSessionReport_2_2.h"
-#include "BluetoothAudioSupportedCodecsDB_2_1.h"
+#include "BluetoothAudioSupportedCodecsDB_2_2.h"
 
 namespace android {
 namespace hardware {
diff --git a/bluetooth/audio/2.2/default/LeAudioOffloadAudioProvider.cpp b/bluetooth/audio/2.2/default/LeAudioOffloadAudioProvider.cpp
index e3da267..2b0c02f 100644
--- a/bluetooth/audio/2.2/default/LeAudioOffloadAudioProvider.cpp
+++ b/bluetooth/audio/2.2/default/LeAudioOffloadAudioProvider.cpp
@@ -22,7 +22,6 @@
 
 #include "AudioPort_2_0_to_2_2_Wrapper.h"
 #include "BluetoothAudioSessionReport_2_2.h"
-#include "BluetoothAudioSupportedCodecsDB_2_1.h"
 #include "BluetoothAudioSupportedCodecsDB_2_2.h"
 
 namespace android {
diff --git a/bluetooth/audio/2.2/types.hal b/bluetooth/audio/2.2/types.hal
index d5f8a3f..6755899 100644
--- a/bluetooth/audio/2.2/types.hal
+++ b/bluetooth/audio/2.2/types.hal
@@ -19,6 +19,8 @@
 import @2.1::Lc3Parameters;
 import @2.1::PcmParameters;
 import @2.0::CodecConfiguration;
+import @2.0::CodecCapabilities;
+import @2.1::CodecType;
 
 enum LeAudioMode : uint8_t {
     UNKNOWN = 0x00,
@@ -26,6 +28,12 @@
     BROADCAST = 0x02,
 };
 
+enum AudioLocation : uint8_t {
+  UNKNOWN = 0,
+  FRONT_LEFT = 1,
+  FRONT_RIGHT = 2,
+};
+
 struct UnicastStreamMap {
     /* The connection handle used for a unicast or a broadcast group. */
     uint16_t streamHandle;
@@ -70,3 +78,50 @@
     CodecConfiguration codecConfig;
     LeAudioConfiguration leAudioConfig;
 };
+
+/** Used to specify the capabilities of the different session types */
+safe_union AudioCapabilities {
+    PcmParameters pcmCapabilities;
+    CodecCapabilities codecCapabilities;
+    LeAudioCodecCapabilitiesSetting leAudioCapabilities;
+};
+
+/**
+ * Used to specify the le audio capabilities for unicast and broadcast hardware offload.
+ */
+struct LeAudioCodecCapabilitiesSetting{
+    UnicastCapability unicastEncodeCapability;
+    UnicastCapability unicastDecodeCapability;
+    BroadcastCapability broadcastCapability;
+};
+
+/**
+ * Used to specify the le audio unicast codec capabilities for hardware offload.
+ */
+struct UnicastCapability {
+    CodecType codecType;
+    AudioLocation supportedChannel;
+
+    // The number of connected device
+    uint8_t deviceCount;
+
+    // Supported channel count for each device
+    uint8_t channelCountPerDevice;
+
+    // Should use safe union when there is more than one codec
+    Lc3Parameters capabilities;
+};
+
+/**
+ * Used to specify the le audio broadcast codec capabilities for hardware offload.
+ */
+struct BroadcastCapability {
+    CodecType codecType;
+    AudioLocation supportedChannel;
+
+    // Supported channel count for each stream
+    uint8_t channelCountPerStream;
+
+    // Should use safe union when there is more than one codec
+    vec<Lc3Parameters> capabilities;
+};
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioCapabilities.aidl
index 20a7731..8ae716f 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioCapabilities.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioCapabilities.aidl
@@ -35,6 +35,6 @@
 @VintfStability
 union AudioCapabilities {
   android.hardware.bluetooth.audio.PcmCapabilities pcmCapabilities;
-  android.hardware.bluetooth.audio.CodecCapabilities codecCapabilities;
-  android.hardware.bluetooth.audio.LeAudioCapabilities leAudioCapabilities;
+  android.hardware.bluetooth.audio.CodecCapabilities a2dpCapabilities;
+  android.hardware.bluetooth.audio.LeAudioCodecCapabilitiesSetting leAudioCapabilities;
 }
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioConfiguration.aidl
index 34f7837..50b54c3 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioConfiguration.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioConfiguration.aidl
@@ -35,6 +35,6 @@
 @VintfStability
 union AudioConfiguration {
   android.hardware.bluetooth.audio.PcmConfiguration pcmConfig;
-  android.hardware.bluetooth.audio.CodecConfiguration codecConfig;
+  android.hardware.bluetooth.audio.CodecConfiguration a2dpConfig;
   android.hardware.bluetooth.audio.LeAudioConfiguration leAudioConfig;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BluetoothAudioStatus.aidl
similarity index 85%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.aidl
copy to bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BluetoothAudioStatus.aidl
index b87870d..7c0d825 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BluetoothAudioStatus.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-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,9 +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.bluetooth.audio;
 @Backing(type="int") @VintfStability
-enum HandleIndex {
-  EMPTY = -1,
-  CACHED = -2,
+enum BluetoothAudioStatus {
+  UNKNOWN = 0,
+  SUCCESS = 1,
+  UNSUPPORTED_CODEC_CONFIGURATION = 2,
+  FAILURE = 3,
 }
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BroadcastCapability.aidl
similarity index 80%
copy from bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl
copy to bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BroadcastCapability.aidl
index 9efafca..58710ef 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BroadcastCapability.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright 2021 The Android Open Source Project
+ * Copyright 2022 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -33,19 +33,18 @@
 
 package android.hardware.bluetooth.audio;
 @VintfStability
-parcelable LeAudioCapabilities {
-  android.hardware.bluetooth.audio.LeAudioMode mode;
+parcelable BroadcastCapability {
   android.hardware.bluetooth.audio.CodecType codecType;
   android.hardware.bluetooth.audio.AudioLocation supportedChannel;
-  int supportedChannelCount;
-  android.hardware.bluetooth.audio.LeAudioCapabilities.LeaudioCodecCapabilities leaudioCodecCapabilities;
+  int channelCountPerStream;
+  android.hardware.bluetooth.audio.BroadcastCapability.LeAudioCodecCapabilities leAudioCodecCapabilities;
   @VintfStability
   parcelable VendorCapabilities {
     ParcelableHolder extension;
   }
   @VintfStability
-  union LeaudioCodecCapabilities {
-    android.hardware.bluetooth.audio.Lc3Capabilities lc3Capabilities;
-    android.hardware.bluetooth.audio.LeAudioCapabilities.VendorCapabilities vendorCapabillities;
+  union LeAudioCodecCapabilities {
+    @nullable android.hardware.bluetooth.audio.Lc3Capabilities[] lc3Capabilities;
+    @nullable android.hardware.bluetooth.audio.BroadcastCapability.VendorCapabilities[] vendorCapabillities;
   }
 }
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl
index b3aa709..5fa3926 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl
@@ -39,6 +39,6 @@
   parcelable BroadcastStreamMap {
     char streamHandle;
     int audioChannelAllocation;
-    android.hardware.bluetooth.audio.LeAudioCodecConfiguration leAudioCondecConfig;
+    android.hardware.bluetooth.audio.LeAudioCodecConfiguration leAudioCodecConfig;
   }
 }
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecCapabilities.aidl
index b451880..e2a08a0 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecCapabilities.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecCapabilities.aidl
@@ -42,5 +42,6 @@
     android.hardware.bluetooth.audio.AacCapabilities aacCapabilities;
     android.hardware.bluetooth.audio.LdacCapabilities ldacCapabilities;
     android.hardware.bluetooth.audio.AptxCapabilities aptxCapabilities;
+    android.hardware.bluetooth.audio.Lc3Capabilities lc3Capabilities;
   }
 }
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecConfiguration.aidl
index 863aee2..34ebd60 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecConfiguration.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecConfiguration.aidl
@@ -45,5 +45,6 @@
     android.hardware.bluetooth.audio.AacConfiguration aacConfig;
     android.hardware.bluetooth.audio.LdacConfiguration ldacConfig;
     android.hardware.bluetooth.audio.AptxConfiguration aptxConfig;
+    android.hardware.bluetooth.audio.Lc3Configuration lc3Config;
   }
 }
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
index 84bcc0c..0dcba2e 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
@@ -35,7 +35,8 @@
 @VintfStability
 interface IBluetoothAudioProvider {
   void endSession();
-  android.hardware.common.fmq.MQDescriptor<int,android.hardware.common.fmq.UnsynchronizedWrite> startSession(in android.hardware.bluetooth.audio.IBluetoothAudioPort hostIf, in android.hardware.bluetooth.audio.AudioConfiguration audioConfig);
-  void streamStarted(in boolean status);
-  void streamSuspended(in boolean status);
+  android.hardware.common.fmq.MQDescriptor<byte,android.hardware.common.fmq.SynchronizedReadWrite> startSession(in android.hardware.bluetooth.audio.IBluetoothAudioPort hostIf, in android.hardware.bluetooth.audio.AudioConfiguration audioConfig);
+  void streamStarted(in android.hardware.bluetooth.audio.BluetoothAudioStatus status);
+  void streamSuspended(in android.hardware.bluetooth.audio.BluetoothAudioStatus status);
+  void updateAudioConfiguration(in android.hardware.bluetooth.audio.AudioConfiguration audioConfig);
 }
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Lc3Capabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Lc3Capabilities.aidl
index 3c650da..cc4449a 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Lc3Capabilities.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Lc3Capabilities.aidl
@@ -39,4 +39,5 @@
   int[] frameDurationUs;
   int[] octetsPerFrame;
   byte[] blocksPerSdu;
+  android.hardware.bluetooth.audio.ChannelMode[] channelMode;
 }
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Lc3Configuration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Lc3Configuration.aidl
index ef77da7..7e8dccf 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Lc3Configuration.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Lc3Configuration.aidl
@@ -39,4 +39,5 @@
   int frameDurationUs;
   int octetsPerFrame;
   byte blocksPerSdu;
+  android.hardware.bluetooth.audio.ChannelMode channelMode;
 }
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacQualityIndex.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacQualityIndex.aidl
index bc0d97b..693392f 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacQualityIndex.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacQualityIndex.aidl
@@ -34,8 +34,8 @@
 package android.hardware.bluetooth.audio;
 @Backing(type="byte") @VintfStability
 enum LdacQualityIndex {
-  QUALITY_HIGH = 1,
-  QUALITY_MID = 2,
-  QUALITY_LOW = 4,
-  QUALITY_ABR = 8,
+  HIGH = 1,
+  MID = 2,
+  LOW = 4,
+  ABR = 8,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCodecCapabilitiesSetting.aidl
similarity index 78%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl
copy to bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCodecCapabilitiesSetting.aidl
index df07c9c..9818d54 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCodecCapabilitiesSetting.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * Copyright 2022 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-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,9 +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.bluetooth.audio;
 @VintfStability
-parcelable ColorTransformPayload {
-  float[] matrix;
-  android.hardware.graphics.common.ColorTransform hint;
+parcelable LeAudioCodecCapabilitiesSetting {
+  android.hardware.bluetooth.audio.UnicastCapability unicastEncodeCapability;
+  android.hardware.bluetooth.audio.UnicastCapability unicastDecodeCapability;
+  android.hardware.bluetooth.audio.BroadcastCapability broadcastCapability;
 }
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
index c6cb5cb..2bc1791 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
@@ -35,10 +35,10 @@
 @VintfStability
 parcelable LeAudioConfiguration {
   android.hardware.bluetooth.audio.LeAudioMode mode;
-  android.hardware.bluetooth.audio.LeAudioConfiguration.LeAuioModeConfig modeConfig;
+  android.hardware.bluetooth.audio.LeAudioConfiguration.LeAudioModeConfig modeConfig;
   android.hardware.bluetooth.audio.CodecType codecType;
   @VintfStability
-  union LeAuioModeConfig {
+  union LeAudioModeConfig {
     android.hardware.bluetooth.audio.UnicastConfiguration unicastConfig;
     android.hardware.bluetooth.audio.BroadcastConfiguration broadcastConfig;
   }
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PcmCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PcmCapabilities.aidl
index 0c2f87d..6cfe5cd 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PcmCapabilities.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PcmCapabilities.aidl
@@ -35,7 +35,7 @@
 @VintfStability
 parcelable PcmCapabilities {
   int[] sampleRateHz;
-  android.hardware.bluetooth.audio.ChannelMode[] channelMode;
+  android.hardware.bluetooth.audio.ChannelMode channelMode;
   byte[] bitsPerSample;
   int[] dataIntervalUs;
 }
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PresentationPosition.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PresentationPosition.aidl
index 810a9a1..7e997e8 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PresentationPosition.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PresentationPosition.aidl
@@ -36,7 +36,7 @@
 parcelable PresentationPosition {
   long remoteDeviceAudioDelayNanos;
   long transmittedOctets;
-  android.hardware.bluetooth.audio.PresentationPosition.TimeSpec transmittedOctetsTimeStamp;
+  android.hardware.bluetooth.audio.PresentationPosition.TimeSpec transmittedOctetsTimestamp;
   @VintfStability
   parcelable TimeSpec {
     long tvSec;
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SessionType.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SessionType.aidl
index 900ab31..72d7fb2 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SessionType.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SessionType.aidl
@@ -36,7 +36,7 @@
 enum SessionType {
   UNKNOWN = 0,
   A2DP_SOFTWARE_ENCODING_DATAPATH = 1,
-  A2DP_HARDWARE_OFFLOAD_DATAPATH = 2,
+  A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH = 2,
   HEARING_AID_SOFTWARE_ENCODING_DATAPATH = 3,
   LE_AUDIO_SOFTWARE_ENCODING_DATAPATH = 4,
   LE_AUDIO_SOFTWARE_DECODING_DATAPATH = 5,
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/UnicastCapability.aidl
similarity index 85%
rename from bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl
rename to bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/UnicastCapability.aidl
index 9efafca..130fef9 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/UnicastCapability.aidl
@@ -33,19 +33,19 @@
 
 package android.hardware.bluetooth.audio;
 @VintfStability
-parcelable LeAudioCapabilities {
-  android.hardware.bluetooth.audio.LeAudioMode mode;
+parcelable UnicastCapability {
   android.hardware.bluetooth.audio.CodecType codecType;
   android.hardware.bluetooth.audio.AudioLocation supportedChannel;
-  int supportedChannelCount;
-  android.hardware.bluetooth.audio.LeAudioCapabilities.LeaudioCodecCapabilities leaudioCodecCapabilities;
+  int deviceCount;
+  int channelCountPerDevice;
+  android.hardware.bluetooth.audio.UnicastCapability.LeAudioCodecCapabilities leAudioCodecCapabilities;
   @VintfStability
   parcelable VendorCapabilities {
     ParcelableHolder extension;
   }
   @VintfStability
-  union LeaudioCodecCapabilities {
+  union LeAudioCodecCapabilities {
     android.hardware.bluetooth.audio.Lc3Capabilities lc3Capabilities;
-    android.hardware.bluetooth.audio.LeAudioCapabilities.VendorCapabilities vendorCapabillities;
+    android.hardware.bluetooth.audio.UnicastCapability.VendorCapabilities vendorCapabillities;
   }
 }
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioCapabilities.aidl
index 6ed4472..a75c445 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioCapabilities.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioCapabilities.aidl
@@ -17,7 +17,7 @@
 package android.hardware.bluetooth.audio;
 
 import android.hardware.bluetooth.audio.CodecCapabilities;
-import android.hardware.bluetooth.audio.LeAudioCapabilities;
+import android.hardware.bluetooth.audio.LeAudioCodecCapabilitiesSetting;
 import android.hardware.bluetooth.audio.PcmCapabilities;
 
 /**
@@ -26,6 +26,6 @@
 @VintfStability
 union AudioCapabilities {
     PcmCapabilities pcmCapabilities;
-    CodecCapabilities codecCapabilities;
-    LeAudioCapabilities leAudioCapabilities;
+    CodecCapabilities a2dpCapabilities;
+    LeAudioCodecCapabilitiesSetting leAudioCapabilities;
 }
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioConfiguration.aidl
index ce515b5..81b41dc 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioConfiguration.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioConfiguration.aidl
@@ -26,6 +26,6 @@
 @VintfStability
 union AudioConfiguration {
     PcmConfiguration pcmConfig;
-    CodecConfiguration codecConfig;
+    CodecConfiguration a2dpConfig;
     LeAudioConfiguration leAudioConfig;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BluetoothAudioStatus.aidl
similarity index 62%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
copy to bluetooth/audio/aidl/android/hardware/bluetooth/audio/BluetoothAudioStatus.aidl
index a0a1d4b..ec78445 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BluetoothAudioStatus.aidl
@@ -1,11 +1,11 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,16 +14,14 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
-
-/**
- * Color representation as a floating point number in the range [0.0 - 1.0]
- */
+package android.hardware.bluetooth.audio;
 
 @VintfStability
-parcelable FloatColor {
-    float r;
-    float g;
-    float b;
-    float a;
+@Backing(type="int")
+enum BluetoothAudioStatus {
+    UNKNOWN = 0,
+    SUCCESS = 1,
+    UNSUPPORTED_CODEC_CONFIGURATION = 2,
+    // General failure
+    FAILURE = 3
 }
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BroadcastCapability.aidl
similarity index 63%
copy from bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl
copy to bluetooth/audio/aidl/android/hardware/bluetooth/audio/BroadcastCapability.aidl
index ea05820..cb63f88 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BroadcastCapability.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright 2021 The Android Open Source Project
+ * Copyright 2022 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -22,26 +22,22 @@
 import android.hardware.bluetooth.audio.LeAudioMode;
 
 /**
- * Used to specify the capabilities of the LC3 codecs supported by Hardware Encoding.
+ * Used to specify the le audio broadcast codec capabilities for hardware offload.
  */
 @VintfStability
-parcelable LeAudioCapabilities {
+parcelable BroadcastCapability {
     @VintfStability
     parcelable VendorCapabilities {
         ParcelableHolder extension;
     }
     @VintfStability
-    union LeaudioCodecCapabilities {
-        Lc3Capabilities lc3Capabilities;
-        VendorCapabilities vendorCapabillities;
+    union LeAudioCodecCapabilities {
+        @nullable Lc3Capabilities[] lc3Capabilities;
+        @nullable VendorCapabilities[] vendorCapabillities;
     }
-    LeAudioMode mode;
     CodecType codecType;
-    /*
-     * This is bitfield, if bit N is set, HW Offloader supports N+1 channels at the same time.
-     * Example: 0x27 = 0b00100111: One, two, three or six channels supported.
-     */
     AudioLocation supportedChannel;
-    int supportedChannelCount;
-    LeaudioCodecCapabilities leaudioCodecCapabilities;
+    // Supported channel count for each stream
+    int channelCountPerStream;
+    LeAudioCodecCapabilities leAudioCodecCapabilities;
 }
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl
index 07d05f1..cfc9d3a 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl
@@ -33,7 +33,7 @@
          * least significant bit to the most significant bit.
          */
         int audioChannelAllocation;
-        LeAudioCodecConfiguration leAudioCondecConfig;
+        LeAudioCodecConfiguration leAudioCodecConfig;
     }
     BroadcastStreamMap[] streamMap;
 }
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecCapabilities.aidl
index 0eee8cb..5bf0252 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecCapabilities.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecCapabilities.aidl
@@ -19,6 +19,7 @@
 import android.hardware.bluetooth.audio.AacCapabilities;
 import android.hardware.bluetooth.audio.AptxCapabilities;
 import android.hardware.bluetooth.audio.CodecType;
+import android.hardware.bluetooth.audio.Lc3Capabilities;
 import android.hardware.bluetooth.audio.LdacCapabilities;
 import android.hardware.bluetooth.audio.SbcCapabilities;
 
@@ -34,6 +35,7 @@
         AacCapabilities aacCapabilities;
         LdacCapabilities ldacCapabilities;
         AptxCapabilities aptxCapabilities;
+        Lc3Capabilities lc3Capabilities;
     }
     CodecType codecType;
     Capabilities capabilities;
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecConfiguration.aidl
index fac90f0..9e43f22 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecConfiguration.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecConfiguration.aidl
@@ -19,6 +19,7 @@
 import android.hardware.bluetooth.audio.AacConfiguration;
 import android.hardware.bluetooth.audio.AptxConfiguration;
 import android.hardware.bluetooth.audio.CodecType;
+import android.hardware.bluetooth.audio.Lc3Configuration;
 import android.hardware.bluetooth.audio.LdacConfiguration;
 import android.hardware.bluetooth.audio.SbcConfiguration;
 
@@ -34,6 +35,7 @@
         AacConfiguration aacConfig;
         LdacConfiguration ldacConfig;
         AptxConfiguration aptxConfig;
+        Lc3Configuration lc3Config;
     }
     CodecType codecType;
     /**
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
index cebd808..6f88f30 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
@@ -17,9 +17,10 @@
 package android.hardware.bluetooth.audio;
 
 import android.hardware.bluetooth.audio.AudioConfiguration;
+import android.hardware.bluetooth.audio.BluetoothAudioStatus;
 import android.hardware.bluetooth.audio.IBluetoothAudioPort;
 import android.hardware.common.fmq.MQDescriptor;
-import android.hardware.common.fmq.UnsynchronizedWrite;
+import android.hardware.common.fmq.SynchronizedReadWrite;
 
 /**
  * HAL interface from the Bluetooth stack to the Audio HAL
@@ -55,7 +56,7 @@
      *    audioConfig.pcmConfig parameter. Invalid if streaming is offloaded
      *    from/to hardware or on failure
      */
-    MQDescriptor<int, UnsynchronizedWrite> startSession(
+    MQDescriptor<byte, SynchronizedReadWrite> startSession(
             in IBluetoothAudioPort hostIf, in AudioConfiguration audioConfig);
 
     /**
@@ -63,12 +64,22 @@
      *
      * @param status true for SUCCESS or false for FAILURE
      */
-    void streamStarted(in boolean status);
+    void streamStarted(in BluetoothAudioStatus status);
 
     /**
      * Callback for IBluetoothAudioPort.suspendStream()
      *
      * @param status true for SUCCESS or false for FAILURE
      */
-    void streamSuspended(in boolean status);
+    void streamSuspended(in BluetoothAudioStatus status);
+
+    /**
+     * Called when the audio configuration of the stream has been changed.
+     *
+     * @param audioConfig The audio configuration negotiated with the remote
+     *    device. The PCM parameters are set if software based encoding,
+     *    otherwise the correct codec configuration is used for hardware
+     *    encoding.
+     */
+    void updateAudioConfiguration(in AudioConfiguration audioConfig);
 }
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Lc3Capabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Lc3Capabilities.aidl
index 1aedefd..fc2f382 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Lc3Capabilities.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Lc3Capabilities.aidl
@@ -16,6 +16,8 @@
 
 package android.hardware.bluetooth.audio;
 
+import android.hardware.bluetooth.audio.ChannelMode;
+
 /**
  * Used for Hardware Encoding/Decoding LC3 codec capabilities.
  */
@@ -41,4 +43,8 @@
      * Number of blocks of codec frames per single SDU (Service Data Unit)
      */
     byte[] blocksPerSdu;
+    /*
+     * Channel mode used in A2DP special audio, ignored in standard LE Audio mode
+     */
+    ChannelMode[] channelMode;
 }
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Lc3Configuration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Lc3Configuration.aidl
index 77c04c1..e8a93b2 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Lc3Configuration.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Lc3Configuration.aidl
@@ -16,6 +16,8 @@
 
 package android.hardware.bluetooth.audio;
 
+import android.hardware.bluetooth.audio.ChannelMode;
+
 /**
  * Used for Hardware Encoding/Decoding LC3 codec configuration.
  */
@@ -41,4 +43,8 @@
      * Number of blocks of codec frames per single SDU (Service Data Unit)
      */
     byte blocksPerSdu;
+    /*
+     * Channel mode used in A2DP special audio, ignored in standard LE Audio mode
+     */
+    ChannelMode channelMode;
 }
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacQualityIndex.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacQualityIndex.aidl
index fc532f4..cb12583 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacQualityIndex.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacQualityIndex.aidl
@@ -22,17 +22,17 @@
     /**
      * 990kbps
      */
-    QUALITY_HIGH = 1,
+    HIGH = 1,
     /**
      * 660kbps
      */
-    QUALITY_MID = 1 << 1,
+    MID = 1 << 1,
     /**
      * 330kbps
      */
-    QUALITY_LOW = 1 << 2,
+    LOW = 1 << 2,
     /**
      * Adaptive Bit Rate mode
      */
-    QUALITY_ABR = 1 << 3,
+    ABR = 1 << 3,
 }
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCodecCapabilitiesSetting.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCodecCapabilitiesSetting.aidl
new file mode 100644
index 0000000..58dac06
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCodecCapabilitiesSetting.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.BroadcastCapability;
+import android.hardware.bluetooth.audio.UnicastCapability;
+
+/**
+ * Used to specify the le audio capabilities for unicast and broadcast hardware offload.
+ */
+@VintfStability
+parcelable LeAudioCodecCapabilitiesSetting {
+    UnicastCapability unicastEncodeCapability;
+    UnicastCapability unicastDecodeCapability;
+    BroadcastCapability broadcastCapability;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
index a212c96..515794b 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
@@ -24,7 +24,7 @@
 @VintfStability
 parcelable LeAudioConfiguration {
     @VintfStability
-    union LeAuioModeConfig {
+    union LeAudioModeConfig {
         UnicastConfiguration unicastConfig;
         BroadcastConfiguration broadcastConfig;
     }
@@ -32,6 +32,6 @@
      * The mode of the LE audio
      */
     LeAudioMode mode;
-    LeAuioModeConfig modeConfig;
+    LeAudioModeConfig modeConfig;
     CodecType codecType;
 }
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/PcmCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/PcmCapabilities.aidl
index 776b777..f5d699e 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/PcmCapabilities.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/PcmCapabilities.aidl
@@ -24,7 +24,7 @@
 @VintfStability
 parcelable PcmCapabilities {
     int[] sampleRateHz;
-    ChannelMode[] channelMode;
+    ChannelMode channelMode;
     byte[] bitsPerSample;
     /**
      * Data interval for data transfer
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/PresentationPosition.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/PresentationPosition.aidl
index 17e746f..f3b8aed 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/PresentationPosition.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/PresentationPosition.aidl
@@ -44,9 +44,9 @@
      */
     long transmittedOctets;
     /*
-     * transmittedOctetsTimeStamp the value of CLOCK_MONOTONIC
+     * transmittedOctetsTimestamp the value of CLOCK_MONOTONIC
      * corresponding to transmittedOctets. If the software data path is
      * unused (e.g., for Hardware Offload), the value is set to zero.
      */
-    TimeSpec transmittedOctetsTimeStamp;
+    TimeSpec transmittedOctetsTimestamp;
 }
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SessionType.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SessionType.aidl
index b588869..30faae3 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SessionType.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SessionType.aidl
@@ -27,7 +27,7 @@
     /**
      * The encoding of AVDTP media is done by HW and there is control only
      */
-    A2DP_HARDWARE_OFFLOAD_DATAPATH,
+    A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
     /**
      * Used when encoded by Bluetooth Stack and streaming to Hearing Aid
      */
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/UnicastCapability.aidl
similarity index 72%
rename from bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl
rename to bluetooth/audio/aidl/android/hardware/bluetooth/audio/UnicastCapability.aidl
index ea05820..cd8a4c1 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/UnicastCapability.aidl
@@ -22,26 +22,24 @@
 import android.hardware.bluetooth.audio.LeAudioMode;
 
 /**
- * Used to specify the capabilities of the LC3 codecs supported by Hardware Encoding.
+ * Used to specify the le audio unicast codec capabilities for hardware offload.
  */
 @VintfStability
-parcelable LeAudioCapabilities {
+parcelable UnicastCapability {
     @VintfStability
     parcelable VendorCapabilities {
         ParcelableHolder extension;
     }
     @VintfStability
-    union LeaudioCodecCapabilities {
+    union LeAudioCodecCapabilities {
         Lc3Capabilities lc3Capabilities;
         VendorCapabilities vendorCapabillities;
     }
-    LeAudioMode mode;
     CodecType codecType;
-    /*
-     * This is bitfield, if bit N is set, HW Offloader supports N+1 channels at the same time.
-     * Example: 0x27 = 0b00100111: One, two, three or six channels supported.
-     */
     AudioLocation supportedChannel;
-    int supportedChannelCount;
-    LeaudioCodecCapabilities leaudioCodecCapabilities;
+    // The number of connected device
+    int deviceCount;
+    // Supported channel count for each device
+    int channelCountPerDevice;
+    LeAudioCodecCapabilities leAudioCodecCapabilities;
 }
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_2.h b/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_2.h
index b4ba8cf..368939e 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_2.h
+++ b/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_2.h
@@ -48,20 +48,38 @@
     std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
         BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
     if (session_ptr != nullptr) {
-      return session_ptr->GetAudioSession()->RegisterStatusCback(cbacks);
+      PortStatusCallbacks_2_2 cb = {
+          .control_result_cb_ = cbacks.control_result_cb_,
+          .session_changed_cb_ = cbacks.session_changed_cb_,
+          .audio_configuration_changed_cb_ = nullptr};
+      return session_ptr->RegisterStatusCback(cb);
+    }
+    return kObserversCookieUndefined;
+  }
+
+  // The control API helps the bluetooth_audio module to register
+  // PortStatusCallbacks_2_2
+  // @return: cookie - the assigned number to this bluetooth_audio output
+  static uint16_t RegisterControlResultCback(
+      const SessionType_2_1& session_type,
+      const PortStatusCallbacks_2_2& cbacks) {
+    std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
+        BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
+    if (session_ptr != nullptr) {
+      return session_ptr->RegisterStatusCback(cbacks);
     }
     return kObserversCookieUndefined;
   }
 
   // The control API helps the bluetooth_audio module to unregister
-  // PortStatusCallbacks
+  // PortStatusCallbacks and PortStatusCallbacks_2_2
   // @param: cookie - indicates which bluetooth_audio output is
   static void UnregisterControlResultCback(const SessionType_2_1& session_type,
                                            uint16_t cookie) {
     std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
         BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
     if (session_ptr != nullptr) {
-      session_ptr->GetAudioSession()->UnregisterStatusCback(cookie);
+      session_ptr->UnregisterStatusCback(cookie);
     }
   }
 
@@ -76,6 +94,12 @@
     } else if (session_type ==
                SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH) {
       return BluetoothAudioSession_2_2::kInvalidOffloadAudioConfiguration;
+    } else if (
+        session_type ==
+            SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
+        session_type ==
+            SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
+      return BluetoothAudioSession_2_2::kInvalidLeOffloadAudioConfiguration;
     } else {
       return BluetoothAudioSession_2_2::kInvalidSoftwareAudioConfiguration;
     }
@@ -87,7 +111,7 @@
     std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
         BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
     if (session_ptr != nullptr) {
-      return session_ptr->GetAudioSession()->StartStream();
+      return session_ptr->StartStream();
     }
     return false;
   }
@@ -96,7 +120,7 @@
     std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
         BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
     if (session_ptr != nullptr) {
-      return session_ptr->GetAudioSession()->SuspendStream();
+      return session_ptr->SuspendStream();
     }
     return false;
   }
@@ -105,7 +129,7 @@
     std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
         BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
     if (session_ptr != nullptr) {
-      session_ptr->GetAudioSession()->StopStream();
+      session_ptr->StopStream();
     }
   }
 
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSessionReport_2_2.h b/bluetooth/audio/utils/session/BluetoothAudioSessionReport_2_2.h
index 194259a..17e140e 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSessionReport_2_2.h
+++ b/bluetooth/audio/utils/session/BluetoothAudioSessionReport_2_2.h
@@ -48,7 +48,7 @@
     std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
         BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
     if (session_ptr != nullptr) {
-      session_ptr->GetAudioSession()->OnSessionEnded();
+      session_ptr->OnSessionEnded();
     }
   }
   // The API reports the Bluetooth stack has replied the result of startStream
@@ -60,7 +60,20 @@
     std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
         BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
     if (session_ptr != nullptr) {
-      session_ptr->GetAudioSession()->ReportControlStatus(start_resp, status);
+      session_ptr->ReportControlStatus(start_resp, status);
+    }
+  }
+  // The API reports the Bluetooth stack has replied the changed of the audio
+  // configuration, and will inform registered bluetooth_audio outputs
+  static void ReportAudioConfigChanged(
+      const ::android::hardware::bluetooth::audio::V2_1::SessionType&
+          session_type,
+      const ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration&
+          audio_config) {
+    std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
+        BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
+    if (session_ptr != nullptr) {
+      session_ptr->ReportAudioConfigChanged(audio_config);
     }
   }
 };
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.cpp b/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.cpp
index 646e225..bf1f9b5 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.cpp
+++ b/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.cpp
@@ -46,6 +46,19 @@
     return false;
   }
 }
+
+bool is_unsupported_2_1_session_type(
+    const ::android::hardware::bluetooth::audio::V2_1::SessionType&
+        session_type) {
+  if (session_type ==
+          SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
+      session_type ==
+          SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
+    return true;
+  } else {
+    return false;
+  }
+}
 }  // namespace
 
 BluetoothAudioSession_2_1::BluetoothAudioSession_2_1(
@@ -53,7 +66,8 @@
         session_type)
     : audio_session(BluetoothAudioSessionInstance::GetSessionInstance(
           static_cast<SessionType_2_0>(session_type))) {
-  if (is_2_0_session_type(session_type)) {
+  if (is_2_0_session_type(session_type) ||
+      is_unsupported_2_1_session_type(session_type)) {
     session_type_2_1_ = (SessionType_2_1::UNKNOWN);
   } else {
     session_type_2_1_ = (session_type);
@@ -80,7 +94,7 @@
     // pcmConfig only differs between 2.0 and 2.1 in AudioConfiguration
     if (fromConf.getDiscriminator() ==
         AudioConfiguration::hidl_discriminator::codecConfig) {
-      toConf.codecConfig() = fromConf.codecConfig();
+      toConf.codecConfig(fromConf.codecConfig());
     } else {
       toConf.pcmConfig() = {
           .sampleRate = static_cast<
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.cpp b/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.cpp
index 80df5d9..60ac4ec 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.cpp
+++ b/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.cpp
@@ -29,6 +29,13 @@
 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 ::android::hardware::bluetooth::audio::V2_0::BitsPerSample;
+using ::android::hardware::bluetooth::audio::V2_0::ChannelMode;
+using ::android::hardware::bluetooth::audio::V2_2::LeAudioConfiguration;
+using ::android::hardware::bluetooth::audio::V2_2::LeAudioMode;
+using PcmParameters_2_1 =
+    ::android::hardware::bluetooth::audio::V2_1::PcmParameters;
+using SampleRate_2_1 = ::android::hardware::bluetooth::audio::V2_1::SampleRate;
 
 using SessionType_2_1 =
     ::android::hardware::bluetooth::audio::V2_1::SessionType;
@@ -38,10 +45,24 @@
 using AudioConfiguration_2_1 =
     ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration;
 
+static constexpr PcmParameters_2_1 kInvalidPcmParameters = {
+    .sampleRate = SampleRate_2_1::RATE_UNKNOWN,
+    .channelMode = ChannelMode::UNKNOWN,
+    .bitsPerSample = BitsPerSample::BITS_UNKNOWN,
+    .dataIntervalUs = 0,
+};
+
+static LeAudioConfiguration kInvalidLeAudioConfig = {
+    .mode = LeAudioMode::UNKNOWN,
+    .config = {},
+};
+
 ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration
     BluetoothAudioSession_2_2::invalidSoftwareAudioConfiguration = {};
 ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration
     BluetoothAudioSession_2_2::invalidOffloadAudioConfiguration = {};
+::android::hardware::bluetooth::audio::V2_2::AudioConfiguration
+    BluetoothAudioSession_2_2::invalidLeOffloadAudioConfiguration = {};
 
 using IBluetoothAudioPort_2_2 =
     ::android::hardware::bluetooth::audio::V2_2::IBluetoothAudioPort;
@@ -72,11 +93,17 @@
   } else {
     session_type_2_1_ = (session_type);
   }
+  invalidSoftwareAudioConfiguration.pcmConfig(kInvalidPcmParameters);
+  invalidOffloadAudioConfiguration.codecConfig(
+      audio_session->kInvalidCodecConfiguration);
+  invalidLeOffloadAudioConfiguration.leAudioConfig(kInvalidLeAudioConfig);
 }
 
 bool BluetoothAudioSession_2_2::IsSessionReady() {
   if (session_type_2_1_ !=
-      SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
+          SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
+      session_type_2_1_ !=
+          SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
     return audio_session->IsSessionReady();
   }
 
@@ -147,9 +174,17 @@
 BluetoothAudioSession_2_2::GetAudioConfig() {
   std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_);
   if (IsSessionReady()) {
+    auto audio_config_discriminator = audio_config_2_2_.getDiscriminator();
     // If session is unknown it means it should be 2.0 type
     if (session_type_2_1_ != SessionType_2_1::UNKNOWN) {
-      if (audio_config_2_2_ != invalidSoftwareAudioConfiguration)
+      if ((audio_config_discriminator ==
+               ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration::
+                   hidl_discriminator::pcmConfig &&
+           audio_config_2_2_ != kInvalidSoftwareAudioConfiguration) ||
+          (audio_config_discriminator ==
+               ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration::
+                   hidl_discriminator::leAudioConfig &&
+           audio_config_2_2_ != kInvalidLeOffloadAudioConfiguration))
         return audio_config_2_2_;
 
       ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration toConf;
@@ -157,7 +192,7 @@
           GetAudioSession_2_1()->GetAudioConfig();
       if (fromConf.getDiscriminator() ==
           AudioConfiguration_2_1::hidl_discriminator::pcmConfig) {
-        toConf.pcmConfig() = fromConf.pcmConfig();
+        toConf.pcmConfig(fromConf.pcmConfig());
         return toConf;
       }
     }
@@ -167,7 +202,7 @@
     // pcmConfig only differs between 2.0 and 2.1 in AudioConfiguration
     if (fromConf.getDiscriminator() ==
         AudioConfiguration::hidl_discriminator::codecConfig) {
-      toConf.codecConfig() = fromConf.codecConfig();
+      toConf.codecConfig(fromConf.codecConfig());
     } else {
       toConf.pcmConfig() = {
           .sampleRate = static_cast<
@@ -179,13 +214,61 @@
     }
     return toConf;
   } else if (session_type_2_1_ ==
-             SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH) {
-    return kInvalidOffloadAudioConfiguration;
+                 SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
+             session_type_2_1_ ==
+                 SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
+    return kInvalidLeOffloadAudioConfiguration;
   } else {
     return kInvalidSoftwareAudioConfiguration;
   }
 }
 
+// Those control functions are for the bluetooth_audio module to start, suspend,
+// stop stream, to check position, and to update metadata.
+bool BluetoothAudioSession_2_2::StartStream() {
+  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 false;
+  }
+  auto hal_retval = audio_session->stack_iface_->startStream();
+  if (!hal_retval.isOk()) {
+    LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
+                 << toString(session_type_2_1_) << " failed";
+    return false;
+  }
+  return true;
+}
+
+bool BluetoothAudioSession_2_2::SuspendStream() {
+  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 false;
+  }
+  auto hal_retval = audio_session->stack_iface_->suspendStream();
+  if (!hal_retval.isOk()) {
+    LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
+                 << toString(session_type_2_1_) << " failed";
+    return false;
+  }
+  return true;
+}
+
+void BluetoothAudioSession_2_2::StopStream() {
+  std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_);
+  if (!IsSessionReady()) {
+    return;
+  }
+  auto hal_retval = audio_session->stack_iface_->stopStream();
+  if (!hal_retval.isOk()) {
+    LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
+                 << toString(session_type_2_1_) << " failed";
+  }
+}
+
 bool BluetoothAudioSession_2_2::UpdateAudioConfig(
     const ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration&
         audio_config) {
@@ -266,18 +349,190 @@
       LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_2_1_)
                  << " DataMQ Invalid";
       audio_config_2_2_ =
-          (session_type_2_1_ == SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH
-               ? kInvalidOffloadAudioConfiguration
+          ((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)
+               ? kInvalidLeOffloadAudioConfiguration
                : kInvalidSoftwareAudioConfiguration);
     } else {
       audio_session->stack_iface_ = stack_iface;
       LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_2_1_)
                 << ", AudioConfiguration=" << toString(audio_config);
-      audio_session->ReportSessionStatus();
+      ReportSessionStatus();
     };
   }
 }
 
+// The report function is used to report that the Bluetooth stack has ended the
+// session, and will invoke session_changed_cb_ to notify registered
+// bluetooth_audio outputs
+void BluetoothAudioSession_2_2::OnSessionEnded() {
+  std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_);
+  bool toggled = IsSessionReady();
+  LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_2_1_);
+  if (session_type_2_1_ == SessionType_2_1::UNKNOWN) {
+    audio_session->OnSessionEnded();
+    return;
+  }
+
+  audio_config_2_2_ =
+      ((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)
+           ? kInvalidLeOffloadAudioConfiguration
+           : kInvalidSoftwareAudioConfiguration);
+  audio_session->stack_iface_ = nullptr;
+  audio_session->UpdateDataPath(nullptr);
+  if (toggled) {
+    ReportSessionStatus();
+  }
+}
+
+// The control function helps the bluetooth_audio module to register
+// PortStatusCallbacks_2_2
+// @return: cookie - the assigned number to this bluetooth_audio output
+uint16_t BluetoothAudioSession_2_2::RegisterStatusCback(
+    const PortStatusCallbacks_2_2& cbacks) {
+  if (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) {
+    PortStatusCallbacks cb = {
+        .control_result_cb_ = cbacks.control_result_cb_,
+        .session_changed_cb_ = cbacks.session_changed_cb_};
+    return audio_session->RegisterStatusCback(cb);
+  }
+
+  std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_);
+  uint16_t cookie = ObserversCookieGetInitValue(session_type_2_1_);
+  uint16_t cookie_upper_bound = ObserversCookieGetUpperBound(session_type_2_1_);
+
+  while (cookie < cookie_upper_bound) {
+    if (observers_.find(cookie) == observers_.end()) {
+      break;
+    }
+    ++cookie;
+  }
+  if (cookie >= cookie_upper_bound) {
+    LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_2_1_)
+               << " has " << observers_.size()
+               << " observers already (No Resource)";
+    return kObserversCookieUndefined;
+  }
+  std::shared_ptr<struct PortStatusCallbacks_2_2> cb =
+      std::make_shared<struct PortStatusCallbacks_2_2>();
+  *cb = cbacks;
+  observers_[cookie] = cb;
+  return cookie;
+}
+
+// The control function helps the bluetooth_audio module to unregister
+// PortStatusCallbacks_2_2
+// @param: cookie - indicates which bluetooth_audio output is
+void BluetoothAudioSession_2_2::UnregisterStatusCback(uint16_t cookie) {
+  std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_);
+  if (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) {
+    audio_session->UnregisterStatusCback(cookie);
+    return;
+  }
+  if (observers_.erase(cookie) != 1) {
+    LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_2_1_)
+                 << " no such provider=0x"
+                 << android::base::StringPrintf("%04x", cookie);
+  }
+}
+
+// invoking the registered session_changed_cb_
+void BluetoothAudioSession_2_2::ReportSessionStatus() {
+  // This is locked already by OnSessionStarted / OnSessionEnded
+  if (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) {
+    audio_session->ReportSessionStatus();
+    return;
+  }
+  if (observers_.empty()) {
+    LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_2_1_)
+              << " has NO port state observer";
+    return;
+  }
+  for (auto& observer : observers_) {
+    uint16_t cookie = observer.first;
+    std::shared_ptr<struct PortStatusCallbacks_2_2> cb = observer.second;
+    LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_2_1_)
+              << " notify to bluetooth_audio=0x"
+              << android::base::StringPrintf("%04x", cookie);
+    cb->session_changed_cb_(cookie);
+  }
+}
+
+// The report function is used to report that the Bluetooth stack has notified
+// the result of startStream or suspendStream, and will invoke
+// control_result_cb_ to notify registered bluetooth_audio outputs
+void BluetoothAudioSession_2_2::ReportControlStatus(
+    bool start_resp, const BluetoothAudioStatus& status) {
+  if (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) {
+    audio_session->ReportControlStatus(start_resp, status);
+    return;
+  }
+  std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_);
+  if (observers_.empty()) {
+    LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_2_1_)
+                 << " has NO port state observer";
+    return;
+  }
+  for (auto& observer : observers_) {
+    uint16_t cookie = observer.first;
+    std::shared_ptr<struct PortStatusCallbacks_2_2> cb = observer.second;
+    LOG(INFO) << __func__ << " - status=" << toString(status)
+              << " for SessionType=" << toString(session_type_2_1_)
+              << ", bluetooth_audio=0x"
+              << android::base::StringPrintf("%04x", cookie)
+              << (start_resp ? " started" : " suspended");
+    cb->control_result_cb_(cookie, start_resp, status);
+  }
+}
+
+// The report function is used to report that the Bluetooth stack has notified
+// the result of startStream or suspendStream, and will invoke
+// control_result_cb_ to notify registered bluetooth_audio outputs
+void BluetoothAudioSession_2_2::ReportAudioConfigChanged(
+    const ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration&
+        audio_config) {
+  if (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) {
+    return;
+  }
+  std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_);
+  audio_config_2_2_ = audio_config;
+  if (observers_.empty()) {
+    LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_2_1_)
+                 << " has NO port state observer";
+    return;
+  }
+  for (auto& observer : observers_) {
+    uint16_t cookie = observer.first;
+    std::shared_ptr<struct PortStatusCallbacks_2_2> cb = observer.second;
+    LOG(INFO) << __func__ << " for SessionType=" << toString(session_type_2_1_)
+              << ", bluetooth_audio=0x"
+              << android::base::StringPrintf("%04x", cookie);
+    if (cb->audio_configuration_changed_cb_ != nullptr) {
+      cb->audio_configuration_changed_cb_(cookie);
+    }
+  }
+}
+
 std::unique_ptr<BluetoothAudioSessionInstance_2_2>
     BluetoothAudioSessionInstance_2_2::instance_ptr =
         std::unique_ptr<BluetoothAudioSessionInstance_2_2>(
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.h b/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.h
index d6ae3d7..3673fd8 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.h
+++ b/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.h
@@ -28,6 +28,40 @@
 namespace bluetooth {
 namespace audio {
 
+inline uint16_t ObserversCookieGetInitValue(
+    const ::android::hardware::bluetooth::audio::V2_1::SessionType&
+        session_type) {
+  return (static_cast<uint16_t>(session_type) << 8 & 0xff00);
+}
+inline uint16_t ObserversCookieGetUpperBound(
+    const ::android::hardware::bluetooth::audio::V2_1::SessionType&
+        session_type) {
+  return (static_cast<uint16_t>(session_type) << 8 & 0xff00) +
+         kObserversCookieSize;
+}
+
+struct PortStatusCallbacks_2_2 {
+  // control_result_cb_ - when the Bluetooth stack reports results of
+  // streamStarted or streamSuspended, the BluetoothAudioProvider will invoke
+  // this callback to report to the bluetooth_audio module.
+  // @param: cookie - indicates which bluetooth_audio output should handle
+  // @param: start_resp - this report is for startStream or not
+  // @param: status - the result of startStream
+  std::function<void(uint16_t cookie, bool start_resp,
+                     const BluetoothAudioStatus& status)>
+      control_result_cb_;
+  // session_changed_cb_ - when the Bluetooth stack start / end session, the
+  // BluetoothAudioProvider will invoke this callback to notify to the
+  // bluetooth_audio module.
+  // @param: cookie - indicates which bluetooth_audio output should handle
+  std::function<void(uint16_t cookie)> session_changed_cb_;
+  // audio_configuration_changed_cb_ - when the Bluetooth stack change the audio
+  // configuration, the BluetoothAudioProvider will invoke this callback to
+  // notify to the bluetooth_audio module.
+  // @param: cookie - indicates which bluetooth_audio output should handle
+  std::function<void(uint16_t cookie)> audio_configuration_changed_cb_;
+};
+
 class BluetoothAudioSession_2_2 {
  private:
   std::shared_ptr<BluetoothAudioSession> audio_session;
@@ -47,6 +81,15 @@
       invalidSoftwareAudioConfiguration;
   static ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration
       invalidOffloadAudioConfiguration;
+  static ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration
+      invalidLeOffloadAudioConfiguration;
+
+  // saving those registered bluetooth_audio's callbacks
+  std::unordered_map<uint16_t, std::shared_ptr<struct PortStatusCallbacks_2_2>>
+      observers_;
+
+  // invoking the registered session_changed_cb_
+  void ReportSessionStatus();
 
  public:
   BluetoothAudioSession_2_2(
@@ -69,6 +112,40 @@
       const ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration&
           audio_config);
 
+  // The report function is used to report that the Bluetooth stack has ended
+  // the session, and will invoke session_changed_cb_ to notify registered
+  // bluetooth_audio outputs
+  void OnSessionEnded();
+
+  // Those control functions are for the bluetooth_audio module to start,
+  // suspend, stop stream, to check position, and to update metadata.
+  bool StartStream();
+  bool SuspendStream();
+  void StopStream();
+
+  // The control function helps the bluetooth_audio module to register
+  // PortStatusCallbacks_2_2
+  // @return: cookie - the assigned number to this bluetooth_audio output
+  uint16_t RegisterStatusCback(const PortStatusCallbacks_2_2& cbacks);
+
+  // The control function helps the bluetooth_audio module to unregister
+  // PortStatusCallbacks_2_2
+  // @param: cookie - indicates which bluetooth_audio output is
+  void UnregisterStatusCback(uint16_t cookie);
+
+  // The report function is used to report that the Bluetooth stack has notified
+  // the result of startStream or suspendStream, and will invoke
+  // control_result_cb_ to notify registered bluetooth_audio outputs
+  void ReportControlStatus(bool start_resp, const BluetoothAudioStatus& status);
+
+  // The report function is used to report that the Bluetooth stack has notified
+  // the audio configuration changed, and will invoke
+  // audio_configuration_changed_cb_ to notify registered bluetooth_audio
+  // outputs
+  void ReportAudioConfigChanged(
+      const ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration&
+          audio_config);
+
   // The control function is for the bluetooth_audio module to get the current
   // AudioConfiguration
   const ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration
@@ -82,6 +159,9 @@
   static constexpr ::android::hardware::bluetooth::audio::V2_2::
       AudioConfiguration& kInvalidOffloadAudioConfiguration =
           invalidOffloadAudioConfiguration;
+  static constexpr ::android::hardware::bluetooth::audio::V2_2::
+      AudioConfiguration& kInvalidLeOffloadAudioConfiguration =
+          invalidLeOffloadAudioConfiguration;
 };
 
 class BluetoothAudioSessionInstance_2_2 {
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_2.cpp b/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_2.cpp
index 5becdaa..4c99b0f 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_2.cpp
+++ b/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_2.cpp
@@ -24,9 +24,63 @@
 namespace bluetooth {
 namespace audio {
 
+using ::android::hardware::bluetooth::audio::V2_0::BitsPerSample;
+using ::android::hardware::bluetooth::audio::V2_1::CodecType;
+using ::android::hardware::bluetooth::audio::V2_1::Lc3FrameDuration;
+using ::android::hardware::bluetooth::audio::V2_1::Lc3Parameters;
+using ::android::hardware::bluetooth::audio::V2_1::SampleRate;
+using ::android::hardware::bluetooth::audio::V2_2::AudioLocation;
+using ::android::hardware::bluetooth::audio::V2_2::BroadcastCapability;
+using ::android::hardware::bluetooth::audio::V2_2::
+    LeAudioCodecCapabilitiesSetting;
+using ::android::hardware::bluetooth::audio::V2_2::UnicastCapability;
 using SessionType_2_1 =
     ::android::hardware::bluetooth::audio::V2_1::SessionType;
 
+// Stores the list of offload supported capability
+std::vector<LeAudioCodecCapabilitiesSetting> kDefaultOffloadLeAudioCapabilities;
+
+static const UnicastCapability kInvalidUnicastCapability = {
+    .codecType = CodecType::UNKNOWN};
+
+static const BroadcastCapability kInvalidBroadcastCapability = {
+    .codecType = CodecType::UNKNOWN};
+
+// Default Supported Codecs
+// LC3 16_1: sample rate: 16 kHz, frame duration: 7.5 ms, octets per frame: 30
+static const Lc3Parameters kLc3Capability_16_1 = {
+    .samplingFrequency = SampleRate::RATE_16000,
+    .frameDuration = Lc3FrameDuration::DURATION_7500US,
+    .octetsPerFrame = 30};
+
+// Default Supported Codecs
+// LC3 16_2: sample rate: 16 kHz, frame duration: 10 ms, octets per frame: 40
+static const Lc3Parameters kLc3Capability_16_2 = {
+    .samplingFrequency = SampleRate::RATE_16000,
+    .frameDuration = Lc3FrameDuration::DURATION_10000US,
+    .octetsPerFrame = 40};
+
+// Default Supported Codecs
+// LC3 48_4: sample rate: 48 kHz, frame duration: 10 ms, octets per frame: 120
+static const Lc3Parameters kLc3Capability_48_4 = {
+    .samplingFrequency = SampleRate::RATE_48000,
+    .frameDuration = Lc3FrameDuration::DURATION_10000US,
+    .octetsPerFrame = 120};
+
+static const std::vector<Lc3Parameters> supportedLc3CapabilityList = {
+    kLc3Capability_48_4, kLc3Capability_16_2, kLc3Capability_16_1};
+
+static AudioLocation stereoAudio = static_cast<AudioLocation>(
+    AudioLocation::FRONT_LEFT | AudioLocation::FRONT_RIGHT);
+static AudioLocation monoAudio = AudioLocation::UNKNOWN;
+
+// Stores the supported setting of audio location, connected device, and the
+// channel count for each device
+std::vector<std::tuple<AudioLocation, uint8_t, uint8_t>>
+    supportedDeviceSetting = {std::make_tuple(stereoAudio, 2, 1),
+                              std::make_tuple(monoAudio, 1, 2),
+                              std::make_tuple(monoAudio, 1, 1)};
+
 bool IsOffloadLeAudioConfigurationValid(
     const ::android::hardware::bluetooth::audio::V2_1::SessionType&
         session_type,
@@ -44,6 +98,60 @@
   return true;
 }
 
+UnicastCapability composeUnicastLc3Capability(AudioLocation audioLocation,
+                                              uint8_t deviceCnt,
+                                              uint8_t channelCount,
+                                              Lc3Parameters capability) {
+  return UnicastCapability{.codecType = CodecType::LC3,
+                           .supportedChannel = audioLocation,
+                           .deviceCount = deviceCnt,
+                           .channelCountPerDevice = channelCount,
+                           .capabilities = capability};
+}
+
+std::vector<LeAudioCodecCapabilitiesSetting> GetLeAudioOffloadCodecCapabilities(
+    const SessionType_2_1& session_type) {
+  if (session_type !=
+          SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
+      session_type !=
+          SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
+    return std::vector<LeAudioCodecCapabilitiesSetting>(0);
+  }
+
+  if (kDefaultOffloadLeAudioCapabilities.empty()) {
+    for (auto [audioLocation, deviceCnt, channelCount] :
+         supportedDeviceSetting) {
+      for (auto capability : supportedLc3CapabilityList) {
+        UnicastCapability lc3Capability = composeUnicastLc3Capability(
+            audioLocation, deviceCnt, channelCount, capability);
+        UnicastCapability lc3MonoDecodeCapability =
+            composeUnicastLc3Capability(monoAudio, 1, 1, capability);
+
+        // Adds the capability for encode only
+        kDefaultOffloadLeAudioCapabilities.push_back(
+            {.unicastEncodeCapability = lc3Capability,
+             .unicastDecodeCapability = kInvalidUnicastCapability,
+             .broadcastCapability = kInvalidBroadcastCapability});
+
+        // Adds the capability for decode only
+        kDefaultOffloadLeAudioCapabilities.push_back(
+            {.unicastEncodeCapability = kInvalidUnicastCapability,
+             .unicastDecodeCapability = lc3Capability,
+             .broadcastCapability = kInvalidBroadcastCapability});
+
+        // Adds the capability for the case that encode and decode exist at the
+        // same time
+        kDefaultOffloadLeAudioCapabilities.push_back(
+            {.unicastEncodeCapability = lc3Capability,
+             .unicastDecodeCapability = lc3MonoDecodeCapability,
+             .broadcastCapability = kInvalidBroadcastCapability});
+      }
+    }
+  }
+
+  return kDefaultOffloadLeAudioCapabilities;
+}
+
 }  // namespace audio
 }  // namespace bluetooth
 }  // namespace android
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_2.h b/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_2.h
index 59d22b7..34bba5f 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_2.h
+++ b/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_2.h
@@ -19,6 +19,7 @@
 #include <android/hardware/bluetooth/audio/2.2/types.h>
 
 #include "BluetoothAudioSupportedCodecsDB.h"
+#include "BluetoothAudioSupportedCodecsDB_2_1.h"
 
 namespace android {
 namespace bluetooth {
@@ -29,6 +30,11 @@
         session_type,
     const ::android::hardware::bluetooth::audio::V2_2::LeAudioConfiguration&
         le_audio_codec_config);
+
+std::vector<hardware::bluetooth::audio::V2_2::LeAudioCodecCapabilitiesSetting>
+GetLeAudioOffloadCodecCapabilities(
+    const ::android::hardware::bluetooth::audio::V2_1::SessionType&
+        session_type);
 }  // namespace audio
 }  // namespace bluetooth
 }  // namespace android
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/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index 77974fc..d39850d 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>
@@ -666,7 +667,7 @@
 
         void waitForBuffersReturned();
 
-     private:
+      private:
         bool processCaptureResultLocked(const CaptureResult& results,
                 hidl_vec<PhysicalCameraMetadata> physicalCameraMetadata);
         Return<void> notifyHelper(const hidl_vec<NotifyMsg>& msgs,
@@ -906,11 +907,12 @@
 
     static Status getMandatoryConcurrentStreams(const camera_metadata_t* staticMeta,
                                                 std::vector<AvailableStream>* outputStreams);
-
+    static bool supportsPreviewStabilization(const std::string& name, sp<ICameraProvider> provider);
     static Status getJpegBufferSize(camera_metadata_t *staticMeta,
             uint32_t* outBufSize);
     static Status isConstrainedModeAvailable(camera_metadata_t *staticMeta);
     static Status isLogicalMultiCamera(const camera_metadata_t *staticMeta);
+    static 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*/);
@@ -953,6 +955,9 @@
 
     void processCaptureRequestInternal(uint64_t bufferusage, RequestTemplate reqTemplate,
                                        bool useSecureOnlyCameras);
+    void processPreviewStabilizationCaptureRequestInternal(
+            bool previewStabilizationOn,
+            /*inout*/ std::unordered_map<std::string, nsecs_t>& cameraDeviceToTimeLag);
 
     // Used by switchToOffline where a new result queue is created for offline reqs
     void updateInflightResultQueue(std::shared_ptr<ResultMetadataQueue> resultQueue);
@@ -1006,7 +1011,11 @@
 
         // Buffers are added by process_capture_result when output buffers
         // return from HAL but framework.
-        ::android::Vector<StreamBuffer> resultOutputBuffers;
+        struct StreamBufferAndTimestamp {
+            StreamBuffer buffer;
+            nsecs_t timeStamp;
+        };
+        ::android::Vector<StreamBufferAndTimestamp> resultOutputBuffers;
 
         std::unordered_set<std::string> expectedPhysicalResults;
 
@@ -1421,8 +1430,25 @@
         return notify;
     }
 
-    request->resultOutputBuffers.appendArray(results.outputBuffers.data(),
-            results.outputBuffers.size());
+    for (const auto& buffer : results.outputBuffers) {
+        // wait for the fence timestamp and store it along with the buffer
+        // TODO: Check if we really need the dup here
+        sp<android::Fence> releaseFence = nullptr;
+        if (buffer.releaseFence && (buffer.releaseFence->numFds == 1) &&
+            buffer.releaseFence->data[0] >= 0) {
+            releaseFence = new android::Fence(dup(buffer.releaseFence->data[0]));
+        }
+        InFlightRequest::StreamBufferAndTimestamp streamBufferAndTimestamp;
+        streamBufferAndTimestamp.buffer = buffer;
+        streamBufferAndTimestamp.timeStamp = systemTime();
+        if (releaseFence && releaseFence->isValid()) {
+            releaseFence->wait(/*ms*/ 300);
+            nsecs_t releaseTime = releaseFence->getSignalTime();
+            if (streamBufferAndTimestamp.timeStamp < releaseTime)
+                streamBufferAndTimestamp.timeStamp = releaseTime;
+        }
+        request->resultOutputBuffers.push_back(streamBufferAndTimestamp);
+    }
     // If shutter event is received notify the pending threads.
     if (request->shutterTimestamp != 0) {
         notify = true;
@@ -2933,6 +2959,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) {
@@ -4793,7 +4950,7 @@
 
             ASSERT_FALSE(inflightReq.errorCodeValid);
             ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u);
-            ASSERT_EQ(testStream.id, inflightReq.resultOutputBuffers[0].streamId);
+            ASSERT_EQ(testStream.id, inflightReq.resultOutputBuffers[0].buffer.streamId);
 
             // For camera device 3.8 or newer, shutterReadoutTimestamp must be
             // available, and it must be >= shutterTimestamp + exposureTime, and
@@ -4853,7 +5010,197 @@
 
             ASSERT_FALSE(inflightReq.errorCodeValid);
             ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u);
-            ASSERT_EQ(testStream.id, inflightReq.resultOutputBuffers[0].streamId);
+            ASSERT_EQ(testStream.id, inflightReq.resultOutputBuffers[0].buffer.streamId);
+        }
+
+        if (useHalBufManager) {
+            verifyBuffersReturned(session, deviceVersion, testStream.id, cb);
+        }
+
+        ret = session->close();
+        ASSERT_TRUE(ret.isOk());
+    }
+}
+
+TEST_P(CameraHidlTest, processCaptureRequestPreviewStabilization) {
+    std::unordered_map<std::string, nsecs_t> cameraDeviceToTimeLag;
+    processPreviewStabilizationCaptureRequestInternal(/*previewStabilizationOn*/ false,
+                                                      cameraDeviceToTimeLag);
+    processPreviewStabilizationCaptureRequestInternal(/*previewStabilizationOn*/ true,
+                                                      cameraDeviceToTimeLag);
+}
+
+void CameraHidlTest::processPreviewStabilizationCaptureRequestInternal(
+        bool previewStabilizationOn,
+        // Used as output when preview stabilization is off, as output when its
+        // on.
+        std::unordered_map<std::string, nsecs_t>& cameraDeviceToTimeLag) {
+    hidl_vec<hidl_string> cameraDeviceNames = getCameraDeviceNames(mProvider);
+    AvailableStream streamThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
+                                       static_cast<int32_t>(PixelFormat::IMPLEMENTATION_DEFINED)};
+    uint64_t bufferId = 1;
+    uint32_t frameNumber = 1;
+    ::android::hardware::hidl_vec<uint8_t> settings;
+
+    for (const auto& name : cameraDeviceNames) {
+        int deviceVersion = getCameraDeviceVersion(name, mProviderType);
+        if (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) {
+            continue;
+        } else if (deviceVersion <= 0) {
+            ALOGE("%s: Unsupported device version %d", __func__, deviceVersion);
+            ADD_FAILURE();
+            return;
+        }
+
+        if (!supportsPreviewStabilization(name, mProvider)) {
+            ALOGI(" %s Camera device %s doesn't support preview stabilization, skipping", __func__,
+                  name.c_str());
+            continue;
+        }
+
+        if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_8) {
+            ALOGE("%s: device version < 3.8 must not advertise preview stabilization,"
+                  " camera metadata validation will fail",
+                  __func__);
+            ADD_FAILURE();
+        }
+
+        V3_2::Stream testStream;
+        HalStreamConfiguration halStreamConfig;
+        sp<ICameraDeviceSession> session;
+        sp<DeviceCb> cb;
+        bool supportsPartialResults = false;
+        bool useHalBufManager = false;
+        uint32_t partialResultCount = 0;
+        configureSingleStream(name, deviceVersion, mProvider, &streamThreshold,
+                              GRALLOC1_CONSUMER_USAGE_HWCOMPOSER, RequestTemplate::PREVIEW,
+                              &session /*out*/, &testStream /*out*/, &halStreamConfig /*out*/,
+                              &supportsPartialResults /*out*/, &partialResultCount /*out*/,
+                              &useHalBufManager /*out*/, &cb /*out*/);
+
+        std::shared_ptr<ResultMetadataQueue> resultQueue;
+        auto resultQueueRet =
+                session->getCaptureResultMetadataQueue([&resultQueue](const auto& descriptor) {
+                    resultQueue = std::make_shared<ResultMetadataQueue>(descriptor);
+                    if (!resultQueue->isValid() || resultQueue->availableToWrite() <= 0) {
+                        ALOGE("%s: HAL returns empty result metadata fmq,"
+                              " not use it",
+                              __func__);
+                        resultQueue = nullptr;
+                        // Don't use the queue onwards.
+                    }
+                });
+        ASSERT_TRUE(resultQueueRet.isOk());
+
+        InFlightRequest inflightReq = {1, false, supportsPartialResults, partialResultCount,
+                                       resultQueue};
+
+        Return<void> ret;
+        android::hardware::camera::common::V1_0::helper::CameraMetadata defaultSettings;
+        ret = session->constructDefaultRequestSettings(
+                RequestTemplate::PREVIEW, [&](auto status, const auto& req) {
+                    ASSERT_EQ(Status::OK, status);
+                    const camera_metadata_t* metadata =
+                            reinterpret_cast<const camera_metadata_t*>(req.data());
+                    defaultSettings = metadata;
+                    settings = req;
+                });
+        ASSERT_TRUE(ret.isOk());
+        android::status_t metadataRet = ::android::OK;
+        uint8_t videoStabilizationMode = ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF;
+        if (previewStabilizationOn) {
+            videoStabilizationMode = ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_PREVIEW_STABILIZATION;
+            metadataRet = defaultSettings.update(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
+                                                 &videoStabilizationMode, 1);
+        } else {
+            metadataRet = defaultSettings.update(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
+                                                 &videoStabilizationMode, 1);
+        }
+        ASSERT_EQ(metadataRet, ::android::OK);
+        hidl_handle buffer_handle;
+        StreamBuffer outputBuffer;
+        if (useHalBufManager) {
+            outputBuffer = {halStreamConfig.streams[0].id,
+                            /*bufferId*/ 0,
+                            buffer_handle,
+                            BufferStatus::OK,
+                            nullptr,
+                            nullptr};
+        } else {
+            allocateGraphicBuffer(
+                    testStream.width, testStream.height,
+                    /* We don't look at halStreamConfig.streams[0].consumerUsage
+                     * since that is 0 for output streams
+                     */
+                    android_convertGralloc1To0Usage(halStreamConfig.streams[0].producerUsage,
+                                                    GRALLOC1_CONSUMER_USAGE_HWCOMPOSER),
+                    halStreamConfig.streams[0].overrideFormat, &buffer_handle);
+            outputBuffer = {halStreamConfig.streams[0].id,
+                            bufferId,
+                            buffer_handle,
+                            BufferStatus::OK,
+                            nullptr,
+                            nullptr};
+        }
+        ::android::hardware::hidl_vec<StreamBuffer> outputBuffers = {outputBuffer};
+        StreamBuffer emptyInputBuffer = {-1, 0, nullptr, BufferStatus::ERROR, nullptr, nullptr};
+        CaptureRequest request = {frameNumber, 0 /* fmqSettingsSize */, settings, emptyInputBuffer,
+                                  outputBuffers};
+
+        {
+            std::unique_lock<std::mutex> l(mLock);
+            mInflightMap.clear();
+            mInflightMap.add(frameNumber, &inflightReq);
+        }
+
+        Status status = Status::INTERNAL_ERROR;
+        uint32_t numRequestProcessed = 0;
+        hidl_vec<BufferCache> cachesToRemove;
+        Return<void> returnStatus = session->processCaptureRequest(
+                {request}, cachesToRemove, [&status, &numRequestProcessed](auto s, uint32_t n) {
+                    status = s;
+                    numRequestProcessed = n;
+                });
+        ASSERT_TRUE(returnStatus.isOk());
+        ASSERT_EQ(Status::OK, status);
+        ASSERT_EQ(numRequestProcessed, 1u);
+
+        {
+            std::unique_lock<std::mutex> l(mLock);
+            while (!inflightReq.errorCodeValid &&
+                   ((0 < inflightReq.numBuffersLeft) || (!inflightReq.haveResultMetadata))) {
+                auto timeout = std::chrono::system_clock::now() +
+                               std::chrono::seconds(kStreamBufferTimeoutSec);
+                ASSERT_NE(std::cv_status::timeout, mResultCondition.wait_until(l, timeout));
+            }
+
+            ASSERT_FALSE(inflightReq.errorCodeValid);
+            ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u);
+            ASSERT_EQ(testStream.id, inflightReq.resultOutputBuffers[0].buffer.streamId);
+            ASSERT_TRUE(inflightReq.shutterReadoutTimestampValid);
+            nsecs_t readoutTimestamp = inflightReq.shutterReadoutTimestamp;
+
+            if (previewStabilizationOn) {
+                // Here we collect the time difference between the buffer ready
+                // timestamp - notify readout timestamp.
+                // timeLag = buffer ready timestamp - notify readout timestamp.
+                // timeLag(previewStabilization) must be <=
+                //        timeLag(stabilization off) + 1 frame duration.
+                auto it = cameraDeviceToTimeLag.find(name.c_str());
+                camera_metadata_entry e;
+                e = inflightReq.collectedResult.find(ANDROID_SENSOR_FRAME_DURATION);
+                ASSERT_TRUE(e.count > 0);
+                nsecs_t frameDuration = e.data.i64[0];
+                ASSERT_TRUE(it != cameraDeviceToTimeLag.end());
+
+                nsecs_t previewStabOnLagTime =
+                        inflightReq.resultOutputBuffers[0].timeStamp - readoutTimestamp;
+                ASSERT_TRUE(previewStabOnLagTime <= (it->second + frameDuration));
+            } else {
+                // Fill in the buffer ready timestamp - notify timestamp;
+                cameraDeviceToTimeLag[std::string(name.c_str())] =
+                        inflightReq.resultOutputBuffers[0].timeStamp - readoutTimestamp;
+            }
         }
 
         if (useHalBufManager) {
@@ -5434,7 +5781,7 @@
 
             ASSERT_FALSE(inflightReqs[i].errorCodeValid);
             ASSERT_NE(inflightReqs[i].resultOutputBuffers.size(), 0u);
-            ASSERT_EQ(previewStream.id, inflightReqs[i].resultOutputBuffers[0].streamId);
+            ASSERT_EQ(previewStream.id, inflightReqs[i].resultOutputBuffers[0].buffer.streamId);
             ASSERT_FALSE(inflightReqs[i].collectedResult.isEmpty());
             ASSERT_TRUE(inflightReqs[i].collectedResult.exists(ANDROID_SENSOR_SENSITIVITY));
             camera_metadata_entry_t isoResult = inflightReqs[i].collectedResult.find(
@@ -5718,7 +6065,7 @@
 
             ASSERT_FALSE(inflightReqs[i].errorCodeValid);
             ASSERT_NE(inflightReqs[i].resultOutputBuffers.size(), 0u);
-            ASSERT_EQ(stream.id, inflightReqs[i].resultOutputBuffers[0].streamId);
+            ASSERT_EQ(stream.id, inflightReqs[i].resultOutputBuffers[0].buffer.streamId);
             ASSERT_FALSE(inflightReqs[i].collectedResult.isEmpty());
         }
 
@@ -5914,7 +6261,7 @@
 
             if (!inflightReq.errorCodeValid) {
                 ASSERT_NE(inflightReq.resultOutputBuffers.size(), 0u);
-                ASSERT_EQ(previewStream.id, inflightReq.resultOutputBuffers[0].streamId);
+                ASSERT_EQ(previewStream.id, inflightReq.resultOutputBuffers[0].buffer.streamId);
             } else {
                 switch (inflightReq.errorCode) {
                     case ErrorCode::ERROR_REQUEST:
@@ -6600,6 +6947,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;
@@ -7536,6 +7899,47 @@
                           previewStream, halStreamConfig, supportsPartialResults,
                           partialResultCount, useHalBufManager, outCb, streamConfigCounter);
 }
+
+bool CameraHidlTest::supportsPreviewStabilization(const std::string& name,
+                                                  sp<ICameraProvider> provider) {
+    Return<void> ret;
+    sp<ICameraDevice> device3_x = nullptr;
+    ret = provider->getCameraDeviceInterface_V3_x(name, [&](auto status, const auto& device) {
+        ALOGI("getCameraDeviceInterface_V3_x returns status:%d", (int)status);
+        ASSERT_EQ(Status::OK, status);
+        ASSERT_NE(device, nullptr);
+        device3_x = device;
+    });
+    if (!(ret.isOk())) {
+        ADD_FAILURE() << "Failed to get camera device interface for " << name;
+    }
+
+    camera_metadata_t* staticMeta = nullptr;
+    ret = device3_x->getCameraCharacteristics([&](Status s, CameraMetadata metadata) {
+        ASSERT_EQ(Status::OK, s);
+        staticMeta =
+                clone_camera_metadata(reinterpret_cast<const camera_metadata_t*>(metadata.data()));
+    });
+    if (!(ret.isOk())) {
+        ADD_FAILURE() << "Failed to get camera characteristics for " << name;
+    }
+    // Go through the characteristics and see if video stabilization modes have
+    // preview stabilization
+    camera_metadata_ro_entry entry;
+
+    int retcode = find_camera_metadata_ro_entry(
+            staticMeta, ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES, &entry);
+    if ((0 == retcode) && (entry.count > 0)) {
+        for (auto i = 0; i < entry.count; i++) {
+            if (entry.data.u8[i] ==
+                ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_PREVIEW_STABILIZATION) {
+                return true;
+            }
+        }
+    }
+    return false;
+}
+
 // Open a device session and configure a preview stream.
 void CameraHidlTest::configureSingleStream(
         const std::string& name, int32_t deviceVersion, sp<ICameraProvider> provider,
diff --git a/compatibility_matrices/compatibility_matrix.3.xml b/compatibility_matrices/compatibility_matrix.3.xml
index a75ed25..468735d 100644
--- a/compatibility_matrices/compatibility_matrix.3.xml
+++ b/compatibility_matrices/compatibility_matrix.3.xml
@@ -207,7 +207,10 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="false">
+    <!-- Either the AIDL or the HIDL health HAL must exist on the device.
+         If the HIDL health HAL exists, it must be at least version 2.0.
+         See DeviceManifestTest.HealthHal -->
+    <hal format="hidl" optional="true">
         <name>android.hardware.health</name>
         <version>2.0</version>
         <interface>
diff --git a/compatibility_matrices/compatibility_matrix.4.xml b/compatibility_matrices/compatibility_matrix.4.xml
index 3b8ee21..96f291f 100644
--- a/compatibility_matrices/compatibility_matrix.4.xml
+++ b/compatibility_matrices/compatibility_matrix.4.xml
@@ -213,7 +213,10 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="false">
+    <!-- Either the AIDL or the HIDL health HAL must exist on the device.
+         If the HIDL health HAL exists, it must be at least version 2.0.
+         See DeviceManifestTest.HealthHal -->
+    <hal format="hidl" optional="true">
         <name>android.hardware.health</name>
         <version>2.0</version>
         <interface>
diff --git a/compatibility_matrices/compatibility_matrix.5.xml b/compatibility_matrices/compatibility_matrix.5.xml
index 0fb21a7..3642814 100644
--- a/compatibility_matrices/compatibility_matrix.5.xml
+++ b/compatibility_matrices/compatibility_matrix.5.xml
@@ -238,7 +238,10 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="false">
+    <!-- Either the AIDL or the HIDL health HAL must exist on the device.
+         If the HIDL health HAL exists, it must be at least version 2.1.
+         See DeviceManifestTest.HealthHal -->
+    <hal format="hidl" optional="true">
         <name>android.hardware.health</name>
         <version>2.1</version>
         <interface>
diff --git a/compatibility_matrices/compatibility_matrix.6.xml b/compatibility_matrices/compatibility_matrix.6.xml
index aee2c51..9c42cb0 100644
--- a/compatibility_matrices/compatibility_matrix.6.xml
+++ b/compatibility_matrices/compatibility_matrix.6.xml
@@ -268,7 +268,10 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="false">
+    <!-- Either the AIDL or the HIDL health HAL must exist on the device.
+         If the HIDL health HAL exists, it must be at least version 2.1.
+         See DeviceManifestTest.HealthHal -->
+    <hal format="hidl" optional="true">
         <name>android.hardware.health</name>
         <version>2.1</version>
         <interface>
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index 6919b9b..cf85688 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -209,12 +209,16 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.contexthub</name>
-        <version>1.2</version>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.drm</name>
+        <version>1</version>
         <interface>
-            <name>IContexthub</name>
-            <instance>default</instance>
+            <name>ICryptoFactory</name>
+            <regex-instance>.*</regex-instance>
+        </interface>
+        <interface>
+            <name>IDrmFactory</name>
+            <regex-instance>.*</regex-instance>
         </interface>
     </hal>
     <hal format="hidl" optional="true">
@@ -260,6 +264,14 @@
             <instance>default</instance>
         </interface>
     </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.gnss.visibility_control</name>
+        <version>1</version>
+        <interface>
+            <name>IGnssVisibilityControl</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
     <hal format="hidl" optional="false">
         <name>android.hardware.graphics.allocator</name>
         <!-- New, non-Go devices should use 4.0, tested in vts_treble_vintf_vendor_test -->
@@ -337,9 +349,9 @@
             <instance>default</instance>
         </interface>
     </hal>
-    <hal format="hidl" optional="true">
+    <hal format="aidl" optional="true">
         <name>android.hardware.ir</name>
-        <version>1.0</version>
+        <version>1</version>
         <interface>
             <name>IConsumerIr</name>
             <instance>default</instance>
@@ -371,9 +383,17 @@
         </interface>
     </hal>
     <hal format="aidl" optional="true">
-        <name>android.hardware.security.keymint</name>
+        <name>android.hardware.security.dice</name>
         <version>1</version>
         <interface>
+            <name>IDiceDevice</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.security.keymint</name>
+        <version>1-2</version>
+        <interface>
             <name>IKeyMintDevice</name>
             <instance>default</instance>
             <instance>strongbox</instance>
@@ -381,9 +401,11 @@
     </hal>
     <hal format="aidl" optional="true">
         <name>android.hardware.security.keymint</name>
+        <version>1-2</version>
         <interface>
             <name>IRemotelyProvisionedComponent</name>
             <instance>default</instance>
+            <instance>strongbox</instance>
         </interface>
     </hal>
     <hal format="aidl" optional="true">
@@ -457,7 +479,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>
@@ -617,6 +639,13 @@
             <instance>strongbox</instance>
         </interface>
     </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.sensors</name>
+        <interface>
+            <name>ISensors</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
     <hal format="hidl" optional="true">
         <name>android.hardware.sensors</name>
         <version>1.0</version>
@@ -786,4 +815,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/HostEndpointInfo.aidl b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/HostEndpointInfo.aidl
index e7dcbc7..84e8531 100644
--- a/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/HostEndpointInfo.aidl
+++ b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/HostEndpointInfo.aidl
@@ -40,7 +40,7 @@
   @nullable String attributionTag;
   @Backing(type="int") @VintfStability
   enum Type {
-    TYPE_FRAMEWORK = 1,
-    TYPE_APP = 2,
+    FRAMEWORK = 1,
+    APP = 2,
   }
 }
diff --git a/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/IContextHub.aidl b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/IContextHub.aidl
index facce4b..f0676be 100644
--- a/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/IContextHub.aidl
+++ b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/IContextHub.aidl
@@ -35,14 +35,15 @@
 @VintfStability
 interface IContextHub {
   List<android.hardware.contexthub.ContextHubInfo> getContextHubs();
-  boolean loadNanoapp(in int contextHubId, in android.hardware.contexthub.NanoappBinary appBinary, in int transactionId);
-  boolean unloadNanoapp(in int contextHubId, in long appId, in int transactionId);
-  boolean disableNanoapp(in int contextHubId, in long appId, in int transactionId);
-  boolean enableNanoapp(in int contextHubId, in long appId, in int transactionId);
+  void loadNanoapp(in int contextHubId, in android.hardware.contexthub.NanoappBinary appBinary, in int transactionId);
+  void unloadNanoapp(in int contextHubId, in long appId, in int transactionId);
+  void disableNanoapp(in int contextHubId, in long appId, in int transactionId);
+  void enableNanoapp(in int contextHubId, in long appId, in int transactionId);
   void onSettingChanged(in android.hardware.contexthub.Setting setting, in boolean enabled);
-  boolean queryNanoapps(in int contextHubId);
-  boolean registerCallback(in int contextHubId, in android.hardware.contexthub.IContextHubCallback cb);
-  boolean sendMessageToHub(in int contextHubId, in android.hardware.contexthub.ContextHubMessage message);
+  void queryNanoapps(in int contextHubId);
+  void registerCallback(in int contextHubId, in android.hardware.contexthub.IContextHubCallback cb);
+  void sendMessageToHub(in int contextHubId, in android.hardware.contexthub.ContextHubMessage message);
   void onHostEndpointConnected(in android.hardware.contexthub.HostEndpointInfo hostEndpointInfo);
   void onHostEndpointDisconnected(char hostEndpointId);
+  const int EX_CONTEXT_HUB_UNSPECIFIED = -1;
 }
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/WhitePointNits.aidl b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/NanoappRpcService.aidl
similarity index 88%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/WhitePointNits.aidl
copy to contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/NanoappRpcService.aidl
index c3925d2..a6a1644 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/WhitePointNits.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;
+package android.hardware.contexthub;
 @VintfStability
-parcelable WhitePointNits {
-  float nits;
+parcelable NanoappRpcService {
+  long id;
+  int version;
 }
diff --git a/contexthub/aidl/android/hardware/contexthub/ContextHubMessage.aidl b/contexthub/aidl/android/hardware/contexthub/ContextHubMessage.aidl
index 867da2f..95d478e 100644
--- a/contexthub/aidl/android/hardware/contexthub/ContextHubMessage.aidl
+++ b/contexthub/aidl/android/hardware/contexthub/ContextHubMessage.aidl
@@ -32,10 +32,14 @@
      */
     char hostEndPoint;
 
-    /** The type of this message */
+    /**
+     * The type of this message payload, defined by the communication endpoints (i.e.
+     * either the nanoapp or the host endpoint). This value can be used to distinguish
+     * the handling of messageBody (e.g. for decoding).
+     */
     int messageType;
 
-    /** The payload containing the message */
+    /** The payload containing the message. */
     byte[] messageBody;
 
     /**
diff --git a/contexthub/aidl/android/hardware/contexthub/HostEndpointInfo.aidl b/contexthub/aidl/android/hardware/contexthub/HostEndpointInfo.aidl
index 40a231d..a9d6657 100644
--- a/contexthub/aidl/android/hardware/contexthub/HostEndpointInfo.aidl
+++ b/contexthub/aidl/android/hardware/contexthub/HostEndpointInfo.aidl
@@ -37,12 +37,12 @@
     @Backing(type="int")
     enum Type {
         /**
-           This endpoint is from the Android framework, where packageName and attributionTag may be
-           empty.
+         * This endpoint is from the Android framework, where packageName and attributionTag may be
+         * empty.
          */
-        TYPE_FRAMEWORK = 1,
+        FRAMEWORK = 1,
 
         /** This endpoint is an Android app. */
-        TYPE_APP = 2,
+        APP = 2,
     }
 }
diff --git a/contexthub/aidl/android/hardware/contexthub/IContextHub.aidl b/contexthub/aidl/android/hardware/contexthub/IContextHub.aidl
index 33d241a..2135041 100644
--- a/contexthub/aidl/android/hardware/contexthub/IContextHub.aidl
+++ b/contexthub/aidl/android/hardware/contexthub/IContextHub.aidl
@@ -52,9 +52,12 @@
      * @param appBinary The nanoapp binary with header
      * @param transactionId The transaction ID associated with this request
      *
-     * @return The return code
+     * @throws EX_ILLEGAL_ARGUMENT if any of the arguments are invalid.
+     *         EX_UNSUPPORTED_OPERATION if this functionality is unsupported.
+     *         EX_SERVICE_SPECIFIC on error
+     *         - EX_CONTEXT_HUB_UNSPECIFIED if the request failed for other reasons.
      */
-    boolean loadNanoapp(in int contextHubId, in NanoappBinary appBinary, in int transactionId);
+    void loadNanoapp(in int contextHubId, in NanoappBinary appBinary, in int transactionId);
 
     /**
      * Invokes the nanoapp's deinitialization "end()" entrypoint, and unloads the nanoapp.
@@ -69,9 +72,12 @@
      * @param appId The unique ID of the nanoapp
      * @param transactionId The transaction ID associated with this request
      *
-     * @return The return code
+     * @throws EX_ILLEGAL_ARGUMENT if any of the arguments are invalid.
+     *         EX_UNSUPPORTED_OPERATION if this functionality is unsupported.
+     *         EX_SERVICE_SPECIFIC on error
+     *         - EX_CONTEXT_HUB_UNSPECIFIED if the request failed for other reasons.
      */
-    boolean unloadNanoapp(in int contextHubId, in long appId, in int transactionId);
+    void unloadNanoapp(in int contextHubId, in long appId, in int transactionId);
 
     /**
      * Disables a nanoapp by invoking the nanoapp's "end()" entrypoint, but does not unload the
@@ -87,9 +93,12 @@
      * @param appId The unique ID of the nanoapp
      * @param transactionId The transaction ID associated with this request
      *
-     * @return The return code
+     * @throws EX_ILLEGAL_ARGUMENT if any of the arguments are invalid.
+     *         EX_UNSUPPORTED_OPERATION if this functionality is unsupported.
+     *         EX_SERVICE_SPECIFIC on error
+     *         - EX_CONTEXT_HUB_UNSPECIFIED if the request failed for other reasons.
      */
-    boolean disableNanoapp(in int contextHubId, in long appId, in int transactionId);
+    void disableNanoapp(in int contextHubId, in long appId, in int transactionId);
 
     /**
      * Enables a nanoapp by invoking the nanoapp's initialization "start()" entrypoint.
@@ -104,9 +113,12 @@
      * @param appId appIdentifier returned by the HAL
      * @param message   message to be sent
      *
-     * @return true on success
+     * @throws EX_ILLEGAL_ARGUMENT if any of the arguments are invalid.
+     *         EX_UNSUPPORTED_OPERATION if this functionality is unsupported.
+     *         EX_SERVICE_SPECIFIC on error
+     *         - EX_CONTEXT_HUB_UNSPECIFIED if the request failed for other reasons.
      */
-    boolean enableNanoapp(in int contextHubId, in long appId, in int transactionId);
+    void enableNanoapp(in int contextHubId, in long appId, in int transactionId);
 
     /**
      * Notification sent by the framework to indicate that the user has changed a setting.
@@ -124,9 +136,12 @@
      *
      * @param contextHubId The identifier of the Context Hub
      *
-     * @return true on success
+     * @throws EX_ILLEGAL_ARGUMENT if any of the arguments are invalid.
+     *         EX_UNSUPPORTED_OPERATION if this functionality is unsupported.
+     *         EX_SERVICE_SPECIFIC on error
+     *         - EX_CONTEXT_HUB_UNSPECIFIED if the request failed for other reasons.
      */
-    boolean queryNanoapps(in int contextHubId);
+    void queryNanoapps(in int contextHubId);
 
     /**
      * Register a callback for the HAL implementation to send asynchronous messages to the service
@@ -138,10 +153,11 @@
      * @param contextHubId The identifier of the Context Hub
      * @param callback an implementation of the IContextHubCallbacks
      *
-     * @return true on success
-     *
+     * @throws EX_ILLEGAL_ARGUMENT if any of the arguments are invalid.
+     *         EX_SERVICE_SPECIFIC on error
+     *         - EX_CONTEXT_HUB_UNSPECIFIED if the request failed for other reasons.
      */
-    boolean registerCallback(in int contextHubId, in IContextHubCallback cb);
+    void registerCallback(in int contextHubId, in IContextHubCallback cb);
 
     /**
      * Sends a message targeted to a nanoapp to the Context Hub.
@@ -149,9 +165,11 @@
      * @param contextHubId The identifier of the Context Hub
      * @param message The message to be sent
      *
-     * @return true on success
+     * @throws EX_ILLEGAL_ARGUMENT if any of the arguments are invalid.
+     *         EX_SERVICE_SPECIFIC on error
+     *         - EX_CONTEXT_HUB_UNSPECIFIED if the request failed for other reasons.
      */
-    boolean sendMessageToHub(in int contextHubId, in ContextHubMessage message);
+    void sendMessageToHub(in int contextHubId, in ContextHubMessage message);
 
     /**
      * Invoked when a host endpoint has connected with the ContextHubService.
@@ -173,8 +191,13 @@
      *
      * @param hostEndPointId The ID of the host that has disconnected.
      *
-     * @return Status::ok on success
-     *         EX_ILLEGAL_ARGUMENT if hostEndpointId is not associated with a connected host.
+     * @throws EX_ILLEGAL_ARGUMENT if hostEndpointId is not associated with a connected host.
      */
     void onHostEndpointDisconnected(char hostEndpointId);
+
+    /**
+     * Error codes that are used as service specific errors with the AIDL return
+     * value EX_SERVICE_SPECIFIC.
+     */
+    const int EX_CONTEXT_HUB_UNSPECIFIED = -1;
 }
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/default/ContextHub.cpp b/contexthub/aidl/default/ContextHub.cpp
index 6da690d..4c23cbc 100644
--- a/contexthub/aidl/default/ContextHub.cpp
+++ b/contexthub/aidl/default/ContextHub.cpp
@@ -21,7 +21,9 @@
 namespace hardware {
 namespace contexthub {
 
-::ndk::ScopedAStatus ContextHub::getContextHubs(std::vector<ContextHubInfo>* out_contextHubInfos) {
+using ::ndk::ScopedAStatus;
+
+ScopedAStatus ContextHub::getContextHubs(std::vector<ContextHubInfo>* out_contextHubInfos) {
     ContextHubInfo hub = {};
     hub.name = "Mock Context Hub";
     hub.vendor = "AOSP";
@@ -39,85 +41,70 @@
 }
 
 // We don't expose any nanoapps for the default impl, therefore all nanoapp-related APIs fail.
-::ndk::ScopedAStatus ContextHub::loadNanoapp(int32_t /* in_contextHubId */,
-                                             const NanoappBinary& /* in_appBinary */,
-                                             int32_t /* in_transactionId */, bool* _aidl_return) {
-    *_aidl_return = false;
+ScopedAStatus ContextHub::loadNanoapp(int32_t /* in_contextHubId */,
+                                      const NanoappBinary& /* in_appBinary */,
+                                      int32_t /* in_transactionId */) {
+    return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ScopedAStatus ContextHub::unloadNanoapp(int32_t /* in_contextHubId */, int64_t /* in_appId */,
+                                        int32_t /* in_transactionId */) {
+    return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ScopedAStatus ContextHub::disableNanoapp(int32_t /* in_contextHubId */, int64_t /* in_appId */,
+                                         int32_t /* in_transactionId */) {
+    return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ScopedAStatus ContextHub::enableNanoapp(int32_t /* in_contextHubId */, int64_t /* in_appId */,
+                                        int32_t /* in_transactionId */) {
+    return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ScopedAStatus ContextHub::onSettingChanged(Setting /* in_setting */, bool /*in_enabled */) {
     return ndk::ScopedAStatus::ok();
 }
 
-::ndk::ScopedAStatus ContextHub::unloadNanoapp(int32_t /* in_contextHubId */,
-                                               int64_t /* in_appId */,
-                                               int32_t /* in_transactionId */, bool* _aidl_return) {
-    *_aidl_return = false;
-    return ndk::ScopedAStatus::ok();
-}
-
-::ndk::ScopedAStatus ContextHub::disableNanoapp(int32_t /* in_contextHubId */,
-                                                int64_t /* in_appId */,
-                                                int32_t /* in_transactionId */,
-                                                bool* _aidl_return) {
-    *_aidl_return = false;
-    return ndk::ScopedAStatus::ok();
-}
-
-::ndk::ScopedAStatus ContextHub::enableNanoapp(int32_t /* in_contextHubId */,
-                                               int64_t /* in_appId */,
-                                               int32_t /* in_transactionId */, bool* _aidl_return) {
-    *_aidl_return = false;
-    return ndk::ScopedAStatus::ok();
-}
-
-::ndk::ScopedAStatus ContextHub::onSettingChanged(Setting /* in_setting */, bool /*in_enabled */) {
-    return ndk::ScopedAStatus::ok();
-}
-
-::ndk::ScopedAStatus ContextHub::queryNanoapps(int32_t in_contextHubId, bool* _aidl_return) {
+ScopedAStatus ContextHub::queryNanoapps(int32_t in_contextHubId) {
     if (in_contextHubId == kMockHubId && mCallback != nullptr) {
         std::vector<NanoappInfo> nanoapps;
         mCallback->handleNanoappInfo(nanoapps);
-        *_aidl_return = true;
+        return ndk::ScopedAStatus::ok();
     } else {
-        *_aidl_return = false;
+        return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
     }
-
-    return ndk::ScopedAStatus::ok();
 }
 
-::ndk::ScopedAStatus ContextHub::registerCallback(int32_t in_contextHubId,
-                                                  const std::shared_ptr<IContextHubCallback>& in_cb,
-                                                  bool* _aidl_return) {
+ScopedAStatus ContextHub::registerCallback(int32_t in_contextHubId,
+                                           const std::shared_ptr<IContextHubCallback>& in_cb) {
     if (in_contextHubId == kMockHubId) {
         mCallback = in_cb;
-        *_aidl_return = true;
+        return ndk::ScopedAStatus::ok();
     } else {
-        *_aidl_return = false;
+        return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
     }
-    return ndk::ScopedAStatus::ok();
 }
 
-::ndk::ScopedAStatus ContextHub::sendMessageToHub(int32_t in_contextHubId,
-                                                  const ContextHubMessage& /* in_message */,
-                                                  bool* _aidl_return) {
+ScopedAStatus ContextHub::sendMessageToHub(int32_t in_contextHubId,
+                                           const ContextHubMessage& /* in_message */) {
     if (in_contextHubId == kMockHubId) {
         // Return true here to indicate that the HAL has accepted the message.
         // Successful delivery of the message to a nanoapp should be handled at
         // a higher level protocol.
-        *_aidl_return = true;
+        return ndk::ScopedAStatus::ok();
     } else {
-        *_aidl_return = false;
+        return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
     }
-
-    return ndk::ScopedAStatus::ok();
 }
 
-::ndk::ScopedAStatus ContextHub::onHostEndpointConnected(const HostEndpointInfo& in_info) {
+ScopedAStatus ContextHub::onHostEndpointConnected(const HostEndpointInfo& in_info) {
     mConnectedHostEndpoints.insert(in_info.hostEndpointId);
 
     return ndk::ScopedAStatus::ok();
 }
 
-::ndk::ScopedAStatus ContextHub::onHostEndpointDisconnected(char16_t in_hostEndpointId) {
+ScopedAStatus ContextHub::onHostEndpointDisconnected(char16_t in_hostEndpointId) {
     if (mConnectedHostEndpoints.count(in_hostEndpointId) > 0) {
         mConnectedHostEndpoints.erase(in_hostEndpointId);
         return ndk::ScopedAStatus::ok();
diff --git a/contexthub/aidl/default/include/contexthub-impl/ContextHub.h b/contexthub/aidl/default/include/contexthub-impl/ContextHub.h
index dd739e6..03d8432 100644
--- a/contexthub/aidl/default/include/contexthub-impl/ContextHub.h
+++ b/contexthub/aidl/default/include/contexthub-impl/ContextHub.h
@@ -28,21 +28,19 @@
 class ContextHub : public BnContextHub {
     ::ndk::ScopedAStatus getContextHubs(std::vector<ContextHubInfo>* out_contextHubInfos) override;
     ::ndk::ScopedAStatus loadNanoapp(int32_t in_contextHubId, const NanoappBinary& in_appBinary,
-                                     int32_t in_transactionId, bool* _aidl_return) override;
+                                     int32_t in_transactionId) override;
     ::ndk::ScopedAStatus unloadNanoapp(int32_t in_contextHubId, int64_t in_appId,
-                                       int32_t in_transactionId, bool* _aidl_return) override;
+                                       int32_t in_transactionId) override;
     ::ndk::ScopedAStatus disableNanoapp(int32_t in_contextHubId, int64_t in_appId,
-                                        int32_t in_transactionId, bool* _aidl_return) override;
+                                        int32_t in_transactionId) override;
     ::ndk::ScopedAStatus enableNanoapp(int32_t in_contextHubId, int64_t in_appId,
-                                       int32_t in_transactionId, bool* _aidl_return) override;
+                                       int32_t in_transactionId) override;
     ::ndk::ScopedAStatus onSettingChanged(Setting in_setting, bool in_enabled) override;
-    ::ndk::ScopedAStatus queryNanoapps(int32_t in_contextHubId, bool* _aidl_return) override;
-    ::ndk::ScopedAStatus registerCallback(int32_t in_contextHubId,
-                                          const std::shared_ptr<IContextHubCallback>& in_cb,
-                                          bool* _aidl_return) override;
+    ::ndk::ScopedAStatus queryNanoapps(int32_t in_contextHubId) override;
+    ::ndk::ScopedAStatus registerCallback(
+            int32_t in_contextHubId, const std::shared_ptr<IContextHubCallback>& in_cb) override;
     ::ndk::ScopedAStatus sendMessageToHub(int32_t in_contextHubId,
-                                          const ContextHubMessage& in_message,
-                                          bool* _aidl_return) override;
+                                          const ContextHubMessage& in_message) override;
     ::ndk::ScopedAStatus onHostEndpointConnected(const HostEndpointInfo& in_info) override;
 
     ::ndk::ScopedAStatus onHostEndpointDisconnected(char16_t in_hostEndpointId) override;
diff --git a/contexthub/aidl/vts/VtsAidlHalContextHubTargetTest.cpp b/contexthub/aidl/vts/VtsAidlHalContextHubTargetTest.cpp
index 1b2dc29..a47f64e 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;
@@ -102,15 +103,12 @@
 };
 
 TEST_P(ContextHubAidl, TestRegisterCallback) {
-    bool success;
     sp<EmptyContextHubCallback> cb = sp<EmptyContextHubCallback>::make();
-    ASSERT_TRUE(contextHub->registerCallback(getHubId(), cb, &success).isOk());
-    ASSERT_TRUE(success);
+    ASSERT_TRUE(contextHub->registerCallback(getHubId(), cb).isOk());
 }
 
 TEST_P(ContextHubAidl, TestRegisterNullCallback) {
-    bool success;
-    ASSERT_TRUE(contextHub->registerCallback(getHubId(), nullptr, &success).isOk());
+    ASSERT_TRUE(contextHub->registerCallback(getHubId(), nullptr).isOk());
 }
 
 // Helper callback that puts the async appInfo callback data into a promise
@@ -139,18 +137,22 @@
 // Calls queryApps() and checks the returned metadata
 TEST_P(ContextHubAidl, TestQueryApps) {
     sp<QueryAppsCallback> cb = sp<QueryAppsCallback>::make();
-    bool success;
-    ASSERT_TRUE(contextHub->registerCallback(getHubId(), cb, &success).isOk());
-    ASSERT_TRUE(success);
-
-    ASSERT_TRUE(contextHub->queryNanoapps(getHubId(), &success).isOk());
-    ASSERT_TRUE(success);
+    ASSERT_TRUE(contextHub->registerCallback(getHubId(), cb).isOk());
+    ASSERT_TRUE(contextHub->queryNanoapps(getHubId()).isOk());
 
     std::vector<NanoappInfo> appInfoList;
     ASSERT_TRUE(waitForCallback(cb->promise.get_future(), &appInfoList));
     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);
+        }
     }
 }
 
@@ -188,9 +190,7 @@
   public:
     virtual void SetUp() override {
         ContextHubAidl::SetUp();
-        bool success;
-        ASSERT_TRUE(contextHub->registerCallback(getHubId(), cb, &success).isOk());
-        ASSERT_TRUE(success);
+        ASSERT_TRUE(contextHub->registerCallback(getHubId(), cb).isOk());
     }
 
     sp<TransactionResultCallback> cb = sp<TransactionResultCallback>::make();
@@ -204,9 +204,7 @@
     std::fill(message.messageBody.begin(), message.messageBody.end(), 0);
 
     ALOGD("Sending message to non-existent nanoapp");
-    bool success;
-    ASSERT_TRUE(contextHub->sendMessageToHub(getHubId(), message, &success).isOk());
-    ASSERT_TRUE(success);
+    ASSERT_TRUE(contextHub->sendMessageToHub(getHubId(), message).isOk());
 }
 
 TEST_P(ContextHubTransactionTest, TestLoadEmptyNanoapp) {
@@ -220,9 +218,7 @@
     emptyApp.targetChreApiMinorVersion = 0;
 
     ALOGD("Loading empty nanoapp");
-    bool success;
-    ASSERT_TRUE(contextHub->loadNanoapp(getHubId(), emptyApp, cb->expectedTransactionId, &success)
-                        .isOk());
+    bool success = contextHub->loadNanoapp(getHubId(), emptyApp, cb->expectedTransactionId).isOk();
     if (success) {
         bool transactionSuccess;
         ASSERT_TRUE(waitForCallback(cb->promise.get_future(), &transactionSuccess));
@@ -234,11 +230,9 @@
     cb->expectedTransactionId = 1234;
 
     ALOGD("Unloading nonexistent nanoapp");
-    bool success;
-    ASSERT_TRUE(contextHub
-                        ->unloadNanoapp(getHubId(), kNonExistentAppId, cb->expectedTransactionId,
-                                        &success)
-                        .isOk());
+    bool success =
+            contextHub->unloadNanoapp(getHubId(), kNonExistentAppId, cb->expectedTransactionId)
+                    .isOk();
     if (success) {
         bool transactionSuccess;
         ASSERT_TRUE(waitForCallback(cb->promise.get_future(), &transactionSuccess));
@@ -250,11 +244,9 @@
     cb->expectedTransactionId = 2345;
 
     ALOGD("Enabling nonexistent nanoapp");
-    bool success;
-    ASSERT_TRUE(contextHub
-                        ->enableNanoapp(getHubId(), kNonExistentAppId, cb->expectedTransactionId,
-                                        &success)
-                        .isOk());
+    bool success =
+            contextHub->enableNanoapp(getHubId(), kNonExistentAppId, cb->expectedTransactionId)
+                    .isOk();
     if (success) {
         bool transactionSuccess;
         ASSERT_TRUE(waitForCallback(cb->promise.get_future(), &transactionSuccess));
@@ -266,11 +258,9 @@
     cb->expectedTransactionId = 3456;
 
     ALOGD("Disabling nonexistent nanoapp");
-    bool success;
-    ASSERT_TRUE(contextHub
-                        ->disableNanoapp(getHubId(), kNonExistentAppId, cb->expectedTransactionId,
-                                         &success)
-                        .isOk());
+    bool success =
+            contextHub->disableNanoapp(getHubId(), kNonExistentAppId, cb->expectedTransactionId)
+                    .isOk();
     if (success) {
         bool transactionSuccess;
         ASSERT_TRUE(waitForCallback(cb->promise.get_future(), &transactionSuccess));
@@ -281,16 +271,13 @@
 void ContextHubAidl::testSettingChanged(Setting setting) {
     // In VTS, we only test that sending the values doesn't cause things to blow up - GTS tests
     // verify the expected E2E behavior in CHRE
-    bool success;
     sp<EmptyContextHubCallback> cb = sp<EmptyContextHubCallback>::make();
-    ASSERT_TRUE(contextHub->registerCallback(getHubId(), cb, &success).isOk());
-    ASSERT_TRUE(success);
+    ASSERT_TRUE(contextHub->registerCallback(getHubId(), cb).isOk());
 
     ASSERT_TRUE(contextHub->onSettingChanged(setting, true /* enabled */).isOk());
     ASSERT_TRUE(contextHub->onSettingChanged(setting, false /* enabled */).isOk());
 
-    ASSERT_TRUE(contextHub->registerCallback(getHubId(), nullptr, &success).isOk());
-    ASSERT_TRUE(success);
+    ASSERT_TRUE(contextHub->registerCallback(getHubId(), nullptr).isOk());
 }
 
 TEST_P(ContextHubAidl, TestOnLocationSettingChanged) {
diff --git a/drm/aidl/Android.bp b/drm/aidl/Android.bp
new file mode 100644
index 0000000..d8500ec
--- /dev/null
+++ b/drm/aidl/Android.bp
@@ -0,0 +1,32 @@
+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.drm",
+    vendor_available: true,
+    srcs: ["android/hardware/drm/*.aidl"],
+    stability: "vintf",
+    imports: [
+        "android.hardware.common-V2",
+    ],
+    backend: {
+        cpp: {
+            enabled: false,
+        },
+        java: {
+            sdk_version: "module_current",
+        },
+        ndk: {
+            vndk: {
+                enabled: true,
+            },
+            min_sdk_version: "current",
+        },
+    },
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/BufferType.aidl
similarity index 88%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.aidl
copy to drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/BufferType.aidl
index b87870d..b6ec34d 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.aidl
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/BufferType.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,9 +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.drm;
 @Backing(type="int") @VintfStability
-enum HandleIndex {
-  EMPTY = -1,
-  CACHED = -2,
+enum BufferType {
+  SHARED_MEMORY = 0,
+  NATIVE_HANDLE = 1,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FloatColor.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DecryptResult.aidl
similarity index 87%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FloatColor.aidl
copy to drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DecryptResult.aidl
index faadf57..d2b48d2 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FloatColor.aidl
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DecryptResult.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,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.drm;
 @VintfStability
-parcelable FloatColor {
-  float r;
-  float g;
-  float b;
-  float a;
+parcelable DecryptResult {
+  int bytesWritten;
+  String detailedError;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DestinationBuffer.aidl
similarity index 82%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl
copy to drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DestinationBuffer.aidl
index df07c9c..4f2d133 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DestinationBuffer.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,9 +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.drm;
 @VintfStability
-parcelable ColorTransformPayload {
-  float[] matrix;
-  android.hardware.graphics.common.ColorTransform hint;
+parcelable DestinationBuffer {
+  android.hardware.drm.BufferType type;
+  android.hardware.drm.SharedBuffer nonsecureMemory;
+  android.hardware.common.NativeHandle secureMemory;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerGenericMetadataKey.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DrmMetric.aidl
similarity index 84%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerGenericMetadataKey.aidl
copy to drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DrmMetric.aidl
index 73385d4..c78dff0 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerGenericMetadataKey.aidl
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DrmMetric.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,9 +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.drm;
 @VintfStability
-parcelable LayerGenericMetadataKey {
+parcelable DrmMetric {
   String name;
-  boolean mandatory;
+  List<android.hardware.drm.DrmMetricNamedValue> attributes;
+  List<android.hardware.drm.DrmMetricNamedValue> values;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FloatColor.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DrmMetricGroup.aidl
similarity index 87%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FloatColor.aidl
copy to drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DrmMetricGroup.aidl
index faadf57..4128eaa 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FloatColor.aidl
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DrmMetricGroup.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;
+package android.hardware.drm;
 @VintfStability
-parcelable FloatColor {
-  float r;
-  float g;
-  float b;
-  float a;
+parcelable DrmMetricGroup {
+  List<android.hardware.drm.DrmMetric> metrics;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerGenericMetadataKey.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DrmMetricNamedValue.aidl
similarity index 87%
rename from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerGenericMetadataKey.aidl
rename to drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DrmMetricNamedValue.aidl
index 73385d4..76ec35c 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerGenericMetadataKey.aidl
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DrmMetricNamedValue.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,9 +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.drm;
 @VintfStability
-parcelable LayerGenericMetadataKey {
+parcelable DrmMetricNamedValue {
   String name;
-  boolean mandatory;
+  android.hardware.drm.DrmMetricValue value;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FloatColor.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DrmMetricValue.aidl
similarity index 87%
rename from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FloatColor.aidl
rename to drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DrmMetricValue.aidl
index faadf57..8064913 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FloatColor.aidl
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/DrmMetricValue.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.drm;
 @VintfStability
-parcelable FloatColor {
-  float r;
-  float g;
-  float b;
-  float a;
+union DrmMetricValue {
+  long int64Value;
+  double doubleValue;
+  String stringValue;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/EventType.aidl
similarity index 85%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.aidl
copy to drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/EventType.aidl
index b87870d..80ebb28 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.aidl
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/EventType.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,9 +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.drm;
 @Backing(type="int") @VintfStability
-enum HandleIndex {
-  EMPTY = -1,
-  CACHED = -2,
+enum EventType {
+  PROVISION_REQUIRED = 0,
+  KEY_NEEDED = 1,
+  KEY_EXPIRED = 2,
+  VENDOR_DEFINED = 3,
+  SESSION_RECLAIMED = 4,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/HdcpLevel.aidl
similarity index 84%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.aidl
copy to drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/HdcpLevel.aidl
index b87870d..5704fb0 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.aidl
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/HdcpLevel.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,9 +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.drm;
 @Backing(type="int") @VintfStability
-enum HandleIndex {
-  EMPTY = -1,
-  CACHED = -2,
+enum HdcpLevel {
+  HDCP_UNKNOWN = 0,
+  HDCP_NONE = 1,
+  HDCP_V1 = 2,
+  HDCP_V2 = 3,
+  HDCP_V2_1 = 4,
+  HDCP_V2_2 = 5,
+  HDCP_NO_OUTPUT = 6,
+  HDCP_V2_3 = 7,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/HdcpLevels.aidl
similarity index 85%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl
copy to drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/HdcpLevels.aidl
index df07c9c..a6f86ac 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/HdcpLevels.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,9 +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.drm;
 @VintfStability
-parcelable ColorTransformPayload {
-  float[] matrix;
-  android.hardware.graphics.common.ColorTransform hint;
+parcelable HdcpLevels {
+  android.hardware.drm.HdcpLevel connectedLevel;
+  android.hardware.drm.HdcpLevel maxLevel;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/ICryptoFactory.aidl
similarity index 81%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl
copy to drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/ICryptoFactory.aidl
index df07c9c..0d4296e 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/ICryptoFactory.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,9 +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.drm;
 @VintfStability
-parcelable ColorTransformPayload {
-  float[] matrix;
-  android.hardware.graphics.common.ColorTransform hint;
+interface ICryptoFactory {
+  @nullable android.hardware.drm.ICryptoPlugin createPlugin(in android.hardware.drm.Uuid uuid, in byte[] initData);
+  boolean isCryptoSchemeSupported(in android.hardware.drm.Uuid uuid);
 }
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/ICryptoPlugin.aidl
similarity index 68%
copy from bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl
copy to drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/ICryptoPlugin.aidl
index 9efafca..2224795 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/ICryptoPlugin.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright 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.
@@ -31,21 +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.bluetooth.audio;
+package android.hardware.drm;
 @VintfStability
-parcelable LeAudioCapabilities {
-  android.hardware.bluetooth.audio.LeAudioMode mode;
-  android.hardware.bluetooth.audio.CodecType codecType;
-  android.hardware.bluetooth.audio.AudioLocation supportedChannel;
-  int supportedChannelCount;
-  android.hardware.bluetooth.audio.LeAudioCapabilities.LeaudioCodecCapabilities leaudioCodecCapabilities;
-  @VintfStability
-  parcelable VendorCapabilities {
-    ParcelableHolder extension;
-  }
-  @VintfStability
-  union LeaudioCodecCapabilities {
-    android.hardware.bluetooth.audio.Lc3Capabilities lc3Capabilities;
-    android.hardware.bluetooth.audio.LeAudioCapabilities.VendorCapabilities vendorCapabillities;
-  }
+interface ICryptoPlugin {
+  android.hardware.drm.DecryptResult decrypt(in boolean secure, in byte[] keyId, in byte[] iv, in android.hardware.drm.Mode mode, in android.hardware.drm.Pattern pattern, in android.hardware.drm.SubSample[] subSamples, in android.hardware.drm.SharedBuffer source, in long offset, in android.hardware.drm.DestinationBuffer destination);
+  List<android.hardware.drm.LogMessage> getLogMessages();
+  void notifyResolution(in int width, in int height);
+  boolean requiresSecureDecoderComponent(in String mime);
+  void setMediaDrmSession(in byte[] sessionId);
+  void setSharedBufferBase(in android.hardware.common.Ashmem base, in int bufferId);
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/IDrmFactory.aidl
similarity index 74%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl
copy to drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/IDrmFactory.aidl
index df07c9c..af48737 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/IDrmFactory.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,9 +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.drm;
 @VintfStability
-parcelable ColorTransformPayload {
-  float[] matrix;
-  android.hardware.graphics.common.ColorTransform hint;
+interface IDrmFactory {
+  @nullable android.hardware.drm.IDrmPlugin createPlugin(in android.hardware.drm.Uuid uuid, in String appPackageName);
+  List<android.hardware.drm.Uuid> getSupportedCryptoSchemes();
+  boolean isContentTypeSupported(in String mimeType);
+  boolean isCryptoSchemeSupported(in android.hardware.drm.Uuid uuid, in String mimeType, in android.hardware.drm.SecurityLevel securityLevel);
 }
diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/IDrmPlugin.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/IDrmPlugin.aidl
new file mode 100644
index 0000000..5f839d7
--- /dev/null
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/IDrmPlugin.aidl
@@ -0,0 +1,77 @@
+/*
+ * 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.drm;
+@VintfStability
+interface IDrmPlugin {
+  void closeSession(in byte[] sessionId);
+  byte[] decrypt(in byte[] sessionId, in byte[] keyId, in byte[] input, in byte[] iv);
+  byte[] encrypt(in byte[] sessionId, in byte[] keyId, in byte[] input, in byte[] iv);
+  android.hardware.drm.HdcpLevels getHdcpLevels();
+  android.hardware.drm.KeyRequest getKeyRequest(in byte[] scope, in byte[] initData, in String mimeType, in android.hardware.drm.KeyType keyType, in android.hardware.drm.KeyValue[] optionalParameters);
+  List<android.hardware.drm.LogMessage> getLogMessages();
+  List<android.hardware.drm.DrmMetricGroup> getMetrics();
+  android.hardware.drm.NumberOfSessions getNumberOfSessions();
+  List<android.hardware.drm.KeySetId> getOfflineLicenseKeySetIds();
+  android.hardware.drm.OfflineLicenseState getOfflineLicenseState(in android.hardware.drm.KeySetId keySetId);
+  byte[] getPropertyByteArray(in String propertyName);
+  String getPropertyString(in String propertyName);
+  android.hardware.drm.ProvisionRequest getProvisionRequest(in String certificateType, in String certificateAuthority);
+  android.hardware.drm.SecureStop getSecureStop(in android.hardware.drm.SecureStopId secureStopId);
+  List<android.hardware.drm.SecureStopId> getSecureStopIds();
+  List<android.hardware.drm.SecureStop> getSecureStops();
+  android.hardware.drm.SecurityLevel getSecurityLevel(in byte[] sessionId);
+  byte[] openSession(in android.hardware.drm.SecurityLevel securityLevel);
+  android.hardware.drm.KeySetId provideKeyResponse(in byte[] scope, in byte[] response);
+  android.hardware.drm.ProvideProvisionResponseResult provideProvisionResponse(in byte[] response);
+  List<android.hardware.drm.KeyValue> queryKeyStatus(in byte[] sessionId);
+  void releaseAllSecureStops();
+  void releaseSecureStop(in android.hardware.drm.SecureStopId secureStopId);
+  void releaseSecureStops(in android.hardware.drm.OpaqueData ssRelease);
+  void removeAllSecureStops();
+  void removeKeys(in byte[] sessionId);
+  void removeOfflineLicense(in android.hardware.drm.KeySetId keySetId);
+  void removeSecureStop(in android.hardware.drm.SecureStopId secureStopId);
+  boolean requiresSecureDecoder(in String mime, in android.hardware.drm.SecurityLevel level);
+  boolean requiresSecureDecoderDefault(in String mime);
+  void restoreKeys(in byte[] sessionId, in android.hardware.drm.KeySetId keySetId);
+  void setCipherAlgorithm(in byte[] sessionId, in String algorithm);
+  void setListener(in android.hardware.drm.IDrmPluginListener listener);
+  void setMacAlgorithm(in byte[] sessionId, in String algorithm);
+  void setPlaybackId(in byte[] sessionId, in String playbackId);
+  void setPropertyByteArray(in String propertyName, in byte[] value);
+  void setPropertyString(in String propertyName, in String value);
+  byte[] sign(in byte[] sessionId, in byte[] keyId, in byte[] message);
+  byte[] signRSA(in byte[] sessionId, in String algorithm, in byte[] message, in byte[] wrappedkey);
+  boolean verify(in byte[] sessionId, in byte[] keyId, in byte[] message, in byte[] signature);
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/IDrmPluginListener.aidl
similarity index 74%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl
copy to drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/IDrmPluginListener.aidl
index df07c9c..0a4b4b7 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/IDrmPluginListener.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,9 +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.drm;
 @VintfStability
-parcelable ColorTransformPayload {
-  float[] matrix;
-  android.hardware.graphics.common.ColorTransform hint;
+interface IDrmPluginListener {
+  oneway void onEvent(in android.hardware.drm.EventType eventType, in byte[] sessionId, in byte[] data);
+  oneway void onExpirationUpdate(in byte[] sessionId, in long expiryTimeInMS);
+  oneway void onKeysChange(in byte[] sessionId, in android.hardware.drm.KeyStatus[] keyStatusList, in boolean hasNewUsableKey);
+  oneway void onSessionLostState(in byte[] sessionId);
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyRequest.aidl
similarity index 85%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl
copy to drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyRequest.aidl
index df07c9c..267f532 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyRequest.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,9 +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.drm;
 @VintfStability
-parcelable ColorTransformPayload {
-  float[] matrix;
-  android.hardware.graphics.common.ColorTransform hint;
+parcelable KeyRequest {
+  byte[] request;
+  android.hardware.drm.KeyRequestType requestType;
+  String defaultUrl;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyRequestType.aidl
similarity index 86%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.aidl
copy to drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyRequestType.aidl
index b87870d..34b9615 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.aidl
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyRequestType.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,9 +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.drm;
 @Backing(type="int") @VintfStability
-enum HandleIndex {
-  EMPTY = -1,
-  CACHED = -2,
+enum KeyRequestType {
+  INITIAL = 0,
+  RENEWAL = 1,
+  RELEASE = 2,
+  UNKNOWN = 3,
+  NONE = 4,
+  UPDATE = 5,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/WhitePointNits.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeySetId.aidl
similarity index 88%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/WhitePointNits.aidl
copy to drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeySetId.aidl
index c3925d2..58dfe1a 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/WhitePointNits.aidl
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeySetId.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.drm;
 @VintfStability
-parcelable WhitePointNits {
-  float nits;
+parcelable KeySetId {
+  byte[] keySetId;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FloatColor.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyStatus.aidl
similarity index 87%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FloatColor.aidl
copy to drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyStatus.aidl
index faadf57..53ab70f 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FloatColor.aidl
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyStatus.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,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.drm;
 @VintfStability
-parcelable FloatColor {
-  float r;
-  float g;
-  float b;
-  float a;
+parcelable KeyStatus {
+  byte[] keyId;
+  android.hardware.drm.KeyStatusType type;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyStatusType.aidl
similarity index 84%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.aidl
copy to drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyStatusType.aidl
index b87870d..e88d388 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.aidl
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyStatusType.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,9 +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.drm;
 @Backing(type="int") @VintfStability
-enum HandleIndex {
-  EMPTY = -1,
-  CACHED = -2,
+enum KeyStatusType {
+  USABLE = 0,
+  EXPIRED = 1,
+  OUTPUTNOTALLOWED = 2,
+  STATUSPENDING = 3,
+  INTERNALERROR = 4,
+  USABLEINFUTURE = 5,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyType.aidl
similarity index 88%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.aidl
copy to drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyType.aidl
index b87870d..7a9d633 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.aidl
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyType.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,9 +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.drm;
 @Backing(type="int") @VintfStability
-enum HandleIndex {
-  EMPTY = -1,
-  CACHED = -2,
+enum KeyType {
+  OFFLINE = 0,
+  STREAMING = 1,
+  RELEASE = 2,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/WhitePointNits.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyValue.aidl
similarity index 88%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/WhitePointNits.aidl
copy to drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyValue.aidl
index c3925d2..35d7b77 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/WhitePointNits.aidl
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/KeyValue.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.drm;
 @VintfStability
-parcelable WhitePointNits {
-  float nits;
+parcelable KeyValue {
+  String key;
+  String value;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FloatColor.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/LogMessage.aidl
similarity index 86%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FloatColor.aidl
copy to drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/LogMessage.aidl
index faadf57..93f76e1 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FloatColor.aidl
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/LogMessage.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.drm;
 @VintfStability
-parcelable FloatColor {
-  float r;
-  float g;
-  float b;
-  float a;
+parcelable LogMessage {
+  long timeMs;
+  android.hardware.drm.LogPriority priority;
+  String message;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/LogPriority.aidl
similarity index 85%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.aidl
copy to drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/LogPriority.aidl
index b87870d..83362c3 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.aidl
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/LogPriority.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,9 +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.drm;
 @Backing(type="int") @VintfStability
-enum HandleIndex {
-  EMPTY = -1,
-  CACHED = -2,
+enum LogPriority {
+  UNKNOWN = 0,
+  DEFAULT = 1,
+  VERBOSE = 2,
+  DEBUG = 3,
+  INFO = 4,
+  WARN = 5,
+  ERROR = 6,
+  FATAL = 7,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/Mode.aidl
similarity index 87%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.aidl
copy to drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/Mode.aidl
index b87870d..7379774 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.aidl
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/Mode.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,9 +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.drm;
 @Backing(type="int") @VintfStability
-enum HandleIndex {
-  EMPTY = -1,
-  CACHED = -2,
+enum Mode {
+  UNENCRYPTED = 0,
+  AES_CTR = 1,
+  AES_CBC_CTS = 2,
+  AES_CBC = 3,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FloatColor.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/NumberOfSessions.aidl
similarity index 87%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FloatColor.aidl
copy to drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/NumberOfSessions.aidl
index faadf57..a421125 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FloatColor.aidl
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/NumberOfSessions.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,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.drm;
 @VintfStability
-parcelable FloatColor {
-  float r;
-  float g;
-  float b;
-  float a;
+parcelable NumberOfSessions {
+  int currentSessions;
+  int maxSessions;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/OfflineLicenseState.aidl
similarity index 87%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.aidl
copy to drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/OfflineLicenseState.aidl
index b87870d..629564d 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.aidl
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/OfflineLicenseState.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,9 +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.drm;
 @Backing(type="int") @VintfStability
-enum HandleIndex {
-  EMPTY = -1,
-  CACHED = -2,
+enum OfflineLicenseState {
+  UNKNOWN = 0,
+  USABLE = 1,
+  INACTIVE = 2,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/WhitePointNits.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/OpaqueData.aidl
similarity index 88%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/WhitePointNits.aidl
copy to drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/OpaqueData.aidl
index c3925d2..3085889 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/WhitePointNits.aidl
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/OpaqueData.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.drm;
 @VintfStability
-parcelable WhitePointNits {
-  float nits;
+parcelable OpaqueData {
+  byte[] opaqueData;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/WhitePointNits.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/Pattern.aidl
similarity index 88%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/WhitePointNits.aidl
copy to drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/Pattern.aidl
index c3925d2..b01562e 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/WhitePointNits.aidl
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/Pattern.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.drm;
 @VintfStability
-parcelable WhitePointNits {
-  float nits;
+parcelable Pattern {
+  int encryptBlocks;
+  int skipBlocks;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FloatColor.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/ProvideProvisionResponseResult.aidl
similarity index 86%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FloatColor.aidl
copy to drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/ProvideProvisionResponseResult.aidl
index faadf57..827de59 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FloatColor.aidl
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/ProvideProvisionResponseResult.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,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.drm;
 @VintfStability
-parcelable FloatColor {
-  float r;
-  float g;
-  float b;
-  float a;
+parcelable ProvideProvisionResponseResult {
+  byte[] certificate;
+  byte[] wrappedKey;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FloatColor.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/ProvisionRequest.aidl
similarity index 87%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FloatColor.aidl
copy to drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/ProvisionRequest.aidl
index faadf57..84c5662 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FloatColor.aidl
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/ProvisionRequest.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,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.drm;
 @VintfStability
-parcelable FloatColor {
-  float r;
-  float g;
-  float b;
-  float a;
+parcelable ProvisionRequest {
+  byte[] request;
+  String defaultUrl;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/WhitePointNits.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/SecureStop.aidl
similarity index 88%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/WhitePointNits.aidl
copy to drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/SecureStop.aidl
index c3925d2..81d2dfe 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/WhitePointNits.aidl
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/SecureStop.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.drm;
 @VintfStability
-parcelable WhitePointNits {
-  float nits;
+parcelable SecureStop {
+  byte[] opaqueData;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/WhitePointNits.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/SecureStopId.aidl
similarity index 88%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/WhitePointNits.aidl
copy to drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/SecureStopId.aidl
index c3925d2..2b904c8 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/WhitePointNits.aidl
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/SecureStopId.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.drm;
 @VintfStability
-parcelable WhitePointNits {
-  float nits;
+parcelable SecureStopId {
+  byte[] secureStopId;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/SecurityLevel.aidl
similarity index 83%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.aidl
copy to drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/SecurityLevel.aidl
index b87870d..65b2b9d 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.aidl
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/SecurityLevel.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,9 +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.drm;
 @Backing(type="int") @VintfStability
-enum HandleIndex {
-  EMPTY = -1,
-  CACHED = -2,
+enum SecurityLevel {
+  UNKNOWN = 0,
+  SW_SECURE_CRYPTO = 1,
+  SW_SECURE_DECODE = 2,
+  HW_SECURE_CRYPTO = 3,
+  HW_SECURE_DECODE = 4,
+  HW_SECURE_ALL = 5,
+  DEFAULT = 6,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FloatColor.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/SharedBuffer.aidl
similarity index 87%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FloatColor.aidl
copy to drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/SharedBuffer.aidl
index faadf57..973ef0d 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FloatColor.aidl
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/SharedBuffer.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.drm;
 @VintfStability
-parcelable FloatColor {
-  float r;
-  float g;
-  float b;
-  float a;
+parcelable SharedBuffer {
+  int bufferId;
+  long offset;
+  long size;
 }
diff --git a/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/Status.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/Status.aidl
new file mode 100644
index 0000000..c640689
--- /dev/null
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/Status.aidl
@@ -0,0 +1,77 @@
+/*
+ * 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.drm;
+@Backing(type="int") @VintfStability
+enum Status {
+  OK = 0,
+  ERROR_DRM_NO_LICENSE = 1,
+  ERROR_DRM_LICENSE_EXPIRED = 2,
+  ERROR_DRM_SESSION_NOT_OPENED = 3,
+  ERROR_DRM_CANNOT_HANDLE = 4,
+  ERROR_DRM_INVALID_STATE = 5,
+  BAD_VALUE = 6,
+  ERROR_DRM_NOT_PROVISIONED = 7,
+  ERROR_DRM_RESOURCE_BUSY = 8,
+  ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION = 9,
+  ERROR_DRM_DEVICE_REVOKED = 10,
+  ERROR_DRM_DECRYPT = 11,
+  ERROR_DRM_UNKNOWN = 12,
+  ERROR_DRM_INSUFFICIENT_SECURITY = 13,
+  ERROR_DRM_FRAME_TOO_LARGE = 14,
+  ERROR_DRM_SESSION_LOST_STATE = 15,
+  ERROR_DRM_RESOURCE_CONTENTION = 16,
+  CANNOT_DECRYPT_ZERO_SUBSAMPLES = 17,
+  CRYPTO_LIBRARY_ERROR = 18,
+  GENERAL_OEM_ERROR = 19,
+  GENERAL_PLUGIN_ERROR = 20,
+  INIT_DATA_INVALID = 21,
+  KEY_NOT_LOADED = 22,
+  LICENSE_PARSE_ERROR = 23,
+  LICENSE_POLICY_ERROR = 24,
+  LICENSE_RELEASE_ERROR = 25,
+  LICENSE_REQUEST_REJECTED = 26,
+  LICENSE_RESTORE_ERROR = 27,
+  LICENSE_STATE_ERROR = 28,
+  MALFORMED_CERTIFICATE = 29,
+  MEDIA_FRAMEWORK_ERROR = 30,
+  MISSING_CERTIFICATE = 31,
+  PROVISIONING_CERTIFICATE_ERROR = 32,
+  PROVISIONING_CONFIGURATION_ERROR = 33,
+  PROVISIONING_PARSE_ERROR = 34,
+  PROVISIONING_REQUEST_REJECTED = 35,
+  RETRYABLE_PROVISIONING_ERROR = 36,
+  SECURE_STOP_RELEASE_ERROR = 37,
+  STORAGE_READ_FAILURE = 38,
+  STORAGE_WRITE_FAILURE = 39,
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FloatColor.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/SubSample.aidl
similarity index 87%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FloatColor.aidl
copy to drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/SubSample.aidl
index faadf57..57d815e 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FloatColor.aidl
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/SubSample.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,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.drm;
 @VintfStability
-parcelable FloatColor {
-  float r;
-  float g;
-  float b;
-  float a;
+parcelable SubSample {
+  int numBytesOfClearData;
+  int numBytesOfEncryptedData;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/WhitePointNits.aidl b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/Uuid.aidl
similarity index 88%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/WhitePointNits.aidl
copy to drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/Uuid.aidl
index c3925d2..ec2eb16 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/WhitePointNits.aidl
+++ b/drm/aidl/aidl_api/android.hardware.drm/current/android/hardware/drm/Uuid.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.drm;
 @VintfStability
-parcelable WhitePointNits {
-  float nits;
+parcelable Uuid {
+  byte[] uuid;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl b/drm/aidl/android/hardware/drm/BufferType.aidl
similarity index 62%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
copy to drm/aidl/android/hardware/drm/BufferType.aidl
index a0a1d4b..089c950 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
+++ b/drm/aidl/android/hardware/drm/BufferType.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,
@@ -14,16 +14,11 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
-
-/**
- * Color representation as a floating point number in the range [0.0 - 1.0]
- */
+package android.hardware.drm;
 
 @VintfStability
-parcelable FloatColor {
-    float r;
-    float g;
-    float b;
-    float a;
+@Backing(type="int")
+enum BufferType {
+    SHARED_MEMORY = 0,
+    NATIVE_HANDLE = 1,
 }
diff --git a/drm/aidl/android/hardware/drm/DecryptResult.aidl b/drm/aidl/android/hardware/drm/DecryptResult.aidl
new file mode 100644
index 0000000..17e939b
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/DecryptResult.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.drm;
+
+/**
+ * The DecryptResult parcelable contains the result of
+ * ICryptoPlugin decrypt method.
+ */
+@VintfStability
+parcelable DecryptResult {
+    /** The number of decrypted bytes. */
+    int bytesWritten;
+
+    /**
+     * Vendor-specific error message if provided by the vendor's
+     * crypto HAL.
+     */
+    String detailedError;
+}
diff --git a/drm/aidl/android/hardware/drm/DestinationBuffer.aidl b/drm/aidl/android/hardware/drm/DestinationBuffer.aidl
new file mode 100644
index 0000000..0f1e3f5
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/DestinationBuffer.aidl
@@ -0,0 +1,45 @@
+/*
+ * 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.drm;
+
+import android.hardware.common.NativeHandle;
+import android.hardware.drm.BufferType;
+import android.hardware.drm.SharedBuffer;
+
+/**
+ * A decrypt destination buffer can be either normal user-space shared
+ * memory for the non-secure decrypt case, or it can be a secure buffer
+ * which is referenced by a native-handle. The native handle is allocated
+ * by the vendor's buffer allocator.
+ */
+@VintfStability
+parcelable DestinationBuffer {
+    /**
+     * The type of the buffer
+     */
+    BufferType type;
+    /**
+     * If type == SHARED_MEMORY, the decrypted data must be written
+     * to user-space non-secure shared memory.
+     */
+    SharedBuffer nonsecureMemory;
+    /**
+     * If type == NATIVE_HANDLE, the decrypted data must be written
+     * to secure memory referenced by the vendor's buffer allocator.
+     */
+    NativeHandle secureMemory;
+}
diff --git a/drm/aidl/android/hardware/drm/DrmMetric.aidl b/drm/aidl/android/hardware/drm/DrmMetric.aidl
new file mode 100644
index 0000000..6199af6
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/DrmMetric.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.drm;
+
+import android.hardware.drm.DrmMetricNamedValue;
+
+/**
+ * The metric being captured.
+ *
+ * A metric must have a name and at least one value. A metric may have 0 or
+ * more attributes. The fields of a Metric are opaque to the framework.
+ */
+@VintfStability
+parcelable DrmMetric {
+    String name;
+
+    /**
+     * Detail(s) about the metric being captured.
+     *
+     * The fields of an Attribute are opaque to the framework.
+     */
+    List<DrmMetricNamedValue> attributes;
+
+    /**
+     * Value(s) of the metric.
+     *
+     * A metric may have multiple values. The component name may be left empty
+     * if there is only supposed to be one value for the given metric. The
+     * fields of the Value are opaque to the framework.
+     */
+    List<DrmMetricNamedValue> values;
+}
diff --git a/drm/aidl/android/hardware/drm/DrmMetricGroup.aidl b/drm/aidl/android/hardware/drm/DrmMetricGroup.aidl
new file mode 100644
index 0000000..3b1f3c9
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/DrmMetricGroup.aidl
@@ -0,0 +1,61 @@
+/*
+ * 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.drm;
+
+import android.hardware.drm.DrmMetric;
+
+/**
+ * This message contains plugin-specific metrics made available to the client.
+ * The message is used for making vendor-specific metrics available to an
+ * application. The framework is not consuming any of the information.
+ *
+ * Metrics are grouped in instances of DrmMetricGroup. Each group contains
+ * multiple instances of Metric.
+ *
+ * Example:
+ *
+ * Capture the timing information of a buffer copy event, "buf_copy", broken
+ * out by the "size" of the buffer.
+ *
+ * DrmMetricGroup {
+ *   metrics[0] {
+ *     name: "buf_copy"
+ *     attributes[0] {
+ *       name: "size"
+ *       type: INT64_TYPE
+ *       int64Value: 1024
+ *     }
+ *     values[0] {
+ *       componentName: "operation_count"
+ *       type: INT64_TYPE
+ *       int64Value: 75
+ *     }
+ *     values[1] {
+ *       component_name: "average_time_seconds"
+ *       type: DOUBLE_TYPE
+ *       doubleValue: 0.00000042
+ *     }
+ *   }
+ * }
+ */
+@VintfStability
+parcelable DrmMetricGroup {
+    /**
+     * The list of metrics to be captured.
+     */
+    List<DrmMetric> metrics;
+}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl b/drm/aidl/android/hardware/drm/DrmMetricNamedValue.aidl
similarity index 63%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
copy to drm/aidl/android/hardware/drm/DrmMetricNamedValue.aidl
index a0a1d4b..5bb17a6 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
+++ b/drm/aidl/android/hardware/drm/DrmMetricNamedValue.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,
@@ -14,16 +14,15 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
+package android.hardware.drm;
+
+import android.hardware.drm.DrmMetricValue;
 
 /**
- * Color representation as a floating point number in the range [0.0 - 1.0]
+ * A name-value pair used in drm metrics.
  */
-
 @VintfStability
-parcelable FloatColor {
-    float r;
-    float g;
-    float b;
-    float a;
+parcelable DrmMetricNamedValue {
+    String name;
+    DrmMetricValue value;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl b/drm/aidl/android/hardware/drm/DrmMetricValue.aidl
similarity index 63%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
copy to drm/aidl/android/hardware/drm/DrmMetricValue.aidl
index a0a1d4b..0203f3f 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
+++ b/drm/aidl/android/hardware/drm/DrmMetricValue.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,
@@ -14,16 +14,14 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
+package android.hardware.drm;
 
 /**
- * Color representation as a floating point number in the range [0.0 - 1.0]
+ * The value of a metric or a metric's attribute.
  */
-
 @VintfStability
-parcelable FloatColor {
-    float r;
-    float g;
-    float b;
-    float a;
+union DrmMetricValue {
+    long int64Value;
+    double doubleValue;
+    String stringValue;
 }
diff --git a/drm/aidl/android/hardware/drm/EventType.aidl b/drm/aidl/android/hardware/drm/EventType.aidl
new file mode 100644
index 0000000..7a06eb0
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/EventType.aidl
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.drm;
+
+/**
+ * EventType enumerates the events that can be delivered by sendEvent
+ */
+@VintfStability
+@Backing(type="int")
+enum EventType {
+    /**
+     * This event type indicates that the app needs to request a certificate
+     * from the provisioning server. The request message data is obtained using
+     * getProvisionRequest().
+     */
+    PROVISION_REQUIRED,
+    /**
+     * This event type indicates that the app needs to request keys from a
+     * license server. The request message data is obtained using getKeyRequest.
+     */
+    KEY_NEEDED,
+    /**
+     * This event type indicates that the licensed usage duration for keys in a
+     * session has expired. The keys are no longer valid.
+     */
+    KEY_EXPIRED,
+    /**
+     * This event may indicate some specific vendor-defined condition, see your
+     * DRM provider documentation for details.
+     */
+    VENDOR_DEFINED,
+    /**
+     * This event indicates that a session opened by the app has been reclaimed
+     * by the resource manager.
+     */
+    SESSION_RECLAIMED,
+}
diff --git a/drm/aidl/android/hardware/drm/HdcpLevel.aidl b/drm/aidl/android/hardware/drm/HdcpLevel.aidl
new file mode 100644
index 0000000..3497b78
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/HdcpLevel.aidl
@@ -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 android.hardware.drm;
+
+/**
+ * HDCP specifications are defined by Digital Content Protection LLC (DCP).
+ *   "HDCP Specification Rev. 2.3 Interface Independent Adaptation"
+ *   "HDCP 2.3 on HDMI Specification"
+ */
+@VintfStability
+@Backing(type="int")
+enum HdcpLevel {
+    /**
+     * Unable to determine the HDCP level
+     */
+    HDCP_UNKNOWN,
+    /**
+     * No HDCP, output is unprotected
+     */
+    HDCP_NONE,
+    /**
+     * HDCP version 1.0
+     */
+    HDCP_V1,
+    /**
+     * HDCP version 2.0 Type 1.
+     */
+    HDCP_V2,
+    /**
+     * HDCP version 2.1 Type 1.
+     */
+    HDCP_V2_1,
+    /**
+     *  HDCP version 2.2 Type 1.
+     */
+    HDCP_V2_2,
+    /**
+     * No digital output, implicitly secure
+     */
+    HDCP_NO_OUTPUT,
+    /**
+     * HDCP version 2.3 Type 1.
+     */
+    HDCP_V2_3,
+}
diff --git a/drm/aidl/android/hardware/drm/HdcpLevels.aidl b/drm/aidl/android/hardware/drm/HdcpLevels.aidl
new file mode 100644
index 0000000..cd4642b
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/HdcpLevels.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.drm;
+
+import android.hardware.drm.HdcpLevel;
+
+@VintfStability
+parcelable HdcpLevels {
+    /** The lowest HDCP level for any connected displays. */
+    HdcpLevel connectedLevel;
+
+    /** The highest HDCP level that can be supported by the device. */
+    HdcpLevel maxLevel;
+}
diff --git a/drm/aidl/android/hardware/drm/ICryptoFactory.aidl b/drm/aidl/android/hardware/drm/ICryptoFactory.aidl
new file mode 100644
index 0000000..202bd3d
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/ICryptoFactory.aidl
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.drm;
+
+import android.hardware.drm.Uuid;
+
+/**
+ * ICryptoFactory is the main entry point for interacting with a vendor's
+ * crypto HAL to create crypto plugins.
+
+ * Crypto plugins create crypto sessions which are used by a codec to decrypt
+ * protected video content.
+ */
+@VintfStability
+interface ICryptoFactory {
+    /**
+     * Create a crypto plugin for the specified uuid and scheme-specific
+     * initialization data.
+     *
+     * @param uuid uniquely identifies the drm scheme. See
+     *     http://dashif.org/identifiers/protection for uuid assignments
+     *
+     * @param initData scheme-specific init data.
+     *
+     * @return A crypto plugin instance if successful, or null if not created.
+     */
+    @nullable android.hardware.drm.ICryptoPlugin createPlugin(
+            in Uuid uuid, in byte[] initData);
+
+    /**
+     * Determine if a crypto scheme is supported by this HAL.
+     *
+     * @param uuid identifies the crypto scheme in question
+     * @return must be true only if the scheme is supported
+     */
+    boolean isCryptoSchemeSupported(in Uuid uuid);
+}
diff --git a/drm/aidl/android/hardware/drm/ICryptoPlugin.aidl b/drm/aidl/android/hardware/drm/ICryptoPlugin.aidl
new file mode 100644
index 0000000..80a63df
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/ICryptoPlugin.aidl
@@ -0,0 +1,138 @@
+/*
+ * 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.drm;
+
+import android.hardware.common.Ashmem;
+import android.hardware.drm.DecryptResult;
+import android.hardware.drm.DestinationBuffer;
+import android.hardware.drm.LogMessage;
+import android.hardware.drm.Mode;
+import android.hardware.drm.Pattern;
+import android.hardware.drm.SharedBuffer;
+import android.hardware.drm.Status;
+import android.hardware.drm.SubSample;
+
+/**
+ * ICryptoPlugin is the HAL for vendor-provided crypto plugins.
+ *
+ * It allows crypto sessions to be opened and operated on, to
+ * load crypto keys for a codec to decrypt protected video content.
+ */
+@VintfStability
+interface ICryptoPlugin {
+    /**
+     * Decrypt an array of subsamples from the source memory buffer to the
+     * destination memory buffer.
+     *
+     * @param secure a flag to indicate if a secure decoder is being used.
+     *     This enables the plugin to configure buffer modes to work
+     *     consistently with a secure decoder.
+     * @param the keyId for the key that is used to do the decryption. The
+     *     keyId refers to a key in the associated MediaDrm instance.
+     * @param iv the initialization vector to use
+     * @param mode the crypto mode to use
+     * @param pattern the crypto pattern to use
+     * @param subSamples a vector of subsamples indicating the number
+     *     of clear and encrypted bytes to process. This allows the decrypt
+     *     call to operate on a range of subsamples in a single call
+     * @param source the input buffer for the decryption
+     * @param offset the offset of the first byte of encrypted data from
+     *     the base of the source buffer
+     * @param destination the output buffer for the decryption
+     *
+     * @return DecryptResult parcelable
+     *     Implicit error codes:
+     *       + ERROR_DRM_CANNOT_HANDLE in other failure cases
+     *       + ERROR_DRM_DECRYPT if the decrypt operation fails
+     *       + ERROR_DRM_FRAME_TOO_LARGE if the frame being decrypted into
+     *             the secure output buffer exceeds the size of the buffer
+     *       + ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION if required output
+     *             protections are not active
+     *       + ERROR_DRM_INSUFFICIENT_SECURITY if the security level of the
+     *             device is not sufficient to meet the requirements in
+     *             the license policy
+     *       + ERROR_DRM_INVALID_STATE if the device is in a state where it
+     *             is not able to perform decryption
+     *       + ERROR_DRM_LICENSE_EXPIRED if the license keys have expired
+     *       + ERROR_DRM_NO_LICENSE if no license keys have been loaded
+     *       + ERROR_DRM_RESOURCE_BUSY if the resources required to perform
+     *             the decryption are not available
+     *       + ERROR_DRM_SESSION_NOT_OPENED if the decrypt session is not
+     *             opened
+     */
+    DecryptResult decrypt(in boolean secure, in byte[] keyId, in byte[] iv, in Mode mode,
+            in Pattern pattern, in SubSample[] subSamples, in SharedBuffer source, in long offset,
+            in DestinationBuffer destination);
+
+    /**
+     * Get OEMCrypto or plugin error messages.
+     *
+     * @return LogMessages
+     *     Implicit error codes:
+     *       + GENERAL_OEM_ERROR on OEM-provided, low-level component failures;
+     *       + GENERAL_PLUGIN_ERROR on unexpected plugin-level errors.
+     */
+    List<LogMessage> getLogMessages();
+
+    /**
+     * Notify a plugin of the currently configured resolution.
+     *
+     * @param width - the display resolutions's width
+     * @param height - the display resolution's height
+     */
+    void notifyResolution(in int width, in int height);
+
+    /**
+     * Check if the specified mime-type requires a secure decoder
+     * component.
+     *
+     * @param mime The content mime-type
+     * @return must be true only if a secure decoder is required
+     * for the specified mime-type
+     */
+    boolean requiresSecureDecoderComponent(in String mime);
+
+    /**
+     * Associate a mediadrm session with this crypto session.
+     *
+     * @param sessionId the MediaDrm session ID to associate with
+     *     this crypto session
+     * @return (implicit) the status of the call, status can be:
+     *     ERROR_DRM_SESSION_NOT_OPENED if the session is not opened, or
+     *     ERROR_DRM_CANNOT_HANDLE if the operation is not supported by
+     *         the drm scheme
+     */
+    void setMediaDrmSession(in byte[] sessionId);
+
+    /**
+     * Set a shared memory base for subsequent decrypt operations.
+     * The buffer base is mmaped from a ParcelFileDesciptor in Ashmem
+     * which maps shared memory in the HAL module.
+     * After the shared buffer base is established, the decrypt() method
+     * receives SharedBuffer instances which specify the buffer address range
+     * for decrypt source and destination addresses.
+     *
+     * There can be multiple shared buffers per crypto plugin. The buffers
+     * are distinguished by the bufferId.
+     *
+     * @param base the base of the memory buffer identified by
+     *     bufferId
+     * @param bufferId identifies the specific shared buffer for which
+     *     the base is being set.
+     */
+    void setSharedBufferBase(in Ashmem base, in int bufferId);
+}
diff --git a/drm/aidl/android/hardware/drm/IDrmFactory.aidl b/drm/aidl/android/hardware/drm/IDrmFactory.aidl
new file mode 100644
index 0000000..b9622a4
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/IDrmFactory.aidl
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.drm;
+
+import android.hardware.drm.SecurityLevel;
+import android.hardware.drm.Uuid;
+
+/**
+ * IDrmFactory is the main entry point for interacting with a vendor's
+ * drm HAL to create drm plugin instances. A drm plugin instance
+ * creates drm sessions which are used to obtain keys for a crypto
+ * session so it can decrypt protected video content.
+ */
+@VintfStability
+interface IDrmFactory {
+    /**
+     * Create a drm plugin instance for the specified uuid and
+     * scheme-specific initialization data.
+     *
+     * @param uuid uniquely identifies the drm scheme. See
+     *     http://dashif.org/identifiers/protection for uuid assignments
+     * @param appPackageName identifies the package name of the calling
+     *     application.
+     *
+     * @return A DRM plugin instance if successful, or null if not created.
+     *     Implicit error codes:
+     *       + ERROR_DRM_CANNOT_HANDLE if the plugin cannot be created.
+     */
+    @nullable android.hardware.drm.IDrmPlugin createPlugin(
+            in Uuid uuid, in String appPackageName);
+
+    /**
+     * Return vector of uuids identifying crypto schemes supported by
+     * this HAL.
+     *
+     * @return List of uuids for which isCryptoSchemeSupported is true;
+     *      each uuid can be used as input to createPlugin.
+     */
+    List<Uuid> getSupportedCryptoSchemes();
+
+    /**
+     * Determine if the HAL factory is able to construct plugins that
+     * support a given media container format specified by mimeType
+     *
+     * @param mimeType identifies the mime type in question
+     *
+     * @return must be true only if the scheme is supported
+     */
+    boolean isContentTypeSupported(in String mimeType);
+
+    /**
+     * Determine if a specific security level is supported by the device.
+     *
+     * @param uuid identifies the crypto scheme in question
+     * @param mimeType identifies the mime type in question
+     * @param securityLevel specifies the security level required
+     *
+     * @return must be true only if the scheme is supported
+     */
+    boolean isCryptoSchemeSupported(
+            in Uuid uuid, in String mimeType, in SecurityLevel securityLevel);
+}
diff --git a/drm/aidl/android/hardware/drm/IDrmPlugin.aidl b/drm/aidl/android/hardware/drm/IDrmPlugin.aidl
new file mode 100644
index 0000000..e649f26
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/IDrmPlugin.aidl
@@ -0,0 +1,755 @@
+/*
+ * 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.drm;
+
+import android.hardware.drm.DrmMetricGroup;
+import android.hardware.drm.HdcpLevels;
+import android.hardware.drm.IDrmPluginListener;
+import android.hardware.drm.KeySetId;
+import android.hardware.drm.KeyRequest;
+import android.hardware.drm.KeyStatus;
+import android.hardware.drm.KeyType;
+import android.hardware.drm.KeyValue;
+import android.hardware.drm.LogMessage;
+import android.hardware.drm.NumberOfSessions;
+import android.hardware.drm.OfflineLicenseState;
+import android.hardware.drm.OpaqueData;
+import android.hardware.drm.ProvideProvisionResponseResult;
+import android.hardware.drm.ProvisionRequest;
+import android.hardware.drm.SecureStop;
+import android.hardware.drm.SecureStopId;
+import android.hardware.drm.SecurityLevel;
+
+/**
+ * IDrmPlugin is used to interact with a specific drm plugin that was
+ * created by IDrmFactory::createPlugin.
+ *
+ * A drm plugin provides methods for obtaining drm keys to be used by a codec
+ * to decrypt protected video content.
+ */
+@VintfStability
+interface IDrmPlugin {
+    /**
+     * Close a session on the DrmPlugin object
+     *
+     * @param sessionId the session id the call applies to
+     *
+     * @return (implicit) the status of the call:
+     *     BAD_VALUE if the sessionId is invalid
+     *     ERROR_DRM_INVALID_STATE if the HAL is in a state where
+     *         the session cannot be closed.
+     *     ERROR_DRM_SESSION_NOT_OPENED if the session is not opened
+     */
+    void closeSession(in byte[] sessionId);
+
+    /**
+     * Decrypt the provided input buffer with the cipher algorithm
+     * specified by setCipherAlgorithm and the key selected by keyId,
+     * and return the decrypted data.
+     *
+     * @param sessionId the session id the call applies to
+     * @param keyId the ID of the key to use for decryption
+     * @param input the input data to decrypt
+     * @param iv the initialization vector to use for decryption
+     *
+     * @return decrypted output buffer
+     *     Implicit error codes:
+     *       + BAD_VALUE if the sessionId is invalid
+     *       + ERROR_DRM_INVALID_STATE if the HAL is in a state where
+     *             the decrypt operation cannot be performed.
+     *       + ERROR_DRM_SESSION_NOT_OPENED if the session is not opened
+     */
+    byte[] decrypt(in byte[] sessionId, in byte[] keyId, in byte[] input, in byte[] iv);
+
+    /**
+     * Encrypt the provided input buffer with the cipher algorithm specified by
+     * setCipherAlgorithm and the key selected by keyId, and return the
+     * encrypted data.
+     *
+     * @param sessionId the session id the call applies to
+     * @param keyId the ID of the key to use for encryption
+     * @param input the input data to encrypt
+     * @param iv the initialization vector to use for encryption
+     *
+     * @return encrypted output buffer
+     *     Implicit error codes:
+     *       + BAD_VALUE if the sessionId is invalid
+     *       + ERROR_DRM_INVALID_STATE if the HAL is in a state where
+     *             the encrypt operation cannot be performed.
+     *       + ERROR_DRM_SESSION_NOT_OPENED if the session is not opened
+     */
+    byte[] encrypt(in byte[] sessionId, in byte[] keyId, in byte[] input, in byte[] iv);
+
+    /**
+     * Return the currently negotiated and max supported HDCP levels.
+     *
+     * The current level is based on the display(s) the device is connected to.
+     * If multiple HDCP-capable displays are simultaneously connected to
+     * separate interfaces, this method returns the lowest negotiated HDCP level
+     * of all interfaces.
+     *
+     * The maximum HDCP level is the highest level that can potentially be
+     * negotiated. It is a constant for any device, i.e. it does not depend on
+     * downstream receiving devices that could be connected. For example, if
+     * the device has HDCP 1.x keys and is capable of negotiating HDCP 1.x, but
+     * does not have HDCP 2.x keys, then the maximum HDCP capability would be
+     * reported as 1.x. If multiple HDCP-capable interfaces are present, it
+     * indicates the highest of the maximum HDCP levels of all interfaces.
+     *
+     * This method should only be used for informational purposes, not for
+     * enforcing compliance with HDCP requirements. Trusted enforcement of HDCP
+     * policies must be handled by the DRM system.
+     *
+     * @return HdcpLevels parcelable
+     *     Implicit error codes:
+     *       + ERROR_DRM_INVALID_STATE if the HAL is in a state where
+     *             the HDCP level cannot be queried
+     */
+    HdcpLevels getHdcpLevels();
+
+    /**
+     * A key request/response exchange occurs between the app and a License
+     * Server to obtain the keys required to decrypt the content.
+     * getKeyRequest() is used to obtain an opaque key request blob that is
+     * delivered to the license server.
+     *
+     * @param scope either a sessionId or a keySetId, depending on the
+     *     specified keyType. When the keyType is OFFLINE or STREAMING, scope
+     *     must be set to the sessionId the keys will be provided to. When the
+     *     keyType is RELEASE, scope must be set to the keySetId of the keys
+     *     being released.
+     * @param initData container-specific data, its meaning is interpreted
+     *     based on the mime type provided in the mimeType parameter. It could
+     *     contain, for example, the content ID, key ID or other data obtained
+     *     from the content metadata that is required to generate the key
+     *     request. initData must be empty when keyType is RELEASE.
+     * @param mimeType identifies the mime type of the content
+     * @param keyType specifies if the keys are to be used for streaming,
+     *     offline or a release
+     * @param optionalParameters included in the key request message to
+     *     allow a client application to provide additional message parameters
+     *     to the server.
+     *
+     * @return KeyRequest parcelable
+     *     Implicit error codes:
+     *       + BAD_VALUE if any parameters are invalid
+     *       + ERROR_DRM_CANNOT_HANDLE if getKeyRequest is not supported at
+     *             the time of the call
+     *       + ERROR_DRM_INVALID_STATE if the HAL is in a state where
+     *             a key request cannot be generated
+     *       + ERROR_DRM_NOT_PROVISIONED if the device requires provisioning
+     *             before it is able to generate a key request
+     *       + ERROR_DRM_RESOURCE_CONTENTION if client applications using the
+     *             hal are temporarily exceeding the available crypto resources
+     *             such that a retry of the operation is likely to succeed
+     *       + ERROR_DRM_SESSION_NOT_OPENED if the session is not opened
+     */
+    KeyRequest getKeyRequest(in byte[] scope, in byte[] initData, in String mimeType,
+            in KeyType keyType, in KeyValue[] optionalParameters);
+
+    /**
+     * Get Plugin error messages.
+     *
+     * @return LogMessages
+     *     Implicit error codes:
+     *       + GENERAL_OEM_ERROR on OEM-provided, low-level component failures;
+     *       + GENERAL_PLUGIN_ERROR on unexpected plugin-level errors.
+     */
+    List<LogMessage> getLogMessages();
+
+    /**
+     * Returns the plugin-specific metrics. Multiple metric groups may be
+     * returned in one call to getMetrics(). The scope and definition of the
+     * metrics is defined by the plugin.
+     *
+     * @return collection of metric groups provided by the plugin
+     *     Implicit error codes:
+     *       + ERROR_DRM_INVALID_STATE if the metrics are not available to be
+     *             returned.
+     */
+    List<DrmMetricGroup> getMetrics();
+
+    /**
+     * Return the current number of open sessions and the maximum number of
+     * sessions that may be opened simultaneously among all DRM instances
+     * for the active DRM scheme.
+     *
+     * @return NumberOfSessions parcelable
+     *     Implicit error codes:
+     *       + ERROR_DRM_INVALID_STATE if the HAL is in a state where the
+     *             number of sessions cannot be queried
+     */
+    NumberOfSessions getNumberOfSessions();
+
+    /**
+     * The keys in an offline license allow protected content to be
+     * played even if the device is not connected to a network.
+     * Offline licenses are stored on the device after a key
+     * request/response exchange when the key request KeyType is
+     * OFFLINE. Normally each app is responsible for keeping track of
+     * the KeySetIds it has created. In some situations however, it
+     * will be necessary to request the list of stored offline license
+     * KeySetIds. If an app loses the KeySetId for any stored licenses
+     * that it created, for example, it must be able to recover the
+     * stored KeySetIds so those licenses will be removed when they
+     * expire or when the app is uninstalled.
+     *
+     * This method returns a list of the KeySetIds for all offline
+     * licenses. The offline license KeySetId allows an app to query
+     * the status of an offline license or remove it.
+     *
+     * @return list of keySetIds
+     *     Implicit error codes:
+     *       + ERROR_DRM_INVALID_STATE if the HAL is in a state where the
+     *             KeySetIds can't be returned
+     */
+    List<KeySetId> getOfflineLicenseKeySetIds();
+
+    /**
+     * Request the state of an offline license. An offline license must
+     * be usable or inactive. The keys in a usable offline license are
+     * available for decryption. When the offline license state is
+     * inactive, the keys have been marked for release using
+     * getKeyRequest with KeyType RELEASE but the key response has not
+     * been received. The keys in an inactive offline license are not
+     * usable for decryption.
+     *
+     * @param keySetId the id of the offline license
+     *
+     * @return The offline license state, UNKNOWN, USABLE or INACTIVE.
+     *     Implicit error codes:
+     *       + BAD_VALUE if the license is not found
+     *       + ERROR_DRM_INVALID_STATE if the HAL is in a state where the
+     *             offline license state can't be queried
+     */
+    OfflineLicenseState getOfflineLicenseState(in KeySetId keySetId);
+
+    /**
+     * Read a byte array property value given the property name.
+     * See getPropertyString.
+     *
+     * @param propertyName the name of the property
+     *
+     * @return property value bye array
+     *     Implicit error codes:
+     *       + BAD_VALUE if the property name is invalid
+     *       + ERROR_DRM_CANNOT_HANDLE if the property is not supported
+     *       + ERROR_DRM_INVALID_STATE if the HAL is in a state where the
+     *             property cannot be obtained
+     */
+    byte[] getPropertyByteArray(in String propertyName);
+
+    /**
+     * A drm scheme can have properties that are settable and readable
+     * by an app. There are a few forms of property access methods,
+     * depending on the data type of the property.
+     *
+     * Property values defined by the public API are:
+     *   "vendor" [string] identifies the maker of the drm scheme
+     *   "version" [string] identifies the version of the drm scheme
+     *   "description" [string] describes the drm scheme
+     *   'deviceUniqueId' [byte array] The device unique identifier is
+     *   established during device provisioning and provides a means of
+     *   uniquely identifying each device.
+     *
+     * Since drm scheme properties may vary, additional field names may be
+     * defined by each DRM vendor. Refer to your DRM provider documentation
+     * for definitions of its additional field names.
+     *
+     * Read a string property value given the property name.
+     *
+     * @param propertyName the name of the property
+     *
+     * @return the property value string.
+     *     Implicit error codes:
+     *       + BAD_VALUE if the property name is invalid
+     *       + ERROR_DRM_CANNOT_HANDLE if the property is not supported
+     *       + ERROR_DRM_INVALID_STATE if the HAL is in a state where the
+     *             property cannot be obtained
+     */
+    String getPropertyString(in String propertyName);
+
+    /**
+     * A provision request/response exchange occurs between the app
+     * and a provisioning server to retrieve a device certificate.
+     * getProvisionRequest is used to obtain an opaque provisioning
+     * request blob that is delivered to the provisioning server.
+     *
+     * @param certificateType the type of certificate requested, e.g. "X.509"
+     * @param certificateAuthority identifies the certificate authority.
+     *     A certificate authority (CA) is an entity which issues digital
+     *     certificates for use by other parties. It is an example of a
+     *     trusted third party.
+     *
+     * @return ProvisionRequest parcelable
+     *     Implicit error codes:
+     *       + ERROR_DRM_CANNOT_HANDLE if the drm scheme does not require
+     *             provisioning
+     *       + ERROR_DRM_INVALID_STATE if the HAL is in a state where
+     *             the provision request cannot be generated
+     *       + ERROR_DRM_RESOURCE_CONTENTION if client applications using
+     *             the hal are temporarily exceeding the available crypto
+     *             resources such that a retry of the operation is likely
+     *             to succeed
+     */
+    ProvisionRequest getProvisionRequest(
+            in String certificateType, in String certificateAuthority);
+
+    /**
+     * Get all secure stops by secure stop ID
+     *
+     * @param secureStopId the ID of the secure stop to return.
+     *     The secure stop ID is delivered by the key server
+     *     as part of the key response and must also be known by the app.
+     *
+     * @return secure stop opaque object.
+     *     Implicit error codes:
+     *       + BAD_VALUE if the secureStopId is invalid
+     *       + ERROR_DRM_INVALID_STATE if the HAL is in a state where
+     *             the secure stop cannot be returned
+     */
+    SecureStop getSecureStop(in SecureStopId secureStopId);
+
+    /**
+     * Get the IDs of all secure stops on the device
+     *
+     * @return list of secure stops IDs.
+     *     Implicit error codes:
+     *       + ERROR_DRM_INVALID_STATE if the HAL is in a state where
+     *             the secure stop IDs list cannot be returned
+     */
+    List<SecureStopId> getSecureStopIds();
+
+    /**
+     * SecureStop is a way of enforcing the concurrent stream limit per
+     * subscriber.
+     *
+     * It can securely monitor the lifetime of sessions across device reboots
+     * by periodically persisting the session lifetime status in secure
+     * storage.
+     *
+     * A signed version of the sessionID is written to persistent storage on the
+     * device when each MediaCrypto object is created and periodically during
+     * playback. The sessionID is signed by the device private key to prevent
+     * tampering.
+     *
+     * When playback is completed the session is destroyed, and the secure
+     * stops are queried by the app. The app then delivers the secure stop
+     * message to a server which verifies the signature to confirm that the
+     * session and its keys have been removed from the device. The persisted
+     * record on the device is removed after receiving and verifying the
+     * signed response from the server.
+     *
+     * Get all secure stops on the device
+     *
+     * @return list of the opaque secure stop objects.
+     *     Implicit error codes:
+     *       + ERROR_DRM_INVALID_STATE if the HAL is in a state where
+     *             the secure stops cannot be returned
+     */
+    List<SecureStop> getSecureStops();
+
+    /**
+     * Return the current security level of a session. A session has an initial
+     * security level determined by the robustness of the DRM system's
+     * implementation on the device.
+     *
+     * @param sessionId the session id the call applies to
+     *
+     * @return the current security level for the session.
+     *     Implicit error codes:
+     *       + BAD_VALUE if the sessionId is invalid
+     *       + ERROR_DRM_INVALID_STATE if the HAL is in a state where
+     *             the security level cannot be queried
+     *       + ERROR_DRM_SESSION_NOT_OPENED if the session is not opened
+     */
+    SecurityLevel getSecurityLevel(in byte[] sessionId);
+
+    /**
+     * Open a new session at a requested security level. The security level
+     * represents the robustness of the device's DRM implementation. By default,
+     * sessions are opened at the native security level of the device which is
+     * the maximum level that can be supported. Overriding the security level is
+     * necessary when the decrypted frames need to be manipulated, such as for
+     * image compositing. The security level parameter must be equal to or lower
+     * than the native level. If the requested level is not supported, the next
+     * lower supported security level must be set. The level can be queried
+     * using {@link #getSecurityLevel}. A session ID is returned.
+     *
+     * @param level the requested security level
+     *
+     * @return sessionId
+     */
+    byte[] openSession(in SecurityLevel securityLevel);
+
+    /**
+     * After a key response is received by the app, it is provided to the
+     * Drm plugin using provideKeyResponse.
+     *
+     * @param scope may be a sessionId or a keySetId depending on the
+     *     type of the response. Scope should be set to the sessionId
+     *     when the response is for either streaming or offline key requests.
+     *     Scope should be set to the keySetId when the response is for
+     *     a release request.
+     * @param response the response from the key server that is being
+     *     provided to the drm HAL.
+     *
+     * @return a keySetId that can be used to later restore the keys to a new
+     *     session with the method restoreKeys when the response is for an
+     *     offline key request.
+     *     Implicit error codes:
+     *       + BAD_VALUE if any parameters are invalid
+     *       + ERROR_DRM_CANNOT_HANDLE if provideKeyResponse is not supported
+     *             at the time of the call
+     *       + ERROR_DRM_DEVICE_REVOKED if the device has been disabled by
+     *             the license policy
+     *       + ERROR_DRM_INVALID_STATE if the HAL is in a state where
+     *             a key response cannot be handled.
+     *       + ERROR_DRM_NOT_PROVISIONED if the device requires provisioning
+     *             before it can handle the key response
+     *       + ERROR_DRM_SESSION_NOT_OPENED if the session is not opened
+     */
+    KeySetId provideKeyResponse(in byte[] scope, in byte[] response);
+
+    /**
+     * After a provision response is received by the app from a provisioning
+     * server, it is provided to the Drm HAL using provideProvisionResponse.
+     * The HAL implementation must receive the provision request and
+     * store the provisioned credentials.
+     *
+     * @param response the opaque provisioning response received by the
+     * app from a provisioning server.
+     *
+     * @return ProvideProvisionResponseResult parcelable, which contains
+     *     the public certificate and encrypted private key that can be
+     *     used by signRSA to compute an RSA signature on a message.
+     *     Implicit error codes:
+     *       + BAD_VALUE if any parameters are invalid
+     *       + ERROR_DRM_DEVICE_REVOKED if the device has been disabled by
+     *             the license policy
+     *       + ERROR_DRM_INVALID_STATE if the HAL is in a state where the
+     *             provision response cannot be handled
+     */
+    ProvideProvisionResponseResult provideProvisionResponse(in byte[] response);
+
+    /**
+     * Request an informative description of the license for the session.
+     * The status is in the form of {name, value} pairs. Since DRM license
+     * policies vary by vendor, the specific status field names are
+     * determined by each DRM vendor. Refer to your DRM provider
+     * documentation for definitions of the field names for a particular
+     * drm scheme.
+     *
+     * @param sessionId the session id the call applies to
+     *
+     * @return a list of name value pairs describing the license.
+     *     Implicit error codes:
+     *       + ERROR_DRM_SESSION_NOT_OPENED if the session is not opened
+     *       + BAD_VALUE if any parameters are invalid
+     *       + ERROR_DRM_INVALID_STATE if the HAL is in a state where the
+     *             key status cannot be queried.
+     */
+    List<KeyValue> queryKeyStatus(in byte[] sessionId);
+
+    /**
+     * Release all secure stops on the device
+     *
+     * @return (implicit) the status of the call:
+     *     ERROR_DRM_INVALID_STATE if the HAL is in a state where
+     *         the secure stops cannot be released.
+     */
+    void releaseAllSecureStops();
+
+    /**
+     * Release a secure stop by secure stop ID
+     *
+     * @param secureStopId the ID of the secure stop to release.
+     *     The secure stop ID is delivered by the key server as
+     *     part of the key response and must also be known by the app.
+     *
+     * @return (implicit) the status of the call:
+     *     BAD_VALUE if the secureStopId is invalid
+     *     ERROR_DRM_INVALID_STATE if the HAL is in a state where
+     *         the secure stop cannot be released.
+     */
+    void releaseSecureStop(in SecureStopId secureStopId);
+
+    /**
+     * Release secure stops given a release message from the key server
+     *
+     * @param ssRelease the secure stop release message identifying
+     *     one or more secure stops to release. ssRelease is opaque,
+     *     it is passed directly from a DRM license server through
+     *     the app and media framework to the vendor HAL module.
+     *     The format and content of ssRelease must be defined by the
+     *     DRM scheme being implemented according to this HAL.
+     *     The DRM scheme can be identified by its UUID which
+     *     can be queried using IDrmFactory::isCryptoSchemeSupported.
+     *
+     * @return (implicit) the status of the call:
+     *     BAD_VALUE if ssRelease is invalid
+     *     ERROR_DRM_INVALID_STATE if the HAL is in a state wherei
+     *         the secure stop cannot be released.
+     */
+    void releaseSecureStops(in OpaqueData ssRelease);
+
+    /**
+     * Remove all secure stops on the device without requiring a secure
+     * stop release response message from the key server.
+     *
+     * @return (implicit) the status of the call:
+     *     ERROR_DRM_INVALID_STATE if the HAL is in a state where
+     *         the secure stops cannot be removed.
+     */
+    void removeAllSecureStops();
+
+    /**
+     * Remove the current keys from a session
+     *
+     * @param sessionId the session id the call applies to
+     *
+     * @return (implicit) the status of the call:
+     *     BAD_VALUE if the sessionId is invalid
+     *     ERROR_DRM_INVALID_STATE if the HAL is in a state where
+     *         the keys cannot be removed.
+     *     ERROR_DRM_SESSION_NOT_OPENED if the session is not opened
+     */
+    void removeKeys(in byte[] sessionId);
+
+    /**
+     * Normally offline licenses are released using a key
+     * request/response exchange using getKeyRequest where the KeyType
+     * is RELEASE, followed by provideKeyResponse. This allows the
+     * server to cryptographically confirm that the license has been
+     * removed and then adjust the count of offline licenses allocated
+     * to the device.
+     * <p>
+     * In some exceptional situations it will be necessary to directly
+     * remove offline licenses without notifying the server, which is
+     * performed by this method.
+     *
+     * @param keySetId the id of the offline license to remove
+     *
+     * @return (implicit) the status of the call:
+     *     BAD_VALUE if the license is not found
+     *     ERROR_DRM_INVALID_STATE if the HAL is in a state where
+     *         the KeySetIds can't be removed.
+     */
+    void removeOfflineLicense(in KeySetId keySetId);
+
+    /**
+     * Remove a secure stop given its secure stop ID, without requiring
+     * a secure stop release response message from the key server.
+     *
+     * @param secureStopId the ID of the secure stop to release.
+     *
+     * @return the status of the call:
+     *     BAD_VALUE if the secureStopId is invalid
+     *     ERROR_DRM_INVALID_STATE if the HAL is in a state where
+     *         the secure stop cannot be removed.
+     */
+    void removeSecureStop(in SecureStopId secureStopId);
+
+    /**
+     * Check if the specified mime-type & security level require a secure decoder
+     * component.
+     *
+     * @param mime The content mime-type
+     * @param level the requested security level
+     *
+     * @return must be true if and only if a secure decoder is
+     *     required for the specified mime-type & security level
+     */
+    boolean requiresSecureDecoder(in String mime, in SecurityLevel level);
+
+    /**
+     * Check if the specified mime-type requires a secure decoder component
+     * at the highest security level supported on the device.
+     *
+     * @param mime The content mime-type
+     *
+     * @return must be true if and only if a secure decoder is required
+     *     for the specified mime-type
+     */
+    boolean requiresSecureDecoderDefault(in String mime);
+
+    /**
+     * Restore persisted offline keys into a new session
+     *
+     * @param sessionId the session id the call applies to
+     * @param keySetId identifies the keys to load, obtained from
+     *     a prior call to provideKeyResponse().
+     *
+     * @return (implicit) the status of the call:
+     *     ERROR_DRM_SESSION_NOT_OPENED if the session is not opened
+     *     BAD_VALUE if any parameters are invalid
+     *     ERROR_DRM_INVALID_STATE if the HAL is in a state where
+     *         keys cannot be restored.
+     */
+    void restoreKeys(in byte[] sessionId, in KeySetId keySetId);
+
+    /**
+     * The following methods implement operations on a CryptoSession to support
+     * encrypt, decrypt, sign verify operations on operator-provided
+     * session keys.
+     *
+     *
+     * Set the cipher algorithm to be used for the specified session.
+     *
+     * @param sessionId the session id the call applies to
+     * @param algorithm the algorithm to use. The string conforms to JCA
+     *     Standard Names for Cipher Transforms and is case insensitive. An
+     *     example algorithm is "AES/CBC/PKCS5Padding".
+     *
+     * @return (implicit) the status of the call:
+     *     BAD_VALUE if any parameters are invalid
+     *     ERROR_DRM_INVALID_STATE  if the HAL is in a state where
+     *         the algorithm cannot be set.
+     *     ERROR_DRM_SESSION_NOT_OPENED if the session is not opened`
+     */
+    void setCipherAlgorithm(in byte[] sessionId, in String algorithm);
+
+    /**
+     * Plugins call the following methods to deliver events to the
+     * java app.
+     *
+     *
+     * Set a listener for a drm session. This allows the drm HAL to
+     * make asynchronous calls back to the client of IDrm.
+     *
+     * @param listener instance of IDrmPluginListener to receive the events
+     */
+    void setListener(in IDrmPluginListener listener);
+
+    /**
+     * Set the MAC algorithm to be used for computing hashes in a session.
+     *
+     * @param sessionId the session id the call applies to
+     * @param algorithm the algorithm to use. The string conforms to JCA
+     *     Standard Names for Mac Algorithms and is case insensitive. An example MAC
+     *     algorithm string is "HmacSHA256".
+     *
+     * @return (implicit) the status of the call:
+     *     BAD_VALUE if any parameters are invalid
+     *     ERROR_DRM_INVALID_STATE  if the HAL is in a state where
+     *         the algorithm cannot be set.
+     *     ERROR_DRM_SESSION_NOT_OPENED if the session is not opened`
+     */
+    void setMacAlgorithm(in byte[] sessionId, in String algorithm);
+
+    /**
+     * Set playback id of a drm session. The playback id can be used to join drm session metrics
+     * with metrics from other low level media components, e.g. codecs, or metrics from the high
+     * level player.
+     *
+     * @param sessionId drm session id
+     * @param playbackId high level playback id
+     *
+     * @return (implicit) the status of the call:
+     *    ERROR_DRM_SESSION_NOT_OPENED if the drm session cannot be found
+     */
+    void setPlaybackId(in byte[] sessionId, in String playbackId);
+
+    /**
+     * Write a property byte array value given the property name
+     *
+     * @param propertyName the name of the property
+     * @param value the value to write
+     *
+     * @return (implicit) the status of the call:
+     *     BAD_VALUE if the property name is invalid
+     *     ERROR_DRM_CANNOT_HANDLE if the property is not supported
+     *     ERROR_DRM_INVALID_STATE if the HAL is in a state where the
+     *         property cannot be set
+     */
+    void setPropertyByteArray(in String propertyName, in byte[] value);
+
+    /**
+     * Write a property string value given the property name
+     *
+     * @param propertyName the name of the property
+     * @param value the value to write
+     *
+     * @return (implicit) status of the call:
+     *     BAD_VALUE if the property name is invalid
+     *     ERROR_DRM_CANNOT_HANDLE if the property is not supported
+     *     ERROR_DRM_INVALID_STATE if the HAL is in a state where the
+     *         property cannot be set
+     */
+    void setPropertyString(in String propertyName, in String value);
+
+    /**
+     * Compute a signature over the provided message using the mac algorithm
+     * specified by setMacAlgorithm and the key selected by keyId and return
+     * the signature.
+     *
+     * @param sessionId the session id the call applies to
+     * @param keyId the ID of the key to use for decryption
+     * @param message the message to compute a signature over
+     *
+     * @return signature computed over the message
+     *     Implicit error codes:
+     *       + ERROR_DRM_SESSION_NOT_OPENED if the session is not opened
+     *       + BAD_VALUE if any parameters are invalid
+     *       + ERROR_DRM_INVALID_STATE if the HAL is in a state where the
+     *             sign operation cannot be performed.
+     */
+    byte[] sign(in byte[] sessionId, in byte[] keyId, in byte[] message);
+
+    /**
+     * Compute an RSA signature on the provided message using the specified
+     * algorithm.
+     *
+     * @param sessionId the session id the call applies to
+     * @param algorithm the signing algorithm, such as "RSASSA-PSS-SHA1"
+     *     or "PKCS1-BlockType1"
+     * @param message the message to compute the signature on
+     * @param wrappedKey the private key returned during provisioning as
+     *     returned by provideProvisionResponse.
+     *
+     * @return signature computed over the message
+     *     Implicit error codes:
+     *       + BAD_VALUE if any parameters are invalid
+     *       + ERROR_DRM_INVALID_STATE if the HAL is in a state where the
+     *             signRSA operation operation cannot be performed
+     *       + ERROR_DRM_SESSION_NOT_OPENED if the session is not opened
+     */
+    byte[] signRSA(
+            in byte[] sessionId, in String algorithm, in byte[] message,
+            in byte[] wrappedkey);
+
+    /**
+     * Compute a hash of the provided message using the mac algorithm specified
+     * by setMacAlgorithm and the key selected by keyId, and compare with the
+     * expected result.
+     *
+     * @param sessionId the session id the call applies to
+     * @param keyId the ID of the key to use for decryption
+     * @param message the message to compute a hash of
+     * @param signature the signature to verify
+     *
+     * @return true if the signature is verified positively, false otherwise.
+     *     Implicit error codes:
+     *       + ERROR_DRM_SESSION_NOT_OPENED if the session is not opened
+     *       + BAD_VALUE if any parameters are invalid
+     *       + ERROR_DRM_INVALID_STATE if the HAL is in a state where the
+     *             verify operation cannot be performed.
+     */
+    boolean verify(
+            in byte[] sessionId, in byte[] keyId, in byte[] message,
+            in byte[] signature);
+}
diff --git a/drm/aidl/android/hardware/drm/IDrmPluginListener.aidl b/drm/aidl/android/hardware/drm/IDrmPluginListener.aidl
new file mode 100644
index 0000000..d52da66
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/IDrmPluginListener.aidl
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.drm;
+
+import android.hardware.drm.EventType;
+import android.hardware.drm.KeyStatus;
+
+/**
+ * IDrmPluginListener is a listener interface for Drm events sent from an
+ * IDrmPlugin instance.
+ */
+@VintfStability
+interface IDrmPluginListener {
+    /**
+     * Legacy event sending method, it sends events of various types using a
+     * single overloaded set of parameters. This form is deprecated.
+     *
+     * @param eventType the type of the event
+     * @param sessionId identifies the session the event originated from
+     * @param data event-specific data blob
+     */
+    oneway void onEvent(in EventType eventType, in byte[] sessionId, in byte[] data);
+
+    /**
+     * Send a license expiration update to the listener. The expiration
+     * update indicates how long the current keys are valid before they
+     * need to be renewed.
+     *
+     * @param sessionId identifies the session the event originated from
+     * @param expiryTimeInMS the time when the keys need to be renewed.
+     * The time is in milliseconds, relative to the Unix epoch. A time
+     * of 0 indicates that the keys never expire.
+     */
+    oneway void onExpirationUpdate(in byte[] sessionId, in long expiryTimeInMS);
+
+    /**
+     * Send a keys change event to the listener. The keys change event
+     * indicates the status of each key in the session. Keys can be
+     * indicated as being usable, expired, outputnotallowed or statuspending.
+     *
+     * @param sessionId identifies the session the event originated from
+     * @param keyStatusList indicates the status for each key ID in the
+     * session.
+     * @param hasNewUsableKey indicates if the event includes at least one
+     * key that has become usable.
+     */
+    oneway void onKeysChange(
+            in byte[] sessionId, in KeyStatus[] keyStatusList, in boolean hasNewUsableKey);
+
+    /**
+     * Some device crypto hardware is incapable of retaining crypto
+     * session state across suspend and resume cycles. A
+     * SessionLostState event must be signaled when a session has
+     * become invalid for this reason. This event must not be used to
+     * indicate a failure in the crypto system. Closing the session
+     * and opening a new one must allow the application to resume
+     * normal use of the drm hal module.
+     *
+     * @param sessionId identifies the session that has been invalidated
+     */
+    oneway void onSessionLostState(in byte[] sessionId);
+}
diff --git a/drm/aidl/android/hardware/drm/KeyRequest.aidl b/drm/aidl/android/hardware/drm/KeyRequest.aidl
new file mode 100644
index 0000000..0c73205
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/KeyRequest.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.drm;
+
+import android.hardware.drm.KeyRequestType;
+
+@VintfStability
+parcelable KeyRequest {
+    /** The opaque key request blob. */
+    byte[] request;
+
+    /**
+     * Enumerated type:
+     *     INITIAL - the first key request for a license
+     *     NONE - indicates that no request is needed because the keys
+     *         are already loaded
+     *     RENEWAL - is a subsequent key request used to refresh the
+     *         keys in a license
+     *     RELEASE - indicates keys are being released
+     *     UPDATE - indicates that the keys need to be refetched after
+     *         the initial license request
+     */
+    KeyRequestType requestType;
+
+    /**
+     * The URL that the request may be sent to,
+     * if provided by the drm HAL. The app can choose to
+     * override this URL. If the HAL implementation does not provide
+     * a defaultUrl, the returned string must be empty.
+     */
+    String defaultUrl;
+}
diff --git a/drm/aidl/android/hardware/drm/KeyRequestType.aidl b/drm/aidl/android/hardware/drm/KeyRequestType.aidl
new file mode 100644
index 0000000..3a603ff
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/KeyRequestType.aidl
@@ -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.
+ */
+
+package android.hardware.drm;
+
+/**
+ * An app determines the type of a key request returned from getKeyRequest.
+ */
+@VintfStability
+@Backing(type="int")
+enum KeyRequestType {
+    /**
+     * Key request type is for an initial license request
+     */
+    INITIAL,
+    /**
+     * Key request type is for license renewal. Renewal requests are used
+     * to extend the validity period for streaming keys.
+     */
+    RENEWAL,
+    /**
+     * Key request type is a release. A key release causes offline keys
+     * to become available for streaming.
+     */
+    RELEASE,
+    /**
+     * Key request type is unknown due to some error condition.
+     */
+    UNKNOWN,
+    /**
+     * Keys are already loaded. No key request is needed.
+     */
+    NONE,
+    /**
+     * Keys have previously been loaded. An additional (non-renewal) license
+     * request is needed.
+     */
+    UPDATE,
+}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl b/drm/aidl/android/hardware/drm/KeySetId.aidl
similarity index 62%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
copy to drm/aidl/android/hardware/drm/KeySetId.aidl
index a0a1d4b..be0ce0e 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
+++ b/drm/aidl/android/hardware/drm/KeySetId.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,
@@ -14,16 +14,9 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
-
-/**
- * Color representation as a floating point number in the range [0.0 - 1.0]
- */
+package android.hardware.drm;
 
 @VintfStability
-parcelable FloatColor {
-    float r;
-    float g;
-    float b;
-    float a;
+parcelable KeySetId {
+    byte[] keySetId;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl b/drm/aidl/android/hardware/drm/KeyStatus.aidl
similarity index 61%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
copy to drm/aidl/android/hardware/drm/KeyStatus.aidl
index a0a1d4b..16e042a 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
+++ b/drm/aidl/android/hardware/drm/KeyStatus.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,
@@ -14,16 +14,16 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
+package android.hardware.drm;
+
+import android.hardware.drm.KeyStatusType;
 
 /**
- * Color representation as a floating point number in the range [0.0 - 1.0]
+ * Used by sendKeysChange to report the usability status of each key
+ * to the app.
  */
-
 @VintfStability
-parcelable FloatColor {
-    float r;
-    float g;
-    float b;
-    float a;
+parcelable KeyStatus {
+    byte[] keyId;
+    KeyStatusType type;
 }
diff --git a/drm/aidl/android/hardware/drm/KeyStatusType.aidl b/drm/aidl/android/hardware/drm/KeyStatusType.aidl
new file mode 100644
index 0000000..6902d87
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/KeyStatusType.aidl
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.drm;
+
+@VintfStability
+@Backing(type="int")
+enum KeyStatusType {
+    /**
+     * The key is currently usable to decrypt media data.
+     */
+    USABLE,
+    /**
+     * The key is no longer usable to decrypt media data because its expiration
+     * time has passed.
+     */
+    EXPIRED,
+    /**
+     * The key is not currently usable to decrypt media data because its output
+     * requirements cannot currently be met.
+     */
+    OUTPUTNOTALLOWED,
+    /**
+     * The status of the key is not yet known and is being determined.
+     */
+    STATUSPENDING,
+    /**
+     * The key is not currently usable to decrypt media data because of an
+     * internal error in processing unrelated to input parameters.
+     */
+    INTERNALERROR,
+    /**
+     * The key is not yet usable to decrypt media because the start
+     * time is in the future. The key must become usable when
+     * its start time is reached.
+     */
+    USABLEINFUTURE,
+}
diff --git a/drm/aidl/android/hardware/drm/KeyType.aidl b/drm/aidl/android/hardware/drm/KeyType.aidl
new file mode 100644
index 0000000..78b4d83
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/KeyType.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.drm;
+
+@VintfStability
+@Backing(type="int")
+enum KeyType {
+    /**
+     * Drm keys can be for offline content or for online streaming.
+     * Offline keys are persisted on the device and may be used when the device
+     * is disconnected from the network.
+     */
+    OFFLINE,
+    /**
+     * Keys for streaming are not persisted and require the device to be
+     * connected to the network for periodic renewal.
+     */
+    STREAMING,
+    /**
+     * The Release type is used to request that offline keys be no longer
+     * restricted to offline use.
+     */
+    RELEASE,
+}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl b/drm/aidl/android/hardware/drm/KeyValue.aidl
similarity index 62%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
copy to drm/aidl/android/hardware/drm/KeyValue.aidl
index a0a1d4b..e26781b 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
+++ b/drm/aidl/android/hardware/drm/KeyValue.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,
@@ -14,16 +14,10 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
-
-/**
- * Color representation as a floating point number in the range [0.0 - 1.0]
- */
+package android.hardware.drm;
 
 @VintfStability
-parcelable FloatColor {
-    float r;
-    float g;
-    float b;
-    float a;
+parcelable KeyValue {
+    String key;
+    String value;
 }
diff --git a/drm/aidl/android/hardware/drm/LogMessage.aidl b/drm/aidl/android/hardware/drm/LogMessage.aidl
new file mode 100644
index 0000000..8ac1ced
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/LogMessage.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.drm;
+
+import android.hardware.drm.LogPriority;
+
+/**
+ * Returned by getLogMessages to report error diagnostics to the
+ * app.
+ *
+ * The |message| field is for informational purposes only, and
+ * NOT meant to be parsed programmatically when handling errors.
+ * For programmatic error handling, please check the return |Status|
+ * of APIs instead.
+ */
+@VintfStability
+parcelable LogMessage {
+    /**
+     * Epoch time in milliseconds.
+     */
+    long timeMs;
+    LogPriority priority;
+    String message;
+}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl b/drm/aidl/android/hardware/drm/LogPriority.aidl
similarity index 62%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
copy to drm/aidl/android/hardware/drm/LogPriority.aidl
index a0a1d4b..4db3b40 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
+++ b/drm/aidl/android/hardware/drm/LogPriority.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,
@@ -14,16 +14,17 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
-
-/**
- * Color representation as a floating point number in the range [0.0 - 1.0]
- */
+package android.hardware.drm;
 
 @VintfStability
-parcelable FloatColor {
-    float r;
-    float g;
-    float b;
-    float a;
+@Backing(type="int")
+enum LogPriority {
+    UNKNOWN,
+    DEFAULT,
+    VERBOSE,
+    DEBUG,
+    INFO,
+    WARN,
+    ERROR,
+    FATAL,
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl b/drm/aidl/android/hardware/drm/Mode.aidl
similarity index 63%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
copy to drm/aidl/android/hardware/drm/Mode.aidl
index a0a1d4b..6fc0065 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
+++ b/drm/aidl/android/hardware/drm/Mode.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,
@@ -14,16 +14,16 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
+package android.hardware.drm;
 
 /**
- * Color representation as a floating point number in the range [0.0 - 1.0]
+ * Enumerate the supported crypto modes
  */
-
 @VintfStability
-parcelable FloatColor {
-    float r;
-    float g;
-    float b;
-    float a;
+@Backing(type="int")
+enum Mode {
+    UNENCRYPTED = 0,
+    AES_CTR = 1,
+    AES_CBC_CTS = 2,
+    AES_CBC = 3,
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl b/drm/aidl/android/hardware/drm/NumberOfSessions.aidl
similarity index 60%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
copy to drm/aidl/android/hardware/drm/NumberOfSessions.aidl
index a0a1d4b..75b7c2e 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
+++ b/drm/aidl/android/hardware/drm/NumberOfSessions.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,
@@ -14,16 +14,13 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
-
-/**
- * Color representation as a floating point number in the range [0.0 - 1.0]
- */
+package android.hardware.drm;
 
 @VintfStability
-parcelable FloatColor {
-    float r;
-    float g;
-    float b;
-    float a;
+parcelable NumberOfSessions {
+    /** The number of currently opened sessions. */
+    int currentSessions;
+
+    /** The maximum number of sessions that the device can support. */
+    int maxSessions;
 }
diff --git a/drm/aidl/android/hardware/drm/OfflineLicenseState.aidl b/drm/aidl/android/hardware/drm/OfflineLicenseState.aidl
new file mode 100644
index 0000000..0f447db
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/OfflineLicenseState.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.drm;
+
+@VintfStability
+@Backing(type="int")
+enum OfflineLicenseState {
+    /**
+     * Offline license state is unknown
+     */
+    UNKNOWN,
+    /**
+     * Offline license state is usable, the keys are usable for decryption.
+     */
+    USABLE,
+    /**
+     * Offline license state is inactive, the keys have been marked for
+     * release using {@link #getKeyRequest} with KEY_TYPE_RELEASE but the
+     * key response has not been received.
+     */
+    INACTIVE,
+}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl b/drm/aidl/android/hardware/drm/OpaqueData.aidl
similarity index 62%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
copy to drm/aidl/android/hardware/drm/OpaqueData.aidl
index a0a1d4b..6b2a2e7 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
+++ b/drm/aidl/android/hardware/drm/OpaqueData.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,
@@ -14,16 +14,9 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
-
-/**
- * Color representation as a floating point number in the range [0.0 - 1.0]
- */
+package android.hardware.drm;
 
 @VintfStability
-parcelable FloatColor {
-    float r;
-    float g;
-    float b;
-    float a;
+parcelable OpaqueData {
+    byte[] opaqueData;
 }
diff --git a/drm/aidl/android/hardware/drm/Pattern.aidl b/drm/aidl/android/hardware/drm/Pattern.aidl
new file mode 100644
index 0000000..88d22cf
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/Pattern.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.drm;
+
+/**
+ * A crypto Pattern is a repeating sequence of encrypted and clear blocks
+ * occurring within the bytes indicated by mNumBytesOfEncryptedDatad bytes
+ * of a subsample. Patterns are used to reduce the CPU overhead of
+ * decrypting samples. As an example, HLS uses 1:9 patterns where every
+ * 10th block is encrypted.
+ */
+@VintfStability
+parcelable Pattern {
+    /**
+     * The number of blocks to be encrypted in the pattern. If zero,
+     * pattern encryption is inoperative.
+     */
+    int encryptBlocks;
+
+    /**
+     * The number of blocks to be skipped (left clear) in the pattern. If
+     * zero, pattern encryption is inoperative.
+     */
+    int skipBlocks;
+}
diff --git a/drm/aidl/android/hardware/drm/ProvideProvisionResponseResult.aidl b/drm/aidl/android/hardware/drm/ProvideProvisionResponseResult.aidl
new file mode 100644
index 0000000..e9f1e2b
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/ProvideProvisionResponseResult.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.drm;
+
+@VintfStability
+parcelable ProvideProvisionResponseResult {
+    /**
+     * The public certificate resulting from the provisioning
+     * operation, if any. An empty vector indicates that no
+     * certificate was returned.
+     */
+    byte[] certificate;
+
+    /**
+     * An opaque object containing encrypted private key material
+     * to be used by signRSA when computing an RSA signature on a
+     * message, see the signRSA method.
+     */
+    byte[] wrappedKey;
+}
diff --git a/drm/aidl/android/hardware/drm/ProvisionRequest.aidl b/drm/aidl/android/hardware/drm/ProvisionRequest.aidl
new file mode 100644
index 0000000..eb42d32
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/ProvisionRequest.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.drm;
+
+@VintfStability
+parcelable ProvisionRequest {
+    /** The opaque certificate request blob. */
+    byte[] request;
+
+    /**
+     * The URL that the provisioning request may be sent to,
+     * if known by the HAL implementation. An app can choose to
+     * override this URL. If the HAL implementation does not provide
+     * a defaultUrl, the returned string must be empty.
+     */
+    String defaultUrl;
+}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl b/drm/aidl/android/hardware/drm/SecureStop.aidl
similarity index 63%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
copy to drm/aidl/android/hardware/drm/SecureStop.aidl
index a0a1d4b..37cfbd3 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
+++ b/drm/aidl/android/hardware/drm/SecureStop.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,
@@ -14,16 +14,12 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
+package android.hardware.drm;
 
 /**
- * Color representation as a floating point number in the range [0.0 - 1.0]
+ * Encapsulates a secure stop opaque object.
  */
-
 @VintfStability
-parcelable FloatColor {
-    float r;
-    float g;
-    float b;
-    float a;
+parcelable SecureStop {
+    byte[] opaqueData;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl b/drm/aidl/android/hardware/drm/SecureStopId.aidl
similarity index 62%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
copy to drm/aidl/android/hardware/drm/SecureStopId.aidl
index a0a1d4b..775e60b 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
+++ b/drm/aidl/android/hardware/drm/SecureStopId.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,
@@ -14,16 +14,9 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
-
-/**
- * Color representation as a floating point number in the range [0.0 - 1.0]
- */
+package android.hardware.drm;
 
 @VintfStability
-parcelable FloatColor {
-    float r;
-    float g;
-    float b;
-    float a;
+parcelable SecureStopId {
+    byte[] secureStopId;
 }
diff --git a/drm/aidl/android/hardware/drm/SecurityLevel.aidl b/drm/aidl/android/hardware/drm/SecurityLevel.aidl
new file mode 100644
index 0000000..aac1b68
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/SecurityLevel.aidl
@@ -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.
+ */
+
+package android.hardware.drm;
+
+@VintfStability
+@Backing(type="int")
+enum SecurityLevel {
+    /**
+     * Unable to determine the security level
+     */
+    UNKNOWN,
+    /**
+     * Software-based whitebox crypto
+     */
+    SW_SECURE_CRYPTO,
+    /**
+     * Software-based whitebox crypto and an obfuscated decoder
+     */
+    SW_SECURE_DECODE,
+    /**
+     * DRM key management and crypto operations are performed within a
+     * hardware backed trusted execution environment
+     */
+    HW_SECURE_CRYPTO,
+    /**
+     * DRM key management, crypto operations and decoding of content
+     * are performed within a hardware backed trusted execution environment
+     */
+    HW_SECURE_DECODE,
+    /**
+     * DRM key management, crypto operations, decoding of content and all
+     * handling of the media (compressed and uncompressed) is handled within
+     * a hardware backed trusted execution environment.
+     */
+    HW_SECURE_ALL,
+    /**
+     * The default security level is defined as the highest security level
+     * supported on the device.
+     */
+    DEFAULT,
+}
diff --git a/drm/aidl/android/hardware/drm/SharedBuffer.aidl b/drm/aidl/android/hardware/drm/SharedBuffer.aidl
new file mode 100644
index 0000000..6977284
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/SharedBuffer.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.drm;
+
+/**
+ * SharedBuffer describes a decrypt buffer which is defined by a bufferId, an
+ * offset and a size.  The offset is relative to the shared memory base for the
+ * memory region identified by bufferId, which is established by
+ * setSharedMemoryBase().
+ */
+@VintfStability
+parcelable SharedBuffer {
+    /**
+     * The unique buffer identifier
+     */
+    int bufferId;
+    /**
+     * The offset from the shared memory base
+     */
+    long offset;
+    /**
+     * The size of the shared buffer in bytes
+     */
+    long size;
+}
diff --git a/drm/aidl/android/hardware/drm/Status.aidl b/drm/aidl/android/hardware/drm/Status.aidl
new file mode 100644
index 0000000..ee57d64
--- /dev/null
+++ b/drm/aidl/android/hardware/drm/Status.aidl
@@ -0,0 +1,221 @@
+/*
+ * 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.drm;
+
+@VintfStability
+@Backing(type="int")
+enum Status {
+    /**
+     * The DRM plugin must return OK when an operation completes without any
+     * errors.
+     */
+    OK,
+    /**
+     * The DRM plugin must return ERROR_DRM_NO_LICENSE, when decryption is
+     * attempted and no license keys have been provided.
+     */
+    ERROR_DRM_NO_LICENSE,
+    /**
+     * ERROR_DRM_LICENSE_EXPIRED must be returned when an attempt is made
+     * to use a license and the keys in that license have expired.
+     */
+    ERROR_DRM_LICENSE_EXPIRED,
+    /**
+     * The DRM plugin must return ERROR_DRM_SESSION_NOT_OPENED when an
+     * attempt is made to use a session that has not been opened.
+     */
+    ERROR_DRM_SESSION_NOT_OPENED,
+    /**
+     * The DRM plugin must return ERROR_DRM_CANNOT_HANDLE when an unsupported
+     * data format or operation is attempted.
+     */
+    ERROR_DRM_CANNOT_HANDLE,
+    /**
+     * ERROR_DRM_INVALID_STATE must be returned when the device is in a state
+     * where it is not able to perform decryption.
+     */
+    ERROR_DRM_INVALID_STATE,
+    /**
+     * The DRM plugin must return BAD_VALUE whenever an illegal parameter is
+     * passed to one of the interface functions.
+     */
+    BAD_VALUE,
+    /**
+     * The DRM plugin must return ERROR_DRM_NOT_PROVISIONED from getKeyRequest,
+     * openSession or provideKeyResponse when the device has not yet been
+     * provisioned.
+     */
+    ERROR_DRM_NOT_PROVISIONED,
+    /**
+     * ERROR_DRM_RESOURCE_BUSY must be returned when resources, such as drm
+     * sessions or secure buffers are not available to perform a requested
+     * operation because they are already in use.
+     */
+    ERROR_DRM_RESOURCE_BUSY,
+    /**
+     * The DRM Plugin must return ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION
+     * when the output protection level enabled on the device is not
+     * sufficient to meet the requirements in the license policy.  HDCP is an
+     * example of a form of output protection.
+     */
+    ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION,
+    /**
+     * The DRM Plugin must return ERROR_DRM_DEVICE_REVOKED from
+     * provideProvisionResponse and provideKeyResponse if the response indicates
+     * that the device has been revoked. Device revocation means that the device
+     * is no longer permitted to play content.
+     */
+    ERROR_DRM_DEVICE_REVOKED,
+    /**
+     * The DRM Plugin must return ERROR_DRM_DECRYPT if the CryptoPlugin
+     * decrypt operation fails.
+     */
+    ERROR_DRM_DECRYPT,
+    /**
+     * ERROR_DRM_UNKNOWN must be returned when a fatal failure occurs and no
+     * other defined error is appropriate.
+     */
+    ERROR_DRM_UNKNOWN,
+    /**
+     * The drm HAL module must return ERROR_DRM_INSUFFICIENT_SECURITY
+     * from the crypto plugin decrypt method when the security level
+     * of the device is not sufficient to meet the requirements in the
+     * license policy.
+     */
+    ERROR_DRM_INSUFFICIENT_SECURITY,
+    /**
+     * The drm HAL module must return ERROR_FRAME_TOO_LARGE from the
+     * decrypt method when the frame being decrypted into the secure
+     * output buffer exceeds the size of the buffer.
+     */
+    ERROR_DRM_FRAME_TOO_LARGE,
+    /**
+     * This error must be returned from any session method when an
+     * attempt is made to use the session after the crypto hardware
+     * state has been invalidated. Some devices are not able to
+     * retain crypto session state across device suspend/resume which
+     * results in invalid session state.
+     */
+    ERROR_DRM_SESSION_LOST_STATE,
+    /**
+     * The drm HAL module must return this error if client
+     * applications using the hal are temporarily exceeding the
+     * capacity of available crypto resources such that a retry of
+     * the operation is likely to succeed.
+     */
+    ERROR_DRM_RESOURCE_CONTENTION,
+    /**
+     * queueSecureInput buffer called with 0 subsamples.
+     */
+    CANNOT_DECRYPT_ZERO_SUBSAMPLES,
+    /**
+     * An error happened within the crypto library used by the drm plugin.
+     */
+    CRYPTO_LIBRARY_ERROR,
+    /**
+     * Non-specific error reported by the device OEM subsystem.
+     */
+    GENERAL_OEM_ERROR,
+    /**
+     * Unexpected internal failure in the drm/crypto plugin.
+     */
+    GENERAL_PLUGIN_ERROR,
+    /**
+     * The init data parameter passed to getKeyRequest is empty or invalid.
+     */
+    INIT_DATA_INVALID,
+    /**
+     * Either the key was not loaded from the license before attempting the
+     * operation, or the key ID parameter provided by the app is incorrect.
+     */
+    KEY_NOT_LOADED,
+    /**
+     * The license response was empty, fields are missing or otherwise unable
+     * to be parsed.
+     */
+    LICENSE_PARSE_ERROR,
+    /**
+     * The operation (e.g. to renew or persist a license) is prohibited by the
+     * license policy.
+     */
+    LICENSE_POLICY_ERROR,
+    /**
+     * Failed to generate a release request because a field in the stored
+     * license is empty or malformed.
+     */
+    LICENSE_RELEASE_ERROR,
+    /**
+     * The license server detected an error in the license request.
+     */
+    LICENSE_REQUEST_REJECTED,
+    /**
+     * Failed to restore an offline license because a field is empty or
+     * malformed.
+     */
+    LICENSE_RESTORE_ERROR,
+    /**
+     * License is in an invalid state for the attempted operation.
+     */
+    LICENSE_STATE_ERROR,
+    /**
+     * Certificate is malformed or is of the wrong type.
+     */
+    MALFORMED_CERTIFICATE,
+    /**
+     * Failure in the media framework.
+     */
+    MEDIA_FRAMEWORK_ERROR,
+    /**
+     * Certificate has not been set.
+     */
+    MISSING_CERTIFICATE,
+    /**
+     * There was an error loading the provisioned certificate.
+     */
+    PROVISIONING_CERTIFICATE_ERROR,
+    /**
+     * Required steps where not performed before provisioning was attempted.
+     */
+    PROVISIONING_CONFIGURATION_ERROR,
+    /**
+     * The provisioning response was empty, fields are missing or otherwise
+     * unable to be parsed.
+     */
+    PROVISIONING_PARSE_ERROR,
+    /**
+     * The provisioning server detected an error in the provisioning request.
+     */
+    PROVISIONING_REQUEST_REJECTED,
+    /**
+     * Provisioning failed in a way that is likely to succeed on a subsequent
+     * attempt.
+     */
+    RETRYABLE_PROVISIONING_ERROR,
+    /**
+     * Failed to generate a secure stop request because a field in the stored
+     * license is empty or malformed.
+     */
+    SECURE_STOP_RELEASE_ERROR,
+    /**
+     * The plugin was unable to read data from the filesystem.
+     */
+    STORAGE_READ_FAILURE,
+    /**
+     * The plugin was unable to write data to the filesystem.
+     */
+    STORAGE_WRITE_FAILURE,
+}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl b/drm/aidl/android/hardware/drm/SubSample.aidl
similarity index 60%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
copy to drm/aidl/android/hardware/drm/SubSample.aidl
index a0a1d4b..68a8fb1 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
+++ b/drm/aidl/android/hardware/drm/SubSample.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,
@@ -14,16 +14,14 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
+package android.hardware.drm;
 
 /**
- * Color representation as a floating point number in the range [0.0 - 1.0]
+ * A subsample consists of some number of bytes of clear (unencrypted)
+ * data followed by a number of bytes of encrypted data.
  */
-
 @VintfStability
-parcelable FloatColor {
-    float r;
-    float g;
-    float b;
-    float a;
+parcelable SubSample {
+    int numBytesOfClearData;
+    int numBytesOfEncryptedData;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl b/drm/aidl/android/hardware/drm/Uuid.aidl
similarity index 62%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
copy to drm/aidl/android/hardware/drm/Uuid.aidl
index a0a1d4b..b36c409 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
+++ b/drm/aidl/android/hardware/drm/Uuid.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,
@@ -14,16 +14,9 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
-
-/**
- * Color representation as a floating point number in the range [0.0 - 1.0]
- */
+package android.hardware.drm;
 
 @VintfStability
-parcelable FloatColor {
-    float r;
-    float g;
-    float b;
-    float a;
+parcelable Uuid {
+    byte[] uuid;
 }
diff --git a/dumpstate/aidl/Android.bp b/dumpstate/aidl/Android.bp
index e18eade..22d836b 100644
--- a/dumpstate/aidl/Android.bp
+++ b/dumpstate/aidl/Android.bp
@@ -34,7 +34,6 @@
             enabled: false,
         },
         ndk: {
-            separate_platform_variant: false,
             vndk: {
                 enabled: true,
             },
diff --git a/dumpstate/aidl/android/hardware/dumpstate/IDumpstateDevice.aidl b/dumpstate/aidl/android/hardware/dumpstate/IDumpstateDevice.aidl
index 3b42546..b994d04 100644
--- a/dumpstate/aidl/android/hardware/dumpstate/IDumpstateDevice.aidl
+++ b/dumpstate/aidl/android/hardware/dumpstate/IDumpstateDevice.aidl
@@ -103,8 +103,9 @@
      * @param timeoutMillis An approximate "budget" for how much time this call has been allotted.
      *     If execution runs longer than this, the IDumpstateDevice service may be killed and only
      *     partial information will be included in the report.
-     * @return If error, return service specific error with code
-     *           ERROR_UNSUPPORTED_MODE or ERROR_DEVICE_LOGGING_NOT_ENABLED
+     * @throws ServiceSpecificException with one of the following values:
+     *         |ERROR_UNSUPPORTED_MODE|,
+     *         |ERROR_DEVICE_LOGGING_NOT_ENABLED|
      */
     void dumpstateBoard(in ParcelFileDescriptor[] fd, in DumpstateMode mode, in long timeoutMillis);
 
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/gnss/aidl/Android.bp b/gnss/aidl/Android.bp
index b197eae..12dd0ac 100644
--- a/gnss/aidl/Android.bp
+++ b/gnss/aidl/Android.bp
@@ -24,9 +24,27 @@
 }
 
 aidl_interface {
+    name: "android.hardware.gnss.visibility_control",
+    vendor_available: true,
+    srcs: ["android/hardware/gnss/visibility_control/*.aidl"],
+    stability: "vintf",
+    backend: {
+        java: {
+            platform_apis: true,
+        },
+        ndk: {
+            vndk: {
+                enabled: true,
+            },
+        },
+    },
+}
+
+aidl_interface {
     name: "android.hardware.gnss",
     vendor_available: true,
     srcs: ["android/hardware/gnss/*.aidl"],
+    imports: ["android.hardware.gnss.visibility_control"],
     stability: "vintf",
     backend: {
         java: {
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl b/gnss/aidl/aidl_api/android.hardware.gnss.visibility_control/current/android/hardware/gnss/visibility_control/IGnssVisibilityControl.aidl
similarity index 81%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl
copy to gnss/aidl/aidl_api/android.hardware.gnss.visibility_control/current/android/hardware/gnss/visibility_control/IGnssVisibilityControl.aidl
index df07c9c..7ef08d2 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss.visibility_control/current/android/hardware/gnss/visibility_control/IGnssVisibilityControl.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,9 +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.gnss.visibility_control;
 @VintfStability
-parcelable ColorTransformPayload {
-  float[] matrix;
-  android.hardware.graphics.common.ColorTransform hint;
+interface IGnssVisibilityControl {
+  void enableNfwLocationAccess(in String[] proxyApps);
+  void setCallback(in android.hardware.gnss.visibility_control.IGnssVisibilityControlCallback callback);
 }
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss.visibility_control/current/android/hardware/gnss/visibility_control/IGnssVisibilityControlCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss.visibility_control/current/android/hardware/gnss/visibility_control/IGnssVisibilityControlCallback.aidl
new file mode 100644
index 0000000..37e1886
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss.visibility_control/current/android/hardware/gnss/visibility_control/IGnssVisibilityControlCallback.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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.visibility_control;
+@VintfStability
+interface IGnssVisibilityControlCallback {
+  void nfwNotifyCb(in android.hardware.gnss.visibility_control.IGnssVisibilityControlCallback.NfwNotification notification);
+  boolean isInEmergencySession();
+  @Backing(type="int") @VintfStability
+  enum NfwProtocolStack {
+    CTRL_PLANE = 0,
+    SUPL = 1,
+    IMS = 10,
+    SIM = 11,
+    OTHER_PROTOCOL_STACK = 100,
+  }
+  @Backing(type="int") @VintfStability
+  enum NfwRequestor {
+    CARRIER = 0,
+    OEM = 10,
+    MODEM_CHIPSET_VENDOR = 11,
+    GNSS_CHIPSET_VENDOR = 12,
+    OTHER_CHIPSET_VENDOR = 13,
+    AUTOMOBILE_CLIENT = 20,
+    OTHER_REQUESTOR = 100,
+  }
+  @Backing(type="int") @VintfStability
+  enum NfwResponseType {
+    REJECTED = 0,
+    ACCEPTED_NO_LOCATION_PROVIDED = 1,
+    ACCEPTED_LOCATION_PROVIDED = 2,
+  }
+  @VintfStability
+  parcelable NfwNotification {
+    String proxyAppPackageName;
+    android.hardware.gnss.visibility_control.IGnssVisibilityControlCallback.NfwProtocolStack protocolStack;
+    String otherProtocolStackName;
+    android.hardware.gnss.visibility_control.IGnssVisibilityControlCallback.NfwRequestor requestor;
+    String requestorId;
+    android.hardware.gnss.visibility_control.IGnssVisibilityControlCallback.NfwResponseType responseType;
+    boolean inEmergencyMode;
+    boolean isCachedLocation;
+  }
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IAGnss.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IAGnss.aidl
index f02e08c..1a69f33 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IAGnss.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IAGnss.aidl
@@ -37,8 +37,8 @@
   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);
+  void setServer(in android.hardware.gnss.IAGnssCallback.AGnssType type, in @utf8InCpp String hostname, in int port);
+  void dataConnOpen(in long networkHandle, in @utf8InCpp String apn, in android.hardware.gnss.IAGnss.ApnIpType apnIpType);
   @Backing(type="int") @VintfStability
   enum ApnIpType {
     INVALID = 0,
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 ea98030..1b4c581 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
@@ -44,7 +44,43 @@
   @nullable android.hardware.gnss.IGnssGeofence getExtensionGnssGeofence();
   @nullable android.hardware.gnss.IGnssNavigationMessageInterface getExtensionGnssNavigationMessage();
   android.hardware.gnss.IAGnss getExtensionAGnss();
+  android.hardware.gnss.IGnssDebug getExtensionGnssDebug();
+  android.hardware.gnss.visibility_control.IGnssVisibilityControl getExtensionGnssVisibilityControl();
+  void start();
+  void stop();
+  void injectTime(in long timeMs, in long timeReferenceMs, in int uncertaintyMs);
+  void injectLocation(in android.hardware.gnss.GnssLocation location);
+  void injectBestLocation(in android.hardware.gnss.GnssLocation location);
+  void deleteAidingData(in android.hardware.gnss.IGnss.GnssAidingData aidingDataFlags);
+  void setPositionMode(in android.hardware.gnss.IGnss.GnssPositionMode mode, in android.hardware.gnss.IGnss.GnssPositionRecurrence recurrence, in int minIntervalMs, in int preferredAccuracyMeters, in int preferredTimeMs, in boolean lowPowerMode);
   const int ERROR_INVALID_ARGUMENT = 1;
   const int ERROR_ALREADY_INIT = 2;
   const int ERROR_GENERIC = 3;
+  @Backing(type="int") @VintfStability
+  enum GnssPositionMode {
+    STANDALONE = 0,
+    MS_BASED = 1,
+    MS_ASSISTED = 2,
+  }
+  @Backing(type="int") @VintfStability
+  enum GnssPositionRecurrence {
+    RECURRENCE_PERIODIC = 0,
+    RECURRENCE_SINGLE = 1,
+  }
+  @Backing(type="int") @VintfStability
+  enum GnssAidingData {
+    DELETE_EPHEMERIS = 1,
+    DELETE_ALMANAC = 2,
+    DELETE_POSITION = 4,
+    DELETE_TIME = 8,
+    DELETE_IONO = 16,
+    DELETE_UTC = 32,
+    DELETE_HEALTH = 64,
+    DELETE_SVDIR = 128,
+    DELETE_SVSTEER = 256,
+    DELETE_SADATA = 512,
+    DELETE_RTI = 1024,
+    DELETE_CELLDB_INFO = 32768,
+    DELETE_ALL = 65535,
+  }
 }
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl
index fb0931c..957a75f 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssCallback.aidl
@@ -35,8 +35,60 @@
 @VintfStability
 interface IGnssCallback {
   void gnssSetCapabilitiesCb(in int capabilities);
+  void gnssStatusCb(in android.hardware.gnss.IGnssCallback.GnssStatusValue status);
+  void gnssSvStatusCb(in android.hardware.gnss.IGnssCallback.GnssSvInfo[] svInfoList);
+  void gnssLocationCb(in android.hardware.gnss.GnssLocation location);
+  void gnssNmeaCb(in long timestamp, in @utf8InCpp String nmea);
+  void gnssAcquireWakelockCb();
+  void gnssReleaseWakelockCb();
+  void gnssSetSystemInfoCb(in android.hardware.gnss.IGnssCallback.GnssSystemInfo info);
+  void gnssRequestTimeCb();
+  void gnssRequestLocationCb(in boolean independentFromGnss, in boolean isUserEmergency);
+  const int CAPABILITY_SCHEDULING = 1;
+  const int CAPABILITY_MSB = 2;
+  const int CAPABILITY_MSA = 4;
+  const int CAPABILITY_SINGLE_SHOT = 8;
+  const int CAPABILITY_ON_DEMAND_TIME = 16;
+  const int CAPABILITY_GEOFENCING = 32;
+  const int CAPABILITY_MEASUREMENTS = 64;
+  const int CAPABILITY_NAV_MESSAGES = 128;
+  const int CAPABILITY_LOW_POWER_MODE = 256;
   const int CAPABILITY_SATELLITE_BLOCKLIST = 512;
+  const int CAPABILITY_MEASUREMENT_CORRECTIONS = 1024;
+  const int CAPABILITY_ANTENNA_INFO = 2048;
   const int CAPABILITY_CORRELATION_VECTOR = 4096;
   const int CAPABILITY_SATELLITE_PVT = 8192;
   const int CAPABILITY_MEASUREMENT_CORRECTIONS_FOR_DRIVING = 16384;
+  @Backing(type="int") @VintfStability
+  enum GnssStatusValue {
+    NONE = 0,
+    SESSION_BEGIN = 1,
+    SESSION_END = 2,
+    ENGINE_ON = 3,
+    ENGINE_OFF = 4,
+  }
+  @Backing(type="int") @VintfStability
+  enum GnssSvFlags {
+    NONE = 0,
+    HAS_EPHEMERIS_DATA = 1,
+    HAS_ALMANAC_DATA = 2,
+    USED_IN_FIX = 4,
+    HAS_CARRIER_FREQUENCY = 8,
+  }
+  @VintfStability
+  parcelable GnssSvInfo {
+    int svid;
+    android.hardware.gnss.GnssConstellationType constellation;
+    float cN0Dbhz;
+    float basebandCN0DbHz;
+    float elevationDegrees;
+    float azimuthDegrees;
+    long carrierFrequencyHz;
+    int svFlag;
+  }
+  @VintfStability
+  parcelable GnssSystemInfo {
+    int yearOfHw;
+    @utf8InCpp String name;
+  }
 }
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/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementInterface.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementInterface.aidl
index 24d6f9c..9c4a54b 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementInterface.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssMeasurementInterface.aidl
@@ -36,4 +36,11 @@
 interface IGnssMeasurementInterface {
   void setCallback(in android.hardware.gnss.IGnssMeasurementCallback callback, in boolean enableFullTracking, in boolean enableCorrVecOutputs);
   void close();
+  void setCallbackWithOptions(in android.hardware.gnss.IGnssMeasurementCallback callback, in android.hardware.gnss.IGnssMeasurementInterface.Options options);
+  @VintfStability
+  parcelable Options {
+    boolean enableFullTracking;
+    boolean enableCorrVecOutputs;
+    int intervalMs;
+  }
 }
diff --git a/gnss/aidl/android/hardware/gnss/IAGnss.aidl b/gnss/aidl/android/hardware/gnss/IAGnss.aidl
index 3e256e2..30b2167 100644
--- a/gnss/aidl/android/hardware/gnss/IAGnss.aidl
+++ b/gnss/aidl/android/hardware/gnss/IAGnss.aidl
@@ -60,7 +60,7 @@
      * @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);
+    void setServer(in AGnssType type, in @utf8InCpp String hostname, in int port);
 
     /**
      * Notifies GNSS that a data connection is available and sets the network handle,
@@ -75,5 +75,6 @@
      * @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);
+    void dataConnOpen(
+            in long networkHandle, in @utf8InCpp String apn, in ApnIpType apnIpType);
 }
diff --git a/gnss/aidl/android/hardware/gnss/IGnss.aidl b/gnss/aidl/android/hardware/gnss/IGnss.aidl
index 91403ca..4ddc6a6 100644
--- a/gnss/aidl/android/hardware/gnss/IGnss.aidl
+++ b/gnss/aidl/android/hardware/gnss/IGnss.aidl
@@ -16,15 +16,18 @@
 
 package android.hardware.gnss;
 
+import android.hardware.gnss.GnssLocation;
 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;
 import android.hardware.gnss.IGnssPowerIndication;
 import android.hardware.gnss.IGnssPsds;
+import android.hardware.gnss.visibility_control.IGnssVisibilityControl;
 
 /**
  * Represents the standard GNSS (Global Navigation Satellite System) interface.
@@ -43,6 +46,53 @@
     /** Any other error. */
     const int ERROR_GENERIC = 3;
 
+    /** Requested operational mode for GNSS operation. */
+    @VintfStability
+    @Backing(type="int")
+    enum GnssPositionMode {
+        /** Mode for running GNSS standalone (no assistance). */
+        STANDALONE = 0,
+        /** AGNSS MS-Based mode. */
+        MS_BASED = 1,
+        /**
+         * AGNSS MS-Assisted mode. This mode is not maintained by the platform anymore.
+         * It is strongly recommended to use MS_BASED instead.
+         */
+        MS_ASSISTED = 2,
+    }
+
+    /** Requested recurrence mode for GNSS operation. */
+    @VintfStability
+    @Backing(type="int")
+    enum GnssPositionRecurrence {
+        /** Receive GNSS fixes on a recurring basis at a specified period. */
+        RECURRENCE_PERIODIC = 0,
+        /** Request a single shot GNSS fix. */
+        RECURRENCE_SINGLE = 1,
+    }
+
+    /**
+     * Flags used to specify which aiding data to delete when calling
+     * deleteAidingData().
+     */
+    @VintfStability
+    @Backing(type="int")
+    enum GnssAidingData {
+        DELETE_EPHEMERIS = 0x0001,
+        DELETE_ALMANAC = 0x0002,
+        DELETE_POSITION = 0x0004,
+        DELETE_TIME = 0x0008,
+        DELETE_IONO = 0x0010,
+        DELETE_UTC = 0x0020,
+        DELETE_HEALTH = 0x0040,
+        DELETE_SVDIR = 0x0080,
+        DELETE_SVSTEER = 0x0100,
+        DELETE_SADATA = 0x0200,
+        DELETE_RTI = 0x0400,
+        DELETE_CELLDB_INFO = 0x8000,
+        DELETE_ALL = 0xFFFF
+    }
+
     /**
      * Opens the interface and provides the callback routines to the implementation of this
      * interface.
@@ -134,4 +184,97 @@
      * @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();
+
+    /**
+     * This method returns the IGnssVisibilityControl.
+     *
+     * @return Handle to the IGnssVisibilityControl.
+     */
+    IGnssVisibilityControl getExtensionGnssVisibilityControl();
+
+    /**
+     * Starts a location output stream using the IGnssCallback gnssLocationCb(), following the
+     * settings from the most recent call to setPositionMode().
+     *
+     * This output must operate independently of any GNSS location batching operations,
+     * see the IGnssBatching for details.
+     */
+    void start();
+
+    /**
+     * Stops the location output stream.
+     */
+    void stop();
+
+    /**
+     * Injects the current time.
+     *
+     * @param timeMs This is the UTC time received from the NTP server, its value is given in
+     *     milliseconds since January 1, 1970.
+     * @param timeReferenceMs The corresponding value of SystemClock.elapsedRealtime() from the
+     *     device when the NTP response was received in milliseconds.
+     * @param uncertaintyMs Uncertainty associated with the value represented by time. Represented
+     *     in milliseconds.
+     */
+    void injectTime(in long timeMs, in long timeReferenceMs, in int uncertaintyMs);
+
+    /**
+     * Injects current location from another (typically network) location provider.
+     *
+     * @param location Current location from the location provider
+     */
+    void injectLocation(in GnssLocation location);
+
+    /**
+     * Injects current location from the best available location provider.
+     *
+     * Unlike injectLocation, this method may inject a recent GNSS location from the HAL
+     * implementation, if that is the best available location known to the framework.
+     *
+     * @param location Location information from the best available location provider.
+     */
+    void injectBestLocation(in GnssLocation location);
+
+    /**
+     * Specifies that the next call to start will not use the information defined in the flags.
+     * GnssAidingData value of DELETE_ALL is passed for a cold start.
+     *
+     * @param aidingDataFlags Flags specifying the aiding data to be deleted.
+     */
+    void deleteAidingData(in GnssAidingData aidingDataFlags);
+
+    /**
+     * Sets the GnssPositionMode parameter, its associated recurrence value, the time between fixes,
+     * requested fix accuracy, time to first fix.
+     *
+     * @param mode Parameter must be one of MS_BASED or STANDALONE. It is allowed by the platform
+     *     (and it is recommended) to fallback to MS_BASED if MS_ASSISTED is passed in, and MS_BASED
+     *     is supported.
+     * @param recurrence GNSS position recurrence value, either periodic or single.
+     * @param minIntervalMs Represents the time between fixes in milliseconds.
+     * @param preferredAccuracyMeters Represents the requested fix accuracy in meters.
+     * @param preferredTimeMs Represents the requested time to first fix in milliseconds.
+     * @param lowPowerMode When true, and IGnss is the only client to the GNSS hardware, the GNSS
+     *     hardware must make strong tradeoffs to substantially restrict power use. Specifically, in
+     *     the case of a several second long minIntervalMs, the GNSS hardware must not, on average,
+     *     run power hungry operations like RF and signal searches for more than one second per
+     *     interval, and must make exactly one call to gnssSvStatusCb(), and either zero or one call
+     *     to GnssLocationCb() at each interval. When false, HAL must operate in the nominal mode
+     *     and is expected to make power and performance tradoffs such as duty-cycling when signal
+     *     conditions are good and more active searches to reacquire GNSS signals when no signals
+     *     are present. When there are additional clients using the GNSS hardware other than IGnss,
+     *     the GNSS hardware may operate in a higher power mode, on behalf of those clients.
+     */
+    void setPositionMode(in GnssPositionMode mode, in GnssPositionRecurrence recurrence,
+            in int minIntervalMs, in int preferredAccuracyMeters, in int preferredTimeMs,
+            in boolean lowPowerMode);
 }
diff --git a/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl b/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl
index aad09ef..157c912 100644
--- a/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl
+++ b/gnss/aidl/android/hardware/gnss/IGnssCallback.aidl
@@ -16,6 +16,8 @@
 
 package android.hardware.gnss;
 
+import android.hardware.gnss.GnssConstellationType;
+import android.hardware.gnss.GnssLocation;
 import android.hardware.gnss.IGnssConfiguration;
 import android.hardware.gnss.IGnssPsds;
 
@@ -26,9 +28,48 @@
  */
 @VintfStability
 interface IGnssCallback {
+    /**
+     * Capability bit mask indicating that GNSS supports scheduling fixes for RECURRENCE_PERIODIC
+     * mode.
+     *
+     * If this is not set, then the framework will use 1000ms for minInterval and will call start()
+     * and stop() to schedule the GNSS.
+     */
+    const int CAPABILITY_SCHEDULING = 1 << 0;
+
+    /** Capability bit mask indicating that GNSS supports MS-Based AGNSS mode */
+    const int CAPABILITY_MSB = 1 << 1;
+
+    /** Capability bit mask indicating that GNSS supports MS-Assisted AGNSS mode */
+    const int CAPABILITY_MSA = 1 << 2;
+
+    /** Capability bit mask indicating that GNSS supports single-shot fixes */
+    const int CAPABILITY_SINGLE_SHOT = 1 << 3;
+
+    /** Capability bit mask indicating that GNSS supports on demand time injection */
+    const int CAPABILITY_ON_DEMAND_TIME = 1 << 4;
+
+    /** Capability bit mask indicating that GNSS supports Geofencing  */
+    const int CAPABILITY_GEOFENCING = 1 << 5;
+
+    /** Capability bit mask indicating that GNSS supports Measurements. */
+    const int CAPABILITY_MEASUREMENTS = 1 << 6;
+
+    /** Capability bit mask indicating that GNSS supports Navigation Messages */
+    const int CAPABILITY_NAV_MESSAGES = 1 << 7;
+
+    /** Capability bit mask indicating that GNSS supports low power mode */
+    const int CAPABILITY_LOW_POWER_MODE = 1 << 8;
+
     /** Capability bit mask indicating that GNSS supports blocklisting satellites */
     const int CAPABILITY_SATELLITE_BLOCKLIST = 1 << 9;
 
+    /** Capability bit mask indicating that GNSS supports measurement corrections */
+    const int CAPABILITY_MEASUREMENT_CORRECTIONS = 1 << 10;
+
+    /** Capability bit mask indicating that GNSS supports measurement corrections */
+    const int CAPABILITY_ANTENNA_INFO = 1 << 11;
+
     /** Capability bit mask indicating that GNSS supports correlation vector */
     const int CAPABILITY_CORRELATION_VECTOR = 1 << 12;
 
@@ -44,4 +85,221 @@
      * @param capabilities Capability parameter is a bit field of the Capability bit masks.
      */
     void gnssSetCapabilitiesCb(in int capabilities);
+
+    /** GNSS status event values. */
+    @VintfStability
+    @Backing(type="int")
+    enum GnssStatusValue {
+        /** GNSS status unknown. */
+        NONE = 0,
+        /** GNSS has begun navigating. */
+        SESSION_BEGIN = 1,
+        /** GNSS has stopped navigating. */
+        SESSION_END = 2,
+        /** GNSS has powered on but is not navigating. */
+        ENGINE_ON = 3,
+        /** GNSS is powered off. */
+        ENGINE_OFF = 4
+    }
+
+    /**
+     * Flags that indicate information about the satellite
+     */
+    @VintfStability
+    @Backing(type="int")
+    enum GnssSvFlags {
+        NONE = 0,
+        HAS_EPHEMERIS_DATA = 1 << 0,
+        HAS_ALMANAC_DATA = 1 << 1,
+        USED_IN_FIX = 1 << 2,
+        HAS_CARRIER_FREQUENCY = 1 << 3,
+    }
+
+    @VintfStability
+    parcelable GnssSvInfo {
+        /**
+         * Pseudo-random or satellite ID number for the satellite, a.k.a. Space Vehicle (SV), or
+         * FCN/OSN number for Glonass. The distinction is made by looking at constellation field.
+         * Values must be in the range of:
+         *
+         * - GNSS:    1-32
+         * - SBAS:    120-151, 183-192
+         * - GLONASS: 1-24, the orbital slot number (OSN), if known.  Or, if not:
+         *            93-106, the frequency channel number (FCN) (-7 to +6) offset by
+         *            + 100
+         *            i.e. report an FCN of -7 as 93, FCN of 0 as 100, and FCN of +6
+         *            as 106.
+         * - QZSS:    193-200
+         * - Galileo: 1-36
+         * - Beidou:  1-37
+         * - IRNSS:   1-14
+         */
+        int svid;
+
+        /**
+         * Defines the constellation of the given SV.
+         */
+        GnssConstellationType constellation;
+
+        /**
+         * Carrier-to-noise density in dB-Hz, typically in the range [0, 63].
+         * It contains the measured C/N0 value for the signal at the antenna port.
+         *
+         * This is a mandatory field.
+         */
+        float cN0Dbhz;
+
+        /**
+         * Baseband Carrier-to-noise density in dB-Hz, typically in the range [0, 63]. It contains
+         * the measured C/N0 value for the signal measured at the baseband.
+         *
+         * This is typically a few dB weaker than the value estimated for C/N0 at the antenna port,
+         * which is reported in cN0DbHz.
+         *
+         * If a signal has separate components (e.g. Pilot and Data channels) and the receiver only
+         * processes one of the components, then the reported basebandCN0DbHz reflects only the
+         * component that is processed.
+         *
+         * This field is mandatory. Like cN0DbHz, it may be reported as 0 for satellites being
+         * reported that may be searched for, but not yet tracked.
+         */
+        float basebandCN0DbHz;
+
+        /** Elevation of SV in degrees. */
+        float elevationDegrees;
+
+        /** Azimuth of SV in degrees. */
+        float azimuthDegrees;
+
+        /**
+         * Carrier frequency of the signal tracked, for example it can be the
+         * GPS central frequency for L1 = 1575.45 MHz, or L2 = 1227.60 MHz, L5 =
+         * 1176.45 MHz, varying GLO channels, etc. If the field is zero, it is
+         * the primary common use central frequency, e.g. L1 = 1575.45 MHz for
+         * GPS.
+         *
+         * For an L1, L5 receiver tracking a satellite on L1 and L5 at the same
+         * time, two GnssSvInfo structs must be reported for this same
+         * satellite, in one of the structs, all the values related
+         * to L1 must be filled, and in the other all of the values related to
+         * L5 must be filled.
+         *
+         * If the data is available, svFlag must contain HAS_CARRIER_FREQUENCY.
+         */
+        long carrierFrequencyHz;
+
+        /** A bit field of the GnssSvFlags. */
+        int svFlag;
+    }
+
+    /**
+     * Called to communicate the status of the GNSS engine.
+     *
+     * @param status Status information from HAL.
+     */
+    void gnssStatusCb(in GnssStatusValue status);
+
+    /**
+     * Callback for the HAL to pass a vector of GnssSvInfo back to the client.
+     *
+     * @param svInfo SV status information from HAL.
+     */
+    void gnssSvStatusCb(in GnssSvInfo[] svInfoList);
+
+    /**
+     * Called when a GNSS location is available.
+     *
+     * @param location Location information from HAL.
+     */
+    void gnssLocationCb(in GnssLocation location);
+
+    /**
+     * Callback for reporting NMEA sentences. Called when NMEA data is available.
+     *
+     * @param timestamp Marks the instance of reporting.
+     * @param nmea Follows standard NMEA 0183. Each sentence begins with a '$'
+     * and ends with a carriage return/line feed sequence and can be no longer
+     * than 80 characters of visible text (plus the line terminators). The data
+     * is contained within this single line with data items separated by commas.
+     * The data itself is just ascii text and may extend over multiple sentences
+     * in certain specialized instances but is normally fully contained in one
+     * variable length sentence. The data may vary in the amount of precision
+     * contained in the message. For example time might be indicated to decimal
+     * parts of a second or location may be shown with 3 or even 4 digits after
+     * the decimal point. Programs that read the data must only use the commas
+     * to determine the field boundaries and not depend on column positions.
+     * There is a provision for a checksum at the end of each sentence which may
+     * or may not be checked by the unit that reads the data. The checksum field
+     * consists of a '*' and two hex digits representing an 8 bit exclusive OR
+     * of all characters between, but not including, the '$' and '*'.
+     */
+    void gnssNmeaCb(in long timestamp, in @utf8InCpp String nmea);
+
+    /**
+     * Callback utility for acquiring the GNSS wakelock. This can be used to prevent
+     * the CPU from suspending while handling GNSS events.
+     */
+    void gnssAcquireWakelockCb();
+
+    /** Callback utility for releasing the GNSS wakelock. */
+    void gnssReleaseWakelockCb();
+
+    /**
+     * Provides information about how new the underlying GPS/GNSS hardware and software is.
+     */
+    @VintfStability
+    parcelable GnssSystemInfo {
+        /**
+         * The year in which the last update was made to the underlying hardware/firmware used to
+         * capture GNSS signals, e.g. 2016.
+         */
+        int yearOfHw;
+
+        /**
+         * The name of the GNSS HAL implementation model and version name.
+         *
+         * This is a user-visible string that identifies the model and version of the GNSS HAL.
+         * For example "ABC Co., Baseband Part 1234, RF Part 567, Software version 3.14.159"
+         *
+         * For privacy reasons, this string must not contain any device-specific serial number or
+         * other identifier that uniquely identifies an individual device.
+         */
+        @utf8InCpp String name;
+    }
+
+    /**
+     * Callback to inform the framework of the GNSS system information.
+     *
+     * This must be called in response to IGnss::setCallback
+     *
+     * @param info GnssSystemInfo about the GPS/GNSS hardware.
+     */
+    void gnssSetSystemInfoCb(in GnssSystemInfo info);
+
+    /** Callback for requesting NTP time */
+    void gnssRequestTimeCb();
+
+    /**
+     * Callback for requesting Location.
+     *
+     * HAL implementation must call this when it wants the framework to provide locations to assist
+     * with GNSS HAL operation, for example, to assist with time to first fix, error recovery, or to
+     * supplement GNSS location for other clients of the GNSS HAL.
+     *
+     * If a request is made with independentFromGnss set to true, the framework must avoid
+     * providing locations derived from GNSS locations (such as "fused" location), to help improve
+     * information independence for situations such as error recovery.
+     *
+     * In response to this method call, GNSS HAL can expect zero, one, or more calls to
+     * IGnss::injectLocation or IGnss::injectBestLocation, dependent on availability of location
+     * from other sources, which may happen at some arbitrary delay. Generally speaking, HAL
+     * implementations must be able to handle calls to IGnss::injectLocation or
+     * IGnss::injectBestLocation at any time.
+     *
+     * @param independentFromGnss True if requesting a location that is independent from GNSS.
+     * @param isUserEmergency True if the location request is for delivery of this location to an
+     *        emergency services endpoint, during a user-initiated emergency session (e.g.
+     *        during-call to E911, or up to 5 minutes after end-of-call or text to E911).
+     */
+    void gnssRequestLocationCb(in boolean independentFromGnss, in boolean isUserEmergency);
 }
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/android/hardware/gnss/IGnssMeasurementInterface.aidl b/gnss/aidl/android/hardware/gnss/IGnssMeasurementInterface.aidl
index 08c83a4..102cdcd 100644
--- a/gnss/aidl/android/hardware/gnss/IGnssMeasurementInterface.aidl
+++ b/gnss/aidl/android/hardware/gnss/IGnssMeasurementInterface.aidl
@@ -24,6 +24,48 @@
 @VintfStability
 interface IGnssMeasurementInterface {
     /**
+     * Options specifying the GnssMeasurement request.
+     */
+    @VintfStability
+    parcelable Options {
+        /**
+         * Enable full tracking mode.
+         *
+         * If true, GNSS chipset must switch off duty cycling. In such mode no clock discontinuities
+         * are expected and, when supported, carrier phase should be continuous in good signal
+         * conditions. All non-blocklisted, healthy constellations, satellites and frequency bands
+         * that the chipset supports must be reported in this mode. The GNSS chipset is allowed to
+         * consume more power in this mode. If false, API must optimize power via duty cycling,
+         * constellations and frequency limits, etc.
+         */
+        boolean enableFullTracking;
+
+        /**
+         * Enable Correlation Vector outputs.
+         *
+         * If true, enable correlation vectors as part of the raw GNSS measurements outputs. If
+         * false, disable correlation vectors.
+         */
+        boolean enableCorrVecOutputs;
+
+        /**
+         * Time interval between the reported measurements in milliseconds.
+         *
+         * The GNSS chipset must not report measurements with a rate slower than requested. All the
+         * available measurements must be reported to the framework.
+         *
+         * For cases where concurrently serving the location and the measurement requests would not
+         * consume more power than only the measurement request, the faster rate of the 2 requests
+         * must be chosen. Otherwise, it is recommended that the GNSS chipset minimizes the power
+         * consumption with appropriate location and measurement intervals to satisfy both requests.
+         * For example, for 2-sec measurement interval request and 7-sec location interval request,
+         * the GNSS chipset is recommended to run the measurement engine with 2-sec interval and the
+         * location engine with 6-sec interval.
+         */
+        int intervalMs;
+    }
+
+    /**
      * Initializes the interface and registers the callback routines with the HAL. After a
      * successful call to 'setCallback' the HAL must begin to provide updates at an average
      * output rate of 1Hz (occasional intra-measurement time offsets in the range from 0-2000msec
@@ -39,13 +81,9 @@
      *
      * @param enableCorrVecOutputs If true, enable correlation vectors as part of the raw GNSS
      *     measurements outputs. If false, disable correlation vectors.
-     *
-     * Returns ok() if successful. Returns ERROR_ALREADY_INIT if a callback has already been
-     * registered without a corresponding call to 'close'. Returns ERROR_GENERIC for any other
-     * error. The HAL must not generate any other updates upon returning this error code.
      */
     void setCallback(in IGnssMeasurementCallback callback, in boolean enableFullTracking,
-                     in boolean enableCorrVecOutputs);
+            in boolean enableCorrVecOutputs);
 
     /**
      * Stops updates from the HAL, and unregisters the callback routines. After a call to close(),
@@ -55,4 +93,11 @@
      * no work.
      */
     void close();
-}
\ No newline at end of file
+
+    /**
+     * Initializes the interface and registers the callback routines with the HAL.
+     *
+     * @param options See Options definition.
+     */
+    void setCallbackWithOptions(in IGnssMeasurementCallback callback, in Options options);
+}
diff --git a/gnss/aidl/android/hardware/gnss/visibility_control/IGnssVisibilityControl.aidl b/gnss/aidl/android/hardware/gnss/visibility_control/IGnssVisibilityControl.aidl
new file mode 100644
index 0000000..93c3f2c
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/visibility_control/IGnssVisibilityControl.aidl
@@ -0,0 +1,82 @@
+/*
+ * 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.visibility_control;
+
+import android.hardware.gnss.visibility_control.IGnssVisibilityControlCallback;
+
+/**
+ * Represents the GNSS location reporting permissions and notification interface.
+ *
+ * This interface is used to tell the GNSS HAL implementation whether the framework user has
+ * granted permission to the GNSS HAL implementation to provide GNSS location information for
+ * non-framework (NFW), non-user initiated emergency use cases, and to notify the framework user
+ * of these GNSS location information deliveries.
+ *
+ * For user initiated emergency cases (and for the configured extended emergency session duration),
+ * the GNSS HAL implementation must serve the emergency location supporting network initiated
+ * location requests immediately irrespective of this permission settings.
+ *
+ * There is no separate need for the GNSS HAL implementation to monitor the global device location
+ * on/off setting. Permission to use GNSS for non-framework use cases is expressly controlled
+ * by the method enableNfwLocationAccess(). The framework monitors the location permission settings
+ * of the configured proxy applications(s), and device location settings, and calls the method
+ * enableNfwLocationAccess() whenever the user control proxy applications have, or do not have,
+ * location permission. The proxy applications are used to provide user visibility and control of
+ * location access by the non-framework on/off device entities they are representing.
+ *
+ * For device user visibility, the GNSS HAL implementation must call the method
+ * IGnssVisibilityControlCallback.nfwNotifyCb() whenever location request is rejected or
+ * location information is provided to non-framework entities (on or off device). This includes
+ * the network initiated location requests for user-initiated emergency use cases as well.
+ *
+ * The HAL implementations that support this interface must not report GNSS location, measurement,
+ * status, or other information that can be used to derive user location to any entity when not
+ * expressly authorized by this HAL. This includes all endpoints for location information
+ * off the device, including carriers, vendors, OEM and others directly or indirectly.
+ */
+@VintfStability
+interface IGnssVisibilityControl {
+    /**
+     * Enables/disables non-framework entity location access permission in the GNSS HAL.
+     *
+     * The framework will call this method to update GNSS HAL implementation every time the
+     * framework user, through the given proxy application(s) and/or device location settings,
+     * explicitly grants/revokes the location access permission for non-framework, non-user
+     * initiated emergency use cases.
+     *
+     * Whenever the user location information is delivered to non-framework entities, the HAL
+     * implementation must call the method IGnssVisibilityControlCallback.nfwNotifyCb() to notify
+     * the framework for user visibility.
+     *
+     * @param proxyApps Full list of package names of proxy Android applications representing
+     * the non-framework location access entities (on/off the device) for which the framework
+     * user has granted non-framework location access permission. The GNSS HAL implementation
+     * must provide location information only to non-framework entities represented by these
+     * proxy applications.
+     *
+     * The package name of the proxy Android application follows the standard Java language
+     * package naming format. For example, com.example.myapp.
+     */
+    void enableNfwLocationAccess(in String[] proxyApps);
+
+    /**
+     * Registers the callback for HAL implementation to use.
+     *
+     * @param callback Handle to IGnssVisibilityControlCallback interface.
+     */
+    void setCallback(in IGnssVisibilityControlCallback callback);
+}
diff --git a/gnss/aidl/android/hardware/gnss/visibility_control/IGnssVisibilityControlCallback.aidl b/gnss/aidl/android/hardware/gnss/visibility_control/IGnssVisibilityControlCallback.aidl
new file mode 100644
index 0000000..051fbe6
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/visibility_control/IGnssVisibilityControlCallback.aidl
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.gnss.visibility_control;
+
+/**
+ * GNSS location reporting permissions and notification callback interface.
+ */
+@VintfStability
+interface IGnssVisibilityControlCallback {
+    /**
+     * Protocol stack that is requesting the non-framework location information.
+     */
+    @VintfStability
+    @Backing(type="int")
+    enum NfwProtocolStack {
+        /** Cellular control plane requests */
+        CTRL_PLANE = 0,
+
+        /** All types of SUPL requests */
+        SUPL = 1,
+
+        /** All types of requests from IMS */
+        IMS = 10,
+
+        /** All types of requests from SIM */
+        SIM = 11,
+
+        /** Requests from other protocol stacks */
+        OTHER_PROTOCOL_STACK = 100
+    }
+
+    /**
+     * Entity that is requesting/receiving the location information.
+     */
+    @VintfStability
+    @Backing(type="int")
+    enum NfwRequestor {
+        /** Wireless service provider */
+        CARRIER = 0,
+
+        /** Device manufacturer */
+        OEM = 10,
+
+        /** Modem chipset vendor */
+        MODEM_CHIPSET_VENDOR = 11,
+
+        /** GNSS chipset vendor */
+        GNSS_CHIPSET_VENDOR = 12,
+
+        /** Other chipset vendor */
+        OTHER_CHIPSET_VENDOR = 13,
+
+        /** Automobile client */
+        AUTOMOBILE_CLIENT = 20,
+
+        /** Other sources */
+        OTHER_REQUESTOR = 100
+    }
+
+    /**
+     * GNSS response type for non-framework location requests.
+     */
+    @VintfStability
+    @Backing(type="int")
+    enum NfwResponseType {
+        /** Request rejected because framework has not given permission for this use case */
+        REJECTED = 0,
+
+        /** Request accepted but could not provide location because of a failure */
+        ACCEPTED_NO_LOCATION_PROVIDED = 1,
+
+        /** Request accepted and location provided */
+        ACCEPTED_LOCATION_PROVIDED = 2,
+    }
+
+    /**
+     * Represents a non-framework location information request/response notification.
+     */
+    @VintfStability
+    parcelable NfwNotification {
+        /**
+         * Package name of the Android proxy application representing the non-framework
+         * entity that requested location. Set to empty string if unknown.
+         *
+         * For user-initiated emergency use cases, this field must be set to empty string
+         * and the inEmergencyMode field must be set to true.
+         */
+        String proxyAppPackageName;
+
+        /** Protocol stack that initiated the non-framework location request. */
+        NfwProtocolStack protocolStack;
+
+        /**
+         * Name of the protocol stack if protocolStack field is set to OTHER_PROTOCOL_STACK.
+         * Otherwise, set to empty string.
+         *
+         * This field is opaque to the framework and used for logging purposes.
+         */
+        String otherProtocolStackName;
+
+        /** Source initiating/receiving the location information. */
+        NfwRequestor requestor;
+
+        /**
+         * Identity of the endpoint receiving the location information. For example, carrier
+         * name, OEM name, SUPL SLP/E-SLP FQDN, chipset vendor name, etc.
+         *
+         * This field is opaque to the framework and used for logging purposes.
+         */
+        String requestorId;
+
+        /** Indicates whether location information was provided for this request. */
+        NfwResponseType responseType;
+
+        /** Is the device in user initiated emergency session. */
+        boolean inEmergencyMode;
+
+        /** Is cached location provided */
+        boolean isCachedLocation;
+    }
+
+    /**
+     * Callback to report a non-framework delivered location.
+     *
+     * The GNSS HAL implementation must call this method to notify the framework whenever
+     * a non-framework location request is made to the GNSS HAL.
+     *
+     * Non-framework entities like low power sensor hubs that request location from GNSS and
+     * only pass location information through Android framework controls are exempt from this
+     * power-spending reporting. However, low power sensor hubs or other chipsets which may send
+     * the location information to anywhere other than Android framework (which provides user
+     * visibility and control), must report location information use through this API whenever
+     * location information (or events driven by that location such as "home" location detection)
+     * leaves the domain of that low power chipset.
+     *
+     * To avoid overly spamming the framework, high speed location reporting of the exact same
+     * type may be throttled to report location at a lower rate than the actual report rate, as
+     * long as the location is reported with a latency of no more than the larger of 5 seconds,
+     * or the next the Android processor awake time. For example, if an Automotive client is
+     * getting location information from the GNSS location system at 20Hz, this method may be
+     * called at 1Hz. As another example, if a low power processor is getting location from the
+     * GNSS chipset, and the Android processor is asleep, the notification to the Android HAL may
+     * be delayed until the next wake of the Android processor.
+     *
+     * @param notification Non-framework delivered location request/response description.
+     */
+    void nfwNotifyCb(in NfwNotification notification);
+
+    /**
+     * Tells if the device is currently in an emergency session.
+     *
+     * Emergency session is defined as the device being actively in a user initiated emergency
+     * call or in post emergency call extension time period.
+     *
+     * If the GNSS HAL implementation cannot determine if the device is in emergency session
+     * mode, it must call this method to confirm that the device is in emergency session before
+     * serving network initiated emergency SUPL and Control Plane location requests.
+     *
+     * @return success True if the framework determines that the device is in emergency session.
+     */
+    boolean isInEmergencySession();
+}
diff --git a/gnss/aidl/default/Android.bp b/gnss/aidl/default/Android.bp
index 1236714..29c26d1 100644
--- a/gnss/aidl/default/Android.bp
+++ b/gnss/aidl/default/Android.bp
@@ -52,12 +52,14 @@
         "android.hardware.gnss.measurement_corrections@1.1",
         "android.hardware.gnss.measurement_corrections@1.0",
         "android.hardware.gnss.visibility_control@1.0",
+        "android.hardware.gnss.visibility_control-V1-ndk",
         "android.hardware.gnss-V2-ndk",
     ],
     srcs: [
         "AGnss.cpp",
         "Gnss.cpp",
         "GnssBatching.cpp",
+        "GnssDebug.cpp",
         "GnssGeofence.cpp",
         "GnssHidlHal.cpp",
         "GnssNavigationMessageInterface.cpp",
@@ -65,6 +67,7 @@
         "GnssPsds.cpp",
         "GnssConfiguration.cpp",
         "GnssMeasurementInterface.cpp",
+        "GnssVisibilityControl.cpp",
         "service.cpp",
     ],
     static_libs: [
diff --git a/gnss/aidl/default/Gnss.cpp b/gnss/aidl/default/Gnss.cpp
index 0e3cdd3..e296351 100644
--- a/gnss/aidl/default/Gnss.cpp
+++ b/gnss/aidl/default/Gnss.cpp
@@ -17,24 +17,35 @@
 #define LOG_TAG "GnssAidl"
 
 #include "Gnss.h"
+#include <inttypes.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"
 #include "GnssPsds.h"
+#include "GnssVisibilityControl.h"
+#include "Utils.h"
 
 namespace aidl::android::hardware::gnss {
+using ::android::hardware::gnss::common::Utils;
+using ndk::ScopedAStatus;
+using GnssSvInfo = IGnssCallback::GnssSvInfo;
+
+constexpr int TTFF_MILLIS = 2200;
 
 std::shared_ptr<IGnssCallback> Gnss::sGnssCallback = nullptr;
 
-ndk::ScopedAStatus Gnss::setCallback(const std::shared_ptr<IGnssCallback>& callback) {
-    ALOGD("Gnss::setCallback");
+Gnss::Gnss() : mMinIntervalMs(1000), mFirstFixReceived(false) {}
+
+ScopedAStatus Gnss::setCallback(const std::shared_ptr<IGnssCallback>& callback) {
+    ALOGD("setCallback");
     if (callback == nullptr) {
         ALOGE("%s: Null callback ignored", __func__);
-        return ndk::ScopedAStatus::fromExceptionCode(STATUS_INVALID_OPERATION);
+        return ScopedAStatus::fromExceptionCode(STATUS_INVALID_OPERATION);
     }
 
     sGnssCallback = callback;
@@ -48,13 +59,99 @@
         ALOGE("%s: Unable to invoke callback.gnssSetCapabilities", __func__);
     }
 
-    return ndk::ScopedAStatus::ok();
+    return ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus Gnss::close() {
-    ALOGD("Gnss::close");
+ScopedAStatus Gnss::start() {
+    ALOGD("start()");
+    if (mIsActive) {
+        ALOGW("Gnss has started. Restarting...");
+        stop();
+    }
+
+    mIsActive = true;
+    this->reportGnssStatusValue(IGnssCallback::GnssStatusValue::SESSION_BEGIN);
+    mThread = std::thread([this]() {
+        auto svStatus = filterBlocklistedSatellites(Utils::getMockSvInfoList());
+        this->reportSvStatus(svStatus);
+        if (!mFirstFixReceived) {
+            std::this_thread::sleep_for(std::chrono::milliseconds(TTFF_MILLIS));
+            mFirstFixReceived = true;
+        }
+        while (mIsActive == true) {
+            auto svStatus = filterBlocklistedSatellites(Utils::getMockSvInfoList());
+            this->reportSvStatus(svStatus);
+
+            mGnssPowerIndication->notePowerConsumption();
+            const auto location = Utils::getMockLocation();
+            this->reportLocation(location);
+            std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMs));
+        }
+    });
+    return ScopedAStatus::ok();
+}
+
+void Gnss::reportLocation(const GnssLocation& location) const {
+    std::unique_lock<std::mutex> lock(mMutex);
+    if (sGnssCallback == nullptr) {
+        ALOGE("%s: GnssCallback is null.", __func__);
+        return;
+    }
+    auto status = sGnssCallback->gnssLocationCb(location);
+    if (!status.isOk()) {
+        ALOGE("%s: Unable to invoke gnssLocationCb", __func__);
+    }
+    return;
+}
+
+void Gnss::reportSvStatus(const std::vector<GnssSvInfo>& svInfoList) const {
+    std::unique_lock<std::mutex> lock(mMutex);
+    if (sGnssCallback == nullptr) {
+        ALOGE("%s: sGnssCallback is null.", __func__);
+        return;
+    }
+    auto status = sGnssCallback->gnssSvStatusCb(svInfoList);
+    if (!status.isOk()) {
+        ALOGE("%s: Unable to invoke callback", __func__);
+    }
+}
+
+std::vector<GnssSvInfo> Gnss::filterBlocklistedSatellites(std::vector<GnssSvInfo> gnssSvInfoList) {
+    ALOGD("filterBlocklistedSatellites");
+    for (uint32_t i = 0; i < gnssSvInfoList.size(); i++) {
+        if (mGnssConfiguration->isBlocklisted(gnssSvInfoList[i])) {
+            gnssSvInfoList[i].svFlag &= ~(uint32_t)IGnssCallback::GnssSvFlags::USED_IN_FIX;
+        }
+    }
+    return gnssSvInfoList;
+}
+
+void Gnss::reportGnssStatusValue(const IGnssCallback::GnssStatusValue gnssStatusValue) const {
+    std::unique_lock<std::mutex> lock(mMutex);
+    if (sGnssCallback == nullptr) {
+        ALOGE("%s: sGnssCallback is null.", __func__);
+        return;
+    }
+    auto status = sGnssCallback->gnssStatusCb(gnssStatusValue);
+    if (!status.isOk()) {
+        ALOGE("%s: Unable to invoke gnssStatusCb", __func__);
+    }
+}
+
+ScopedAStatus Gnss::stop() {
+    ALOGD("stop");
+    mIsActive = false;
+    this->reportGnssStatusValue(IGnssCallback::GnssStatusValue::SESSION_END);
+    if (mThread.joinable()) {
+        mThread.join();
+    }
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus Gnss::close() {
+    ALOGD("close");
     sGnssCallback = nullptr;
-    return ndk::ScopedAStatus::ok();
+    return ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus Gnss::getExtensionAGnss(std::shared_ptr<IAGnss>* iAGnss) {
@@ -63,60 +160,107 @@
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus Gnss::getExtensionPsds(std::shared_ptr<IGnssPsds>* iGnssPsds) {
-    ALOGD("Gnss::getExtensionPsds");
-    *iGnssPsds = SharedRefBase::make<GnssPsds>();
-    return ndk::ScopedAStatus::ok();
+ScopedAStatus Gnss::injectTime(int64_t timeMs, int64_t timeReferenceMs, int uncertaintyMs) {
+    ALOGD("injectTime. timeMs:%" PRId64 ", timeReferenceMs:%" PRId64 ", uncertaintyMs:%d", timeMs,
+          timeReferenceMs, uncertaintyMs);
+    return ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus Gnss::getExtensionGnssConfiguration(
+ScopedAStatus Gnss::injectLocation(const GnssLocation& location) {
+    ALOGD("injectLocation. lat:%lf, lng:%lf, acc:%f", location.latitudeDegrees,
+          location.longitudeDegrees, location.horizontalAccuracyMeters);
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus Gnss::injectBestLocation(const GnssLocation& location) {
+    ALOGD("injectBestLocation. lat:%lf, lng:%lf, acc:%f", location.latitudeDegrees,
+          location.longitudeDegrees, location.horizontalAccuracyMeters);
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus Gnss::deleteAidingData(GnssAidingData aidingDataFlags) {
+    ALOGD("deleteAidingData. flags:%d", (int)aidingDataFlags);
+    mFirstFixReceived = false;
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus Gnss::setPositionMode(GnssPositionMode, GnssPositionRecurrence, int minIntervalMs,
+                                    int /* preferredAccuracyMeters */, int /* preferredTimeMs */,
+                                    bool lowPowerMode) {
+    ALOGD("setPositionMode. minIntervalMs:%d, lowPowerMode:%d", minIntervalMs, (int)lowPowerMode);
+    mMinIntervalMs = minIntervalMs;
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus Gnss::getExtensionPsds(std::shared_ptr<IGnssPsds>* iGnssPsds) {
+    ALOGD("getExtensionPsds");
+    *iGnssPsds = SharedRefBase::make<GnssPsds>();
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus Gnss::getExtensionGnssConfiguration(
         std::shared_ptr<IGnssConfiguration>* iGnssConfiguration) {
-    ALOGD("Gnss::getExtensionGnssConfiguration");
+    ALOGD("getExtensionGnssConfiguration");
     if (mGnssConfiguration == nullptr) {
         mGnssConfiguration = SharedRefBase::make<GnssConfiguration>();
     }
     *iGnssConfiguration = mGnssConfiguration;
-    return ndk::ScopedAStatus::ok();
+    return ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus Gnss::getExtensionGnssPowerIndication(
+ScopedAStatus Gnss::getExtensionGnssPowerIndication(
         std::shared_ptr<IGnssPowerIndication>* iGnssPowerIndication) {
-    ALOGD("Gnss::getExtensionGnssPowerIndication");
+    ALOGD("getExtensionGnssPowerIndication");
     if (mGnssPowerIndication == nullptr) {
         mGnssPowerIndication = SharedRefBase::make<GnssPowerIndication>();
     }
 
     *iGnssPowerIndication = mGnssPowerIndication;
-    return ndk::ScopedAStatus::ok();
+    return ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus Gnss::getExtensionGnssMeasurement(
+ScopedAStatus Gnss::getExtensionGnssMeasurement(
         std::shared_ptr<IGnssMeasurementInterface>* iGnssMeasurement) {
-    ALOGD("Gnss::getExtensionGnssMeasurement");
+    ALOGD("getExtensionGnssMeasurement");
 
     *iGnssMeasurement = SharedRefBase::make<GnssMeasurementInterface>();
-    return ndk::ScopedAStatus::ok();
+    return ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus Gnss::getExtensionGnssBatching(std::shared_ptr<IGnssBatching>* iGnssBatching) {
-    ALOGD("Gnss::getExtensionGnssBatching");
+ScopedAStatus Gnss::getExtensionGnssBatching(std::shared_ptr<IGnssBatching>* iGnssBatching) {
+    ALOGD("getExtensionGnssBatching");
 
     *iGnssBatching = SharedRefBase::make<GnssBatching>();
-    return ndk::ScopedAStatus::ok();
+    return ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus Gnss::getExtensionGnssGeofence(std::shared_ptr<IGnssGeofence>* iGnssGeofence) {
-    ALOGD("Gnss::getExtensionGnssGeofence");
+ScopedAStatus Gnss::getExtensionGnssGeofence(std::shared_ptr<IGnssGeofence>* iGnssGeofence) {
+    ALOGD("getExtensionGnssGeofence");
 
     *iGnssGeofence = SharedRefBase::make<GnssGeofence>();
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus Gnss::getExtensionGnssNavigationMessage(
+        std::shared_ptr<IGnssNavigationMessageInterface>* iGnssNavigationMessage) {
+    ALOGD("getExtensionGnssNavigationMessage");
+
+    *iGnssNavigationMessage = SharedRefBase::make<GnssNavigationMessageInterface>();
+    return ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Gnss::getExtensionGnssDebug(std::shared_ptr<IGnssDebug>* iGnssDebug) {
+    ALOGD("Gnss::getExtensionGnssDebug");
+
+    *iGnssDebug = SharedRefBase::make<GnssDebug>();
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus Gnss::getExtensionGnssNavigationMessage(
-        std::shared_ptr<IGnssNavigationMessageInterface>* iGnssNavigationMessage) {
-    ALOGD("Gnss::getExtensionGnssNavigationMessage");
+ndk::ScopedAStatus Gnss::getExtensionGnssVisibilityControl(
+        std::shared_ptr<visibility_control::IGnssVisibilityControl>* iGnssVisibilityControl) {
+    ALOGD("Gnss::getExtensionGnssVisibilityControl");
 
-    *iGnssNavigationMessage = SharedRefBase::make<GnssNavigationMessageInterface>();
+    *iGnssVisibilityControl = SharedRefBase::make<visibility_control::GnssVisibilityControl>();
     return ndk::ScopedAStatus::ok();
 }
 
diff --git a/gnss/aidl/default/Gnss.h b/gnss/aidl/default/Gnss.h
index 4feb781..384c862 100644
--- a/gnss/aidl/default/Gnss.h
+++ b/gnss/aidl/default/Gnss.h
@@ -20,9 +20,14 @@
 #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>
+#include <aidl/android/hardware/gnss/visibility_control/BnGnssVisibilityControl.h>
+#include <atomic>
+#include <mutex>
+#include <thread>
 #include "GnssConfiguration.h"
 #include "GnssPowerIndication.h"
 
@@ -30,8 +35,22 @@
 
 class Gnss : public BnGnss {
   public:
+    Gnss();
+    ~Gnss() { stop(); };
     ndk::ScopedAStatus setCallback(const std::shared_ptr<IGnssCallback>& callback) override;
+    ndk::ScopedAStatus start() override;
+    ndk::ScopedAStatus stop() override;
     ndk::ScopedAStatus close() override;
+
+    ndk::ScopedAStatus injectTime(int64_t timeMs, int64_t timeReferenceMs,
+                                  int uncertaintyMs) override;
+    ndk::ScopedAStatus injectLocation(const GnssLocation& location) override;
+    ndk::ScopedAStatus injectBestLocation(const GnssLocation& location) override;
+    ndk::ScopedAStatus deleteAidingData(GnssAidingData aidingDataFlags) override;
+    ndk::ScopedAStatus setPositionMode(GnssPositionMode mode, GnssPositionRecurrence recurrence,
+                                       int minIntervalMs, int preferredAccuracyMeters,
+                                       int preferredTimeMs, bool lowPowerMode) override;
+
     ndk::ScopedAStatus getExtensionPsds(std::shared_ptr<IGnssPsds>* iGnssPsds) override;
     ndk::ScopedAStatus getExtensionGnssConfiguration(
             std::shared_ptr<IGnssConfiguration>* iGnssConfiguration) override;
@@ -46,12 +65,29 @@
     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;
+    ndk::ScopedAStatus getExtensionGnssVisibilityControl(
+            std::shared_ptr<android::hardware::gnss::visibility_control::IGnssVisibilityControl>*
+                    iGnssVisibilityControl) override;
 
     std::shared_ptr<GnssConfiguration> mGnssConfiguration;
     std::shared_ptr<GnssPowerIndication> mGnssPowerIndication;
 
   private:
+    void reportLocation(const GnssLocation&) const;
+    void reportSvStatus(const std::vector<IGnssCallback::GnssSvInfo>& svInfoList) const;
+    std::vector<IGnssCallback::GnssSvInfo> filterBlocklistedSatellites(
+            std::vector<IGnssCallback::GnssSvInfo> gnssSvInfoList);
+    void reportGnssStatusValue(const IGnssCallback::GnssStatusValue gnssStatusValue) const;
+
     static std::shared_ptr<IGnssCallback> sGnssCallback;
+
+    std::atomic<long> mMinIntervalMs;
+    std::atomic<bool> mIsActive;
+    std::atomic<bool> mFirstFixReceived;
+    std::thread mThread;
+
+    mutable std::mutex mMutex;
 };
 
 }  // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/GnssConfiguration.cpp b/gnss/aidl/default/GnssConfiguration.cpp
index 30e0d8c..96a1aa2 100644
--- a/gnss/aidl/default/GnssConfiguration.cpp
+++ b/gnss/aidl/default/GnssConfiguration.cpp
@@ -49,4 +49,14 @@
     return (mBlocklistedSourceSet.find(source) != mBlocklistedSourceSet.end());
 }
 
+bool GnssConfiguration::isBlocklisted(const IGnssCallback::GnssSvInfo& gnssSvInfo) const {
+    std::unique_lock<std::recursive_mutex> lock(mMutex);
+    if (mBlocklistedConstellationSet.find(gnssSvInfo.constellation) !=
+        mBlocklistedConstellationSet.end()) {
+        return true;
+    }
+    BlocklistedSource source = {.constellation = gnssSvInfo.constellation, .svid = gnssSvInfo.svid};
+    return (mBlocklistedSourceSet.find(source) != mBlocklistedSourceSet.end());
+}
+
 }  // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/GnssConfiguration.h b/gnss/aidl/default/GnssConfiguration.h
index 491733c..3c77f32 100644
--- a/gnss/aidl/default/GnssConfiguration.h
+++ b/gnss/aidl/default/GnssConfiguration.h
@@ -16,6 +16,7 @@
 
 #pragma once
 
+#include <aidl/android/hardware/gnss/BnGnssCallback.h>
 #include <aidl/android/hardware/gnss/BnGnssConfiguration.h>
 #include <android/hardware/gnss/2.1/IGnssCallback.h>
 #include <mutex>
@@ -62,6 +63,7 @@
     ndk::ScopedAStatus setBlocklist(const vector<BlocklistedSource>& blocklist) override;
 
     bool isBlocklistedV2_1(const GnssSvInfoV2_1& gnssSvInfo) const;
+    bool isBlocklisted(const IGnssCallback::GnssSvInfo& gnssSvInfo) const;
 
   private:
     BlocklistedSourceSet mBlocklistedSourceSet;
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/GnssMeasurementInterface.cpp b/gnss/aidl/default/GnssMeasurementInterface.cpp
index 9e4f7c7..2c7241b 100644
--- a/gnss/aidl/default/GnssMeasurementInterface.cpp
+++ b/gnss/aidl/default/GnssMeasurementInterface.cpp
@@ -56,11 +56,29 @@
     return ndk::ScopedAStatus::ok();
 }
 
+ndk::ScopedAStatus GnssMeasurementInterface::setCallbackWithOptions(
+        const std::shared_ptr<IGnssMeasurementCallback>& callback, const Options& options) {
+    ALOGD("setCallbackWithOptions: fullTracking:%d, corrVec:%d, intervalMs:%d",
+          (int)options.enableFullTracking, (int)options.enableCorrVecOutputs, options.intervalMs);
+    std::unique_lock<std::mutex> lock(mMutex);
+    sCallback = callback;
+
+    if (mIsActive) {
+        ALOGW("GnssMeasurement callback already set. Resetting the callback...");
+        stop();
+    }
+    mMinIntervalMillis = options.intervalMs;
+    start(options.enableCorrVecOutputs);
+
+    return ndk::ScopedAStatus::ok();
+}
+
 ndk::ScopedAStatus GnssMeasurementInterface::close() {
     ALOGD("close");
     stop();
     std::unique_lock<std::mutex> lock(mMutex);
     sCallback = nullptr;
+    mMinIntervalMillis = 1000;
     return ndk::ScopedAStatus::ok();
 }
 
diff --git a/gnss/aidl/default/GnssMeasurementInterface.h b/gnss/aidl/default/GnssMeasurementInterface.h
index db63515..bf77806 100644
--- a/gnss/aidl/default/GnssMeasurementInterface.h
+++ b/gnss/aidl/default/GnssMeasurementInterface.h
@@ -32,6 +32,9 @@
                                    const bool enableFullTracking,
                                    const bool enableCorrVecOutputs) override;
     ndk::ScopedAStatus close() override;
+    ndk::ScopedAStatus setCallbackWithOptions(
+            const std::shared_ptr<IGnssMeasurementCallback>& callback,
+            const Options& options) override;
 
   private:
     void start(const bool enableCorrVecOutputs);
diff --git a/gnss/aidl/default/GnssVisibilityControl.cpp b/gnss/aidl/default/GnssVisibilityControl.cpp
new file mode 100644
index 0000000..208d73c
--- /dev/null
+++ b/gnss/aidl/default/GnssVisibilityControl.cpp
@@ -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.
+ */
+
+#define LOG_TAG "GnssVisibilityControl"
+
+#include "GnssVisibilityControl.h"
+#include <log/log.h>
+
+namespace aidl::android::hardware::gnss::visibility_control {
+
+std::shared_ptr<IGnssVisibilityControlCallback> GnssVisibilityControl::sCallback = nullptr;
+
+ndk::ScopedAStatus GnssVisibilityControl::enableNfwLocationAccess(
+        const std::vector<std::string>& proxyApps) {
+    std::string os;
+    bool first = true;
+    for (const auto& proxyApp : proxyApps) {
+        if (first) {
+            first = false;
+        } else {
+            os += " ";
+        }
+        os += proxyApp;
+    }
+
+    ALOGD("GnssVisibilityControl::enableNfwLocationAccess proxyApps: %s", os.c_str());
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus GnssVisibilityControl::setCallback(
+        const std::shared_ptr<IGnssVisibilityControlCallback>& callback) {
+    ALOGD("GnssVisibilityControl::setCallback");
+    std::unique_lock<std::mutex> lock(mMutex);
+    sCallback = callback;
+    return ndk::ScopedAStatus::ok();
+}
+
+}  // namespace aidl::android::hardware::gnss::visibility_control
diff --git a/gnss/aidl/default/GnssVisibilityControl.h b/gnss/aidl/default/GnssVisibilityControl.h
new file mode 100644
index 0000000..5b36442
--- /dev/null
+++ b/gnss/aidl/default/GnssVisibilityControl.h
@@ -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.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/gnss/visibility_control/BnGnssVisibilityControl.h>
+
+namespace aidl::android::hardware::gnss::visibility_control {
+
+struct GnssVisibilityControl : public BnGnssVisibilityControl {
+  public:
+    ndk::ScopedAStatus enableNfwLocationAccess(const std::vector<std::string>& hostname) override;
+    ndk::ScopedAStatus setCallback(
+            const std::shared_ptr<IGnssVisibilityControlCallback>& callback) override;
+
+  private:
+    // Synchronization lock for sCallback
+    mutable std::mutex mMutex;
+    // Guarded by mMutex
+    static std::shared_ptr<IGnssVisibilityControlCallback> sCallback;
+};
+
+}  // namespace aidl::android::hardware::gnss::visibility_control
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/Android.bp b/gnss/aidl/vts/Android.bp
index 041d579..d532fad 100644
--- a/gnss/aidl/vts/Android.bp
+++ b/gnss/aidl/vts/Android.bp
@@ -37,6 +37,7 @@
         "GnssMeasurementCallbackAidl.cpp",
         "GnssNavigationMessageCallback.cpp",
         "GnssPowerIndicationCallback.cpp",
+        "GnssVisibilityControlCallback.cpp",
         "VtsHalGnssTargetTest.cpp",
     ],
     shared_libs: [
@@ -49,6 +50,7 @@
     static_libs: [
         "android.hardware.gnss-V2-cpp",
         "android.hardware.gnss@common-vts-lib",
+        "android.hardware.gnss.visibility_control-V1-cpp",
     ],
     test_suites: [
         "general-tests",
diff --git a/gnss/aidl/vts/GnssBatchingCallback.cpp b/gnss/aidl/vts/GnssBatchingCallback.cpp
index 2da3b12..d4eb0a5 100644
--- a/gnss/aidl/vts/GnssBatchingCallback.cpp
+++ b/gnss/aidl/vts/GnssBatchingCallback.cpp
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#define LOG_TAG "GnssBatchingCallbackAidl"
+
 #include "GnssBatchingCallback.h"
 #include <inttypes.h>
 #include <log/log.h>
diff --git a/gnss/aidl/vts/GnssCallbackAidl.cpp b/gnss/aidl/vts/GnssCallbackAidl.cpp
index f5c745b..77a2506 100644
--- a/gnss/aidl/vts/GnssCallbackAidl.cpp
+++ b/gnss/aidl/vts/GnssCallbackAidl.cpp
@@ -14,11 +14,62 @@
  * limitations under the License.
  */
 
+#define LOG_TAG "GnssCallbackAidl"
+
 #include "GnssCallbackAidl.h"
 #include <log/log.h>
 
-android::binder::Status GnssCallbackAidl::gnssSetCapabilitiesCb(const int capabilities) {
-    ALOGI("Capabilities received %d", capabilities);
+using android::binder::Status;
+using android::hardware::gnss::GnssLocation;
+using GnssSvInfo = android::hardware::gnss::IGnssCallback::GnssSvInfo;
+using GnssSystemInfo = android::hardware::gnss::IGnssCallback::GnssSystemInfo;
+
+Status GnssCallbackAidl::gnssSetCapabilitiesCb(const int capabilities) {
+    ALOGI("Capabilities received %#08x", capabilities);
     capabilities_cbq_.store(capabilities);
-    return android::binder::Status::ok();
+    return Status::ok();
+}
+
+Status GnssCallbackAidl::gnssStatusCb(const GnssStatusValue /* status */) {
+    ALOGI("gnssSvStatusCb");
+    return Status::ok();
+}
+
+Status GnssCallbackAidl::gnssSvStatusCb(const std::vector<GnssSvInfo>& svInfoList) {
+    ALOGI("gnssSvStatusCb. Size = %d", (int)svInfoList.size());
+    sv_info_list_cbq_.store(svInfoList);
+    return Status::ok();
+}
+
+Status GnssCallbackAidl::gnssLocationCb(const GnssLocation& location) {
+    ALOGI("Location received");
+    location_cbq_.store(location);
+    return Status::ok();
+}
+
+Status GnssCallbackAidl::gnssNmeaCb(const int64_t /* timestamp */, const std::string& /* nmea */) {
+    return Status::ok();
+}
+
+Status GnssCallbackAidl::gnssAcquireWakelockCb() {
+    return Status::ok();
+}
+
+Status GnssCallbackAidl::gnssReleaseWakelockCb() {
+    return Status::ok();
+}
+
+Status GnssCallbackAidl::gnssSetSystemInfoCb(const GnssSystemInfo& info) {
+    ALOGI("gnssSetSystemInfoCb, year=%d, name=%s", info.yearOfHw, info.name.c_str());
+    info_cbq_.store(info);
+    return Status::ok();
+}
+
+Status GnssCallbackAidl::gnssRequestTimeCb() {
+    return Status::ok();
+}
+
+Status GnssCallbackAidl::gnssRequestLocationCb(const bool /* independentFromGnss */,
+                                               const bool /* isUserEmergency */) {
+    return Status::ok();
 }
diff --git a/gnss/aidl/vts/GnssCallbackAidl.h b/gnss/aidl/vts/GnssCallbackAidl.h
index 7f802ea..209728d 100644
--- a/gnss/aidl/vts/GnssCallbackAidl.h
+++ b/gnss/aidl/vts/GnssCallbackAidl.h
@@ -22,11 +22,37 @@
 /* Callback class for data & Event. */
 class GnssCallbackAidl : public android::hardware::gnss::BnGnssCallback {
   public:
-    GnssCallbackAidl() : capabilities_cbq_("capabilities"){};
+    GnssCallbackAidl()
+        : capabilities_cbq_("capabilities"),
+          info_cbq_("system_info"),
+          location_cbq_("location"),
+          sv_info_list_cbq_("sv_info"){};
     ~GnssCallbackAidl(){};
 
     android::binder::Status gnssSetCapabilitiesCb(const int capabilities) override;
+    android::binder::Status gnssStatusCb(const GnssStatusValue status) override;
+    android::binder::Status gnssSvStatusCb(const std::vector<GnssSvInfo>& svInfoList) override;
+    android::binder::Status gnssLocationCb(
+            const android::hardware::gnss::GnssLocation& location) override;
+    android::binder::Status gnssNmeaCb(const int64_t timestamp, const std::string& nmea) override;
+    android::binder::Status gnssAcquireWakelockCb() override;
+    android::binder::Status gnssReleaseWakelockCb() override;
+    android::binder::Status gnssSetSystemInfoCb(const GnssSystemInfo& info) override;
+    android::binder::Status gnssRequestTimeCb() override;
+    android::binder::Status gnssRequestLocationCb(const bool independentFromGnss,
+                                                  const bool isUserEmergency) override;
 
     int last_capabilities_;
+    android::hardware::gnss::IGnssCallback::GnssSystemInfo last_info_;
+    android::hardware::gnss::GnssLocation last_location_;
+
     android::hardware::gnss::common::GnssCallbackEventQueue<int> capabilities_cbq_;
+    android::hardware::gnss::common::GnssCallbackEventQueue<
+            android::hardware::gnss::IGnssCallback::GnssSystemInfo>
+            info_cbq_;
+    android::hardware::gnss::common::GnssCallbackEventQueue<android::hardware::gnss::GnssLocation>
+            location_cbq_;
+    android::hardware::gnss::common::GnssCallbackEventQueue<
+            std::vector<android::hardware::gnss::IGnssCallback::GnssSvInfo>>
+            sv_info_list_cbq_;
 };
\ No newline at end of file
diff --git a/gnss/aidl/vts/GnssVisibilityControlCallback.cpp b/gnss/aidl/vts/GnssVisibilityControlCallback.cpp
new file mode 100644
index 0000000..aa27af1
--- /dev/null
+++ b/gnss/aidl/vts/GnssVisibilityControlCallback.cpp
@@ -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.
+ */
+
+#include "GnssVisibilityControlCallback.h"
+#include <log/log.h>
+
+android::binder::Status GnssVisibilityControlCallback::nfwNotifyCb(const NfwNotification&) {
+    // To implement
+    return android::binder::Status::ok();
+}
+
+android::binder::Status GnssVisibilityControlCallback::isInEmergencySession(bool*) {
+    // To implement
+    return android::binder::Status::ok();
+}
diff --git a/gnss/aidl/vts/GnssVisibilityControlCallback.h b/gnss/aidl/vts/GnssVisibilityControlCallback.h
new file mode 100644
index 0000000..fbacde7
--- /dev/null
+++ b/gnss/aidl/vts/GnssVisibilityControlCallback.h
@@ -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.
+ */
+
+#pragma once
+
+#include <android/hardware/gnss/visibility_control/BnGnssVisibilityControlCallback.h>
+
+class GnssVisibilityControlCallback
+    : public android::hardware::gnss::visibility_control::BnGnssVisibilityControlCallback {
+  public:
+    GnssVisibilityControlCallback(){};
+    ~GnssVisibilityControlCallback(){};
+    android::binder::Status nfwNotifyCb(
+            const android::hardware::gnss::visibility_control::IGnssVisibilityControlCallback::
+                    NfwNotification& notification) override;
+    android::binder::Status isInEmergencySession(bool* _aidl_return) override;
+};
diff --git a/gnss/aidl/vts/gnss_hal_test.cpp b/gnss/aidl/vts/gnss_hal_test.cpp
index 2447bf8..13c32ee 100644
--- a/gnss/aidl/vts/gnss_hal_test.cpp
+++ b/gnss/aidl/vts/gnss_hal_test.cpp
@@ -14,20 +14,31 @@
  * limitations under the License.
  */
 
+#define LOG_TAG "GnssHalTest"
+
 #include "gnss_hal_test.h"
 #include <hidl/ServiceManagement.h>
+#include "Utils.h"
 
-using GnssConstellationTypeAidl = android::hardware::gnss::GnssConstellationType;
+using android::hardware::gnss::GnssConstellationType;
+using android::hardware::gnss::GnssLocation;
+using android::hardware::gnss::IGnss;
+using android::hardware::gnss::IGnssCallback;
+using android::hardware::gnss::common::Utils;
+using GnssConstellationTypeV2_0 = android::hardware::gnss::V2_0::GnssConstellationType;
 
 void GnssHalTest::SetUp() {
     // Get AIDL handle
     aidl_gnss_hal_ = android::waitForDeclaredService<IGnssAidl>(String16(GetParam().c_str()));
     ASSERT_NE(aidl_gnss_hal_, nullptr);
+    ALOGD("AIDL Interface Version = %d", aidl_gnss_hal_->getInterfaceVersion());
 
-    const auto& hidlInstanceNames = android::hardware::getAllHalInstanceNames(
-            android::hardware::gnss::V2_1::IGnss::descriptor);
-    gnss_hal_ = IGnss_V2_1::getService(hidlInstanceNames[0]);
-    ASSERT_NE(gnss_hal_, nullptr);
+    if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+        const auto& hidlInstanceNames = android::hardware::getAllHalInstanceNames(
+                android::hardware::gnss::V2_1::IGnss::descriptor);
+        gnss_hal_ = IGnss_V2_1::getService(hidlInstanceNames[0]);
+        ASSERT_NE(gnss_hal_, nullptr);
+    }
 
     SetUpGnssCallback();
 }
@@ -40,7 +51,6 @@
     if (!status.isOk()) {
         ALOGE("Failed to setCallback");
     }
-
     ASSERT_TRUE(status.isOk());
 
     /*
@@ -48,9 +58,243 @@
      */
     EXPECT_TRUE(aidl_gnss_cb_->capabilities_cbq_.retrieve(aidl_gnss_cb_->last_capabilities_,
                                                           TIMEOUT_SEC));
-
     EXPECT_EQ(aidl_gnss_cb_->capabilities_cbq_.calledCount(), 1);
 
-    // Invoke the super method.
-    GnssHalTestTemplate<IGnss_V2_1>::SetUpGnssCallback();
+    if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+        // Invoke the super method.
+        GnssHalTestTemplate<IGnss_V2_1>::SetUpGnssCallback();
+    }
+}
+
+void GnssHalTest::CheckLocation(const GnssLocation& location, bool check_speed) {
+    Utils::checkLocation(location, check_speed, /* check_more_accuracies= */ true);
+}
+
+void GnssHalTest::SetPositionMode(const int min_interval_msec, const bool low_power_mode) {
+    if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+        // Invoke the super method.
+        return GnssHalTestTemplate<IGnss_V2_1>::SetPositionMode(min_interval_msec, low_power_mode);
+    }
+
+    const int kPreferredAccuracy = 0;  // Ideally perfect (matches GnssLocationProvider)
+    const int kPreferredTimeMsec = 0;  // Ideally immediate
+
+    auto status = aidl_gnss_hal_->setPositionMode(
+            IGnss::GnssPositionMode::MS_BASED, IGnss::GnssPositionRecurrence::RECURRENCE_PERIODIC,
+            min_interval_msec, kPreferredAccuracy, kPreferredTimeMsec, low_power_mode);
+
+    ASSERT_TRUE(status.isOk());
+}
+
+bool GnssHalTest::StartAndCheckFirstLocation(const int min_interval_msec,
+                                             const bool low_power_mode) {
+    if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+        // Invoke the super method.
+        return GnssHalTestTemplate<IGnss_V2_1>::StartAndCheckFirstLocation(min_interval_msec,
+                                                                           low_power_mode);
+    }
+
+    SetPositionMode(min_interval_msec, low_power_mode);
+    auto result = aidl_gnss_hal_->start();
+
+    EXPECT_TRUE(result.isOk());
+
+    /*
+     * GnssLocationProvider support of AGPS SUPL & XtraDownloader is not available in VTS,
+     * so allow time to demodulate ephemeris over the air.
+     */
+    const int kFirstGnssLocationTimeoutSeconds = 75;
+
+    EXPECT_TRUE(aidl_gnss_cb_->location_cbq_.retrieve(aidl_gnss_cb_->last_location_,
+                                                      kFirstGnssLocationTimeoutSeconds));
+    int locationCalledCount = aidl_gnss_cb_->location_cbq_.calledCount();
+    EXPECT_EQ(locationCalledCount, 1);
+
+    if (locationCalledCount > 0) {
+        // don't require speed on first fix
+        CheckLocation(aidl_gnss_cb_->last_location_, false);
+        return true;
+    }
+    return false;
+}
+
+void GnssHalTest::StopAndClearLocations() {
+    ALOGD("StopAndClearLocations");
+    if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+        // Invoke the super method.
+        return GnssHalTestTemplate<IGnss_V2_1>::StopAndClearLocations();
+    }
+
+    auto status = aidl_gnss_hal_->stop();
+    EXPECT_TRUE(status.isOk());
+
+    /*
+     * Clear notify/waiting counter, allowing up till the timeout after
+     * the last reply for final startup messages to arrive (esp. system
+     * info.)
+     */
+    while (aidl_gnss_cb_->location_cbq_.retrieve(aidl_gnss_cb_->last_location_, TIMEOUT_SEC)) {
+    }
+    aidl_gnss_cb_->location_cbq_.reset();
+}
+
+void GnssHalTest::StartAndCheckLocations(int count) {
+    if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+        // Invoke the super method.
+        return GnssHalTestTemplate<IGnss_V2_1>::StartAndCheckLocations(count);
+    }
+    const int kMinIntervalMsec = 500;
+    const int kLocationTimeoutSubsequentSec = 2;
+    const bool kLowPowerMode = false;
+
+    EXPECT_TRUE(StartAndCheckFirstLocation(kMinIntervalMsec, kLowPowerMode));
+
+    for (int i = 1; i < count; i++) {
+        EXPECT_TRUE(aidl_gnss_cb_->location_cbq_.retrieve(aidl_gnss_cb_->last_location_,
+                                                          kLocationTimeoutSubsequentSec));
+        int locationCalledCount = aidl_gnss_cb_->location_cbq_.calledCount();
+        EXPECT_EQ(locationCalledCount, i + 1);
+        // Don't cause confusion by checking details if no location yet
+        if (locationCalledCount > 0) {
+            // Should be more than 1 location by now, but if not, still don't check first fix speed
+            CheckLocation(aidl_gnss_cb_->last_location_, locationCalledCount > 1);
+        }
+    }
+}
+
+std::list<std::vector<IGnssCallback::GnssSvInfo>> GnssHalTest::convertToAidl(
+        const std::list<hidl_vec<IGnssCallback_2_1::GnssSvInfo>>& sv_info_list) {
+    std::list<std::vector<IGnssCallback::GnssSvInfo>> aidl_sv_info_list;
+    for (const auto& sv_info_vec : sv_info_list) {
+        std::vector<IGnssCallback::GnssSvInfo> aidl_sv_info_vec;
+        for (const auto& sv_info : sv_info_vec) {
+            IGnssCallback::GnssSvInfo aidl_sv_info;
+            aidl_sv_info.svid = sv_info.v2_0.v1_0.svid;
+            aidl_sv_info.constellation =
+                    static_cast<GnssConstellationType>(sv_info.v2_0.constellation);
+            aidl_sv_info.cN0Dbhz = sv_info.v2_0.v1_0.cN0Dbhz;
+            aidl_sv_info.basebandCN0DbHz = sv_info.basebandCN0DbHz;
+            aidl_sv_info.elevationDegrees = sv_info.v2_0.v1_0.elevationDegrees;
+            aidl_sv_info.azimuthDegrees = sv_info.v2_0.v1_0.azimuthDegrees;
+            aidl_sv_info.carrierFrequencyHz = (int64_t)sv_info.v2_0.v1_0.carrierFrequencyHz;
+            aidl_sv_info.svFlag = (int)sv_info.v2_0.v1_0.svFlag;
+            aidl_sv_info_vec.push_back(aidl_sv_info);
+        }
+        aidl_sv_info_list.push_back(aidl_sv_info_vec);
+    }
+    return aidl_sv_info_list;
+}
+
+/*
+ * FindStrongFrequentNonGpsSource:
+ *
+ * Search through a GnssSvStatus list for the strongest non-GPS satellite observed enough times
+ *
+ * returns the strongest source,
+ *         or a source with constellation == UNKNOWN if none are found sufficient times
+ */
+BlocklistedSource GnssHalTest::FindStrongFrequentNonGpsSource(
+        const std::list<hidl_vec<IGnssCallback_2_1::GnssSvInfo>> sv_info_list,
+        const int min_observations) {
+    return FindStrongFrequentNonGpsSource(convertToAidl(sv_info_list), min_observations);
+}
+
+BlocklistedSource GnssHalTest::FindStrongFrequentNonGpsSource(
+        const std::list<std::vector<IGnssCallback::GnssSvInfo>> sv_info_list,
+        const int min_observations) {
+    std::map<ComparableBlocklistedSource, SignalCounts> mapSignals;
+
+    for (const auto& sv_info_vec : sv_info_list) {
+        for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
+            const auto& gnss_sv = sv_info_vec[iSv];
+            if ((gnss_sv.svFlag & (int)IGnssCallback::GnssSvFlags::USED_IN_FIX) &&
+                (gnss_sv.constellation != GnssConstellationType::GPS)) {
+                ComparableBlocklistedSource source;
+                source.id.svid = gnss_sv.svid;
+                source.id.constellation = gnss_sv.constellation;
+
+                const auto& itSignal = mapSignals.find(source);
+                if (itSignal == mapSignals.end()) {
+                    SignalCounts counts;
+                    counts.observations = 1;
+                    counts.max_cn0_dbhz = gnss_sv.cN0Dbhz;
+                    mapSignals.insert(
+                            std::pair<ComparableBlocklistedSource, SignalCounts>(source, counts));
+                } else {
+                    itSignal->second.observations++;
+                    if (itSignal->second.max_cn0_dbhz < gnss_sv.cN0Dbhz) {
+                        itSignal->second.max_cn0_dbhz = gnss_sv.cN0Dbhz;
+                    }
+                }
+            }
+        }
+    }
+
+    float max_cn0_dbhz_with_sufficient_count = 0.;
+    int total_observation_count = 0;
+    int blocklisted_source_count_observation = 0;
+
+    ComparableBlocklistedSource source_to_blocklist;  // initializes to zero = UNKNOWN constellation
+    for (auto const& pairSignal : mapSignals) {
+        total_observation_count += pairSignal.second.observations;
+        if ((pairSignal.second.observations >= min_observations) &&
+            (pairSignal.second.max_cn0_dbhz > max_cn0_dbhz_with_sufficient_count)) {
+            source_to_blocklist = pairSignal.first;
+            blocklisted_source_count_observation = pairSignal.second.observations;
+            max_cn0_dbhz_with_sufficient_count = pairSignal.second.max_cn0_dbhz;
+        }
+    }
+    ALOGD("Among %d observations, chose svid %d, constellation %d, "
+          "with %d observations at %.1f max CNo",
+          total_observation_count, source_to_blocklist.id.svid,
+          (int)source_to_blocklist.id.constellation, blocklisted_source_count_observation,
+          max_cn0_dbhz_with_sufficient_count);
+
+    return source_to_blocklist.id;
+}
+
+GnssConstellationType GnssHalTest::startLocationAndGetNonGpsConstellation(
+        const int locations_to_await, const int gnss_sv_info_list_timeout) {
+    if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+        return static_cast<GnssConstellationType>(
+                GnssHalTestTemplate<IGnss_V2_1>::startLocationAndGetNonGpsConstellation(
+                        locations_to_await, gnss_sv_info_list_timeout));
+    }
+    aidl_gnss_cb_->location_cbq_.reset();
+    StartAndCheckLocations(locations_to_await);
+    const int location_called_count = aidl_gnss_cb_->location_cbq_.calledCount();
+
+    // Tolerate 1 less sv status to handle edge cases in reporting.
+    int sv_info_list_cbq_size = aidl_gnss_cb_->sv_info_list_cbq_.size();
+    EXPECT_GE(sv_info_list_cbq_size + 1, locations_to_await);
+    ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations (%d received)",
+          sv_info_list_cbq_size, locations_to_await, location_called_count);
+
+    // Find first non-GPS constellation to blocklist
+    GnssConstellationType constellation_to_blocklist = GnssConstellationType::UNKNOWN;
+    for (int i = 0; i < sv_info_list_cbq_size; ++i) {
+        std::vector<IGnssCallback::GnssSvInfo> sv_info_vec;
+        aidl_gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, gnss_sv_info_list_timeout);
+        for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
+            auto& gnss_sv = sv_info_vec[iSv];
+            if ((gnss_sv.svFlag & (uint32_t)IGnssCallback::GnssSvFlags::USED_IN_FIX) &&
+                (gnss_sv.constellation != GnssConstellationType::UNKNOWN) &&
+                (gnss_sv.constellation != GnssConstellationType::GPS)) {
+                // found a non-GPS constellation
+                constellation_to_blocklist = gnss_sv.constellation;
+                break;
+            }
+        }
+        if (constellation_to_blocklist != GnssConstellationType::UNKNOWN) {
+            break;
+        }
+    }
+
+    if (constellation_to_blocklist == GnssConstellationType::UNKNOWN) {
+        ALOGI("No non-GPS constellations found, constellation blocklist test less effective.");
+        // Proceed functionally to blocklist something.
+        constellation_to_blocklist = GnssConstellationType::GLONASS;
+    }
+
+    return constellation_to_blocklist;
 }
diff --git a/gnss/aidl/vts/gnss_hal_test.h b/gnss/aidl/vts/gnss_hal_test.h
index e3ecbed..d479af3 100644
--- a/gnss/aidl/vts/gnss_hal_test.h
+++ b/gnss/aidl/vts/gnss_hal_test.h
@@ -41,9 +41,50 @@
   public:
     GnssHalTest(){};
     ~GnssHalTest(){};
+
+    struct ComparableBlocklistedSource {
+        android::hardware::gnss::BlocklistedSource id;
+
+        ComparableBlocklistedSource() {
+            id.constellation = android::hardware::gnss::GnssConstellationType::UNKNOWN;
+            id.svid = 0;
+        }
+
+        bool operator<(const ComparableBlocklistedSource& compare) const {
+            return ((id.svid < compare.id.svid) || ((id.svid == compare.id.svid) &&
+                                                    (id.constellation < compare.id.constellation)));
+        }
+    };
+
+    struct SignalCounts {
+        int observations;
+        float max_cn0_dbhz;
+    };
+
     virtual void SetUp() override;
     virtual void SetUpGnssCallback() override;
 
+    void CheckLocation(const android::hardware::gnss::GnssLocation& location,
+                       const bool check_speed);
+    void SetPositionMode(const int min_interval_msec, const bool low_power_mode);
+    bool StartAndCheckFirstLocation(const int min_interval_msec, const bool low_power_mode);
+    void StopAndClearLocations();
+    void StartAndCheckLocations(int count);
+
+    android::hardware::gnss::GnssConstellationType startLocationAndGetNonGpsConstellation(
+            const int locations_to_await, const int gnss_sv_info_list_timeout);
+    std::list<std::vector<android::hardware::gnss::IGnssCallback::GnssSvInfo>> convertToAidl(
+            const std::list<hidl_vec<android::hardware::gnss::V2_1::IGnssCallback::GnssSvInfo>>&
+                    sv_info_list);
+    android::hardware::gnss::BlocklistedSource FindStrongFrequentNonGpsSource(
+            const std::list<hidl_vec<android::hardware::gnss::V2_1::IGnssCallback::GnssSvInfo>>
+                    sv_info_list,
+            const int min_observations);
+    android::hardware::gnss::BlocklistedSource FindStrongFrequentNonGpsSource(
+            const std::list<std::vector<android::hardware::gnss::IGnssCallback::GnssSvInfo>>
+                    sv_info_list,
+            const int min_observations);
+
     sp<IGnssAidl> aidl_gnss_hal_;
     sp<GnssCallbackAidl> aidl_gnss_cb_;  // Primary callback interface
 };
diff --git a/gnss/aidl/vts/gnss_hal_test_cases.cpp b/gnss/aidl/vts/gnss_hal_test_cases.cpp
index aac59db..9acef8b 100644
--- a/gnss/aidl/vts/gnss_hal_test_cases.cpp
+++ b/gnss/aidl/vts/gnss_hal_test_cases.cpp
@@ -19,16 +19,20 @@
 #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 <android/hardware/gnss/visibility_control/IGnssVisibilityControl.h>
+#include <cutils/properties.h>
 #include "AGnssCallbackAidl.h"
 #include "GnssBatchingCallback.h"
 #include "GnssGeofenceCallback.h"
 #include "GnssMeasurementCallbackAidl.h"
 #include "GnssNavigationMessageCallback.h"
 #include "GnssPowerIndicationCallback.h"
+#include "GnssVisibilityControlCallback.h"
 #include "gnss_hal_test.h"
 
 using android::sp;
@@ -42,7 +46,9 @@
 using android::hardware::gnss::IGnss;
 using android::hardware::gnss::IGnssBatching;
 using android::hardware::gnss::IGnssBatchingCallback;
+using android::hardware::gnss::IGnssCallback;
 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,9 +58,17 @@
 using android::hardware::gnss::IGnssPsds;
 using android::hardware::gnss::PsdsType;
 using android::hardware::gnss::SatellitePvt;
+using android::hardware::gnss::visibility_control::IGnssVisibilityControl;
 
+using GnssConstellationTypeV2_0 = android::hardware::gnss::V2_0::GnssConstellationType;
 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
@@ -312,7 +326,11 @@
     auto powerStats1 = gnssPowerIndicationCallback->last_gnss_power_stats_;
 
     // Get a location and request another GnssPowerStats
-    gnss_cb_->location_cbq_.reset();
+    if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+        gnss_cb_->location_cbq_.reset();
+    } else {
+        aidl_gnss_cb_->location_cbq_.reset();
+    }
     StartAndCheckFirstLocation(/* min_interval_msec= */ 1000, /* low_power_mode= */ false);
 
     // Request and verify the 2nd GnssPowerStats has larger values than the 1st one
@@ -363,88 +381,6 @@
 }
 
 /*
- * FindStrongFrequentNonGpsSource:
- *
- * Search through a GnssSvStatus list for the strongest non-GPS satellite observed enough times
- *
- * returns the strongest source,
- *         or a source with constellation == UNKNOWN if none are found sufficient times
- */
-BlocklistedSource FindStrongFrequentNonGpsSource(
-        const std::list<hidl_vec<IGnssCallback_2_1::GnssSvInfo>> sv_info_list,
-        const int min_observations) {
-    struct ComparableBlocklistedSource {
-        BlocklistedSource id;
-
-        ComparableBlocklistedSource() {
-            id.constellation = GnssConstellationTypeAidl::UNKNOWN;
-            id.svid = 0;
-        }
-
-        bool operator<(const ComparableBlocklistedSource& compare) const {
-            return ((id.svid < compare.id.svid) || ((id.svid == compare.id.svid) &&
-                                                    (id.constellation < compare.id.constellation)));
-        }
-    };
-
-    struct SignalCounts {
-        int observations;
-        float max_cn0_dbhz;
-    };
-
-    std::map<ComparableBlocklistedSource, SignalCounts> mapSignals;
-
-    for (const auto& sv_info_vec : sv_info_list) {
-        for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
-            const auto& gnss_sv = sv_info_vec[iSv];
-            if ((gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX) &&
-                (gnss_sv.v2_0.constellation != GnssConstellationType::GPS)) {
-                ComparableBlocklistedSource source;
-                source.id.svid = gnss_sv.v2_0.v1_0.svid;
-                source.id.constellation =
-                        static_cast<GnssConstellationTypeAidl>(gnss_sv.v2_0.constellation);
-
-                const auto& itSignal = mapSignals.find(source);
-                if (itSignal == mapSignals.end()) {
-                    SignalCounts counts;
-                    counts.observations = 1;
-                    counts.max_cn0_dbhz = gnss_sv.v2_0.v1_0.cN0Dbhz;
-                    mapSignals.insert(
-                            std::pair<ComparableBlocklistedSource, SignalCounts>(source, counts));
-                } else {
-                    itSignal->second.observations++;
-                    if (itSignal->second.max_cn0_dbhz < gnss_sv.v2_0.v1_0.cN0Dbhz) {
-                        itSignal->second.max_cn0_dbhz = gnss_sv.v2_0.v1_0.cN0Dbhz;
-                    }
-                }
-            }
-        }
-    }
-
-    float max_cn0_dbhz_with_sufficient_count = 0.;
-    int total_observation_count = 0;
-    int blocklisted_source_count_observation = 0;
-
-    ComparableBlocklistedSource source_to_blocklist;  // initializes to zero = UNKNOWN constellation
-    for (auto const& pairSignal : mapSignals) {
-        total_observation_count += pairSignal.second.observations;
-        if ((pairSignal.second.observations >= min_observations) &&
-            (pairSignal.second.max_cn0_dbhz > max_cn0_dbhz_with_sufficient_count)) {
-            source_to_blocklist = pairSignal.first;
-            blocklisted_source_count_observation = pairSignal.second.observations;
-            max_cn0_dbhz_with_sufficient_count = pairSignal.second.max_cn0_dbhz;
-        }
-    }
-    ALOGD("Among %d observations, chose svid %d, constellation %d, "
-          "with %d observations at %.1f max CNo",
-          total_observation_count, source_to_blocklist.id.svid,
-          (int)source_to_blocklist.id.constellation, blocklisted_source_count_observation,
-          max_cn0_dbhz_with_sufficient_count);
-
-    return source_to_blocklist.id;
-}
-
-/*
  * BlocklistIndividualSatellites:
  *
  * 1) Turns on location, waits for 3 locations, ensuring they are valid, and checks corresponding
@@ -469,12 +405,20 @@
     const int kLocationsToAwait = 3;
     const int kRetriesToUnBlocklist = 10;
 
-    gnss_cb_->location_cbq_.reset();
+    if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+        gnss_cb_->location_cbq_.reset();
+    } else {
+        aidl_gnss_cb_->location_cbq_.reset();
+    }
     StartAndCheckLocations(kLocationsToAwait);
-    int location_called_count = gnss_cb_->location_cbq_.calledCount();
+    int location_called_count = (aidl_gnss_hal_->getInterfaceVersion() == 1)
+                                        ? gnss_cb_->location_cbq_.calledCount()
+                                        : aidl_gnss_cb_->location_cbq_.calledCount();
 
     // Tolerate 1 less sv status to handle edge cases in reporting.
-    int sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size();
+    int sv_info_list_cbq_size = (aidl_gnss_hal_->getInterfaceVersion() == 1)
+                                        ? gnss_cb_->sv_info_list_cbq_.size()
+                                        : aidl_gnss_cb_->sv_info_list_cbq_.size();
     EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
     ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations (%d received)",
           sv_info_list_cbq_size, kLocationsToAwait, location_called_count);
@@ -486,14 +430,22 @@
      */
 
     const int kGnssSvInfoListTimeout = 2;
-    std::list<hidl_vec<IGnssCallback_2_1::GnssSvInfo>> sv_info_vec_list;
-    int count = gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec_list, sv_info_list_cbq_size,
-                                                     kGnssSvInfoListTimeout);
-
-    ASSERT_EQ(count, sv_info_list_cbq_size);
-
-    BlocklistedSource source_to_blocklist =
-            FindStrongFrequentNonGpsSource(sv_info_vec_list, kLocationsToAwait - 1);
+    BlocklistedSource source_to_blocklist;
+    if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+        std::list<hidl_vec<IGnssCallback_2_1::GnssSvInfo>> sv_info_vec_list;
+        int count = gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec_list, sv_info_list_cbq_size,
+                                                         kGnssSvInfoListTimeout);
+        ASSERT_EQ(count, sv_info_list_cbq_size);
+        source_to_blocklist =
+                FindStrongFrequentNonGpsSource(sv_info_vec_list, kLocationsToAwait - 1);
+    } else {
+        std::list<std::vector<IGnssCallback::GnssSvInfo>> sv_info_vec_list;
+        int count = aidl_gnss_cb_->sv_info_list_cbq_.retrieve(
+                sv_info_vec_list, sv_info_list_cbq_size, kGnssSvInfoListTimeout);
+        ASSERT_EQ(count, sv_info_list_cbq_size);
+        source_to_blocklist =
+                FindStrongFrequentNonGpsSource(sv_info_vec_list, kLocationsToAwait - 1);
+    }
 
     if (source_to_blocklist.constellation == GnssConstellationTypeAidl::UNKNOWN) {
         // Cannot find a non-GPS satellite. Let the test pass.
@@ -517,32 +469,53 @@
     ASSERT_TRUE(status.isOk());
 
     // retry and ensure satellite not used
-    gnss_cb_->sv_info_list_cbq_.reset();
+    if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+        gnss_cb_->sv_info_list_cbq_.reset();
+        gnss_cb_->location_cbq_.reset();
+    } else {
+        aidl_gnss_cb_->sv_info_list_cbq_.reset();
+        aidl_gnss_cb_->location_cbq_.reset();
+    }
 
-    gnss_cb_->location_cbq_.reset();
     StartAndCheckLocations(kLocationsToAwait);
 
     // early exit if test is being run with insufficient signal
-    location_called_count = gnss_cb_->location_cbq_.calledCount();
+    location_called_count = (aidl_gnss_hal_->getInterfaceVersion() == 1)
+                                    ? gnss_cb_->location_cbq_.calledCount()
+                                    : aidl_gnss_cb_->location_cbq_.calledCount();
     if (location_called_count == 0) {
         ALOGE("0 Gnss locations received - ensure sufficient signal and retry");
     }
     ASSERT_TRUE(location_called_count > 0);
 
     // Tolerate 1 less sv status to handle edge cases in reporting.
-    sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size();
+    sv_info_list_cbq_size = (aidl_gnss_hal_->getInterfaceVersion() == 1)
+                                    ? gnss_cb_->sv_info_list_cbq_.size()
+                                    : aidl_gnss_cb_->sv_info_list_cbq_.size();
     EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
     ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations (%d received)",
           sv_info_list_cbq_size, kLocationsToAwait, location_called_count);
     for (int i = 0; i < sv_info_list_cbq_size; ++i) {
-        hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
-        gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
-        for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
-            const auto& gnss_sv = sv_info_vec[iSv];
-            EXPECT_FALSE((gnss_sv.v2_0.v1_0.svid == source_to_blocklist.svid) &&
-                         (static_cast<GnssConstellationTypeAidl>(gnss_sv.v2_0.constellation) ==
-                          source_to_blocklist.constellation) &&
-                         (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
+        if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+            hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
+            gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
+            for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
+                auto& gnss_sv = sv_info_vec[iSv];
+                EXPECT_FALSE(
+                        (gnss_sv.v2_0.v1_0.svid == source_to_blocklist.svid) &&
+                        (static_cast<GnssConstellationTypeAidl>(gnss_sv.v2_0.constellation) ==
+                         source_to_blocklist.constellation) &&
+                        (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
+            }
+        } else {
+            std::vector<IGnssCallback::GnssSvInfo> sv_info_vec;
+            aidl_gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
+            for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
+                auto& gnss_sv = sv_info_vec[iSv];
+                EXPECT_FALSE((gnss_sv.svid == source_to_blocklist.svid) &&
+                             (gnss_sv.constellation == source_to_blocklist.constellation) &&
+                             (gnss_sv.svFlag & (int)IGnssCallback::GnssSvFlags::USED_IN_FIX));
+            }
         }
     }
 
@@ -557,36 +530,59 @@
     int unblocklist_loops_remaining = kRetriesToUnBlocklist;
     while (!strongest_sv_is_reobserved && (unblocklist_loops_remaining-- > 0)) {
         StopAndClearLocations();
-        gnss_cb_->sv_info_list_cbq_.reset();
 
-        gnss_cb_->location_cbq_.reset();
+        if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+            gnss_cb_->sv_info_list_cbq_.reset();
+            gnss_cb_->location_cbq_.reset();
+        } else {
+            aidl_gnss_cb_->sv_info_list_cbq_.reset();
+            aidl_gnss_cb_->location_cbq_.reset();
+        }
         StartAndCheckLocations(kLocationsToAwait);
 
         // early exit loop if test is being run with insufficient signal
-        location_called_count = gnss_cb_->location_cbq_.calledCount();
+        location_called_count = (aidl_gnss_hal_->getInterfaceVersion() == 1)
+                                        ? gnss_cb_->location_cbq_.calledCount()
+                                        : aidl_gnss_cb_->location_cbq_.calledCount();
         if (location_called_count == 0) {
             ALOGE("0 Gnss locations received - ensure sufficient signal and retry");
         }
         ASSERT_TRUE(location_called_count > 0);
 
         // Tolerate 1 less sv status to handle edge cases in reporting.
-        sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size();
+        sv_info_list_cbq_size = (aidl_gnss_hal_->getInterfaceVersion() == 1)
+                                        ? gnss_cb_->sv_info_list_cbq_.size()
+                                        : aidl_gnss_cb_->sv_info_list_cbq_.size();
         EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
         ALOGD("Clear blocklist, observed %d GnssSvInfo, while awaiting %d Locations"
               ", tries remaining %d",
               sv_info_list_cbq_size, kLocationsToAwait, unblocklist_loops_remaining);
 
         for (int i = 0; i < sv_info_list_cbq_size; ++i) {
-            hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
-            gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
-            for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
-                const auto& gnss_sv = sv_info_vec[iSv];
-                if ((gnss_sv.v2_0.v1_0.svid == source_to_blocklist.svid) &&
-                    (static_cast<GnssConstellationTypeAidl>(gnss_sv.v2_0.constellation) ==
-                     source_to_blocklist.constellation) &&
-                    (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX)) {
-                    strongest_sv_is_reobserved = true;
-                    break;
+            if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+                hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
+                gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
+                for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
+                    auto& gnss_sv = sv_info_vec[iSv];
+                    if ((gnss_sv.v2_0.v1_0.svid == source_to_blocklist.svid) &&
+                        (static_cast<GnssConstellationTypeAidl>(gnss_sv.v2_0.constellation) ==
+                         source_to_blocklist.constellation) &&
+                        (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX)) {
+                        strongest_sv_is_reobserved = true;
+                        break;
+                    }
+                }
+            } else {
+                std::vector<IGnssCallback::GnssSvInfo> sv_info_vec;
+                aidl_gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
+                for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
+                    auto& gnss_sv = sv_info_vec[iSv];
+                    if ((gnss_sv.svid == source_to_blocklist.svid) &&
+                        (gnss_sv.constellation == source_to_blocklist.constellation) &&
+                        (gnss_sv.svFlag & (int)IGnssCallback::GnssSvFlags::USED_IN_FIX)) {
+                        strongest_sv_is_reobserved = true;
+                        break;
+                    }
                 }
             }
             if (strongest_sv_is_reobserved) break;
@@ -648,27 +644,47 @@
     ASSERT_TRUE(status.isOk());
 
     // retry and ensure constellation not used
-    gnss_cb_->sv_info_list_cbq_.reset();
-
-    gnss_cb_->location_cbq_.reset();
+    if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+        gnss_cb_->sv_info_list_cbq_.reset();
+        gnss_cb_->location_cbq_.reset();
+    } else {
+        aidl_gnss_cb_->sv_info_list_cbq_.reset();
+        aidl_gnss_cb_->location_cbq_.reset();
+    }
     StartAndCheckLocations(kLocationsToAwait);
 
     // Tolerate 1 less sv status to handle edge cases in reporting.
-    int sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size();
+    int sv_info_list_cbq_size = (aidl_gnss_hal_->getInterfaceVersion() == 1)
+                                        ? gnss_cb_->sv_info_list_cbq_.size()
+                                        : aidl_gnss_cb_->sv_info_list_cbq_.size();
     EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
     ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations", sv_info_list_cbq_size,
           kLocationsToAwait);
     for (int i = 0; i < sv_info_list_cbq_size; ++i) {
-        hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
-        gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
-        for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
-            const auto& gnss_sv = sv_info_vec[iSv];
-            EXPECT_FALSE((static_cast<GnssConstellationTypeAidl>(gnss_sv.v2_0.constellation) ==
-                          source_to_blocklist_1.constellation) &&
-                         (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
-            EXPECT_FALSE((static_cast<GnssConstellationTypeAidl>(gnss_sv.v2_0.constellation) ==
-                          source_to_blocklist_2.constellation) &&
-                         (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
+        if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+            hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
+            gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
+            for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
+                const auto& gnss_sv = sv_info_vec[iSv];
+                EXPECT_FALSE(
+                        (static_cast<GnssConstellationTypeAidl>(gnss_sv.v2_0.constellation) ==
+                         source_to_blocklist_1.constellation) &&
+                        (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
+                EXPECT_FALSE(
+                        (static_cast<GnssConstellationTypeAidl>(gnss_sv.v2_0.constellation) ==
+                         source_to_blocklist_2.constellation) &&
+                        (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
+            }
+        } else {
+            std::vector<IGnssCallback::GnssSvInfo> sv_info_vec;
+            aidl_gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
+            for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
+                const auto& gnss_sv = sv_info_vec[iSv];
+                EXPECT_FALSE((gnss_sv.constellation == source_to_blocklist_1.constellation) &&
+                             (gnss_sv.svFlag & (int)IGnssCallback::GnssSvFlags::USED_IN_FIX));
+                EXPECT_FALSE((gnss_sv.constellation == source_to_blocklist_2.constellation) &&
+                             (gnss_sv.svFlag & (int)IGnssCallback::GnssSvFlags::USED_IN_FIX));
+            }
         }
     }
 
@@ -731,27 +747,47 @@
     StopAndClearLocations();
 
     // retry and ensure constellation not used
-    gnss_cb_->sv_info_list_cbq_.reset();
-
-    gnss_cb_->location_cbq_.reset();
+    if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+        gnss_cb_->sv_info_list_cbq_.reset();
+        gnss_cb_->location_cbq_.reset();
+    } else {
+        aidl_gnss_cb_->sv_info_list_cbq_.reset();
+        aidl_gnss_cb_->location_cbq_.reset();
+    }
     StartAndCheckLocations(kLocationsToAwait);
 
     // Tolerate 1 less sv status to handle edge cases in reporting.
-    int sv_info_list_cbq_size = gnss_cb_->sv_info_list_cbq_.size();
+    int sv_info_list_cbq_size = (aidl_gnss_hal_->getInterfaceVersion() == 1)
+                                        ? gnss_cb_->sv_info_list_cbq_.size()
+                                        : aidl_gnss_cb_->sv_info_list_cbq_.size();
     EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
     ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations", sv_info_list_cbq_size,
           kLocationsToAwait);
     for (int i = 0; i < sv_info_list_cbq_size; ++i) {
-        hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
-        gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
-        for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
-            const auto& gnss_sv = sv_info_vec[iSv];
-            EXPECT_FALSE((static_cast<GnssConstellationTypeAidl>(gnss_sv.v2_0.constellation) ==
-                          source_to_blocklist_1.constellation) &&
-                         (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
-            EXPECT_FALSE((static_cast<GnssConstellationTypeAidl>(gnss_sv.v2_0.constellation) ==
-                          source_to_blocklist_2.constellation) &&
-                         (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
+        if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+            hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
+            gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
+            for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
+                const auto& gnss_sv = sv_info_vec[iSv];
+                EXPECT_FALSE(
+                        (static_cast<GnssConstellationTypeAidl>(gnss_sv.v2_0.constellation) ==
+                         source_to_blocklist_1.constellation) &&
+                        (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
+                EXPECT_FALSE(
+                        (static_cast<GnssConstellationTypeAidl>(gnss_sv.v2_0.constellation) ==
+                         source_to_blocklist_2.constellation) &&
+                        (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
+            }
+        } else {
+            std::vector<IGnssCallback::GnssSvInfo> sv_info_vec;
+            aidl_gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
+            for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
+                const auto& gnss_sv = sv_info_vec[iSv];
+                EXPECT_FALSE((gnss_sv.constellation == source_to_blocklist_1.constellation) &&
+                             (gnss_sv.svFlag & (int)IGnssCallback::GnssSvFlags::USED_IN_FIX));
+                EXPECT_FALSE((gnss_sv.constellation == source_to_blocklist_2.constellation) &&
+                             (gnss_sv.svFlag & (int)IGnssCallback::GnssSvFlags::USED_IN_FIX));
+            }
         }
     }
 
@@ -817,6 +853,116 @@
     ASSERT_TRUE(status.isOk());
 
     // Set SUPL server host/port
-    status = iAGnss->setServer(AGnssType::SUPL, String16("supl.google.com"), 7275);
+    status = iAGnss->setServer(AGnssType::SUPL, std::string("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()) {
+        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
+    }
+}
+
+/*
+ * TestAGnssExtension:
+ * TestGnssVisibilityControlExtension:
+ * 1. Gets the IGnssVisibilityControl extension.
+ * 2. Sets GnssVisibilityControlCallback
+ * 3. Sets proxy apps
+ */
+TEST_P(GnssHalTest, TestGnssVisibilityControlExtension) {
+    if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+        return;
+    }
+    sp<IGnssVisibilityControl> iGnssVisibilityControl;
+    auto status = aidl_gnss_hal_->getExtensionGnssVisibilityControl(&iGnssVisibilityControl);
+    ASSERT_TRUE(status.isOk());
+    ASSERT_TRUE(iGnssVisibilityControl != nullptr);
+    auto gnssVisibilityControlCallback = sp<GnssVisibilityControlCallback>::make();
+    status = iGnssVisibilityControl->setCallback(gnssVisibilityControlCallback);
+    ASSERT_TRUE(status.isOk());
+
+    std::vector<String16> proxyApps{String16("com.example.ims"), String16("com.example.mdt")};
+    status = iGnssVisibilityControl->enableNfwLocationAccess(proxyApps);
+    ASSERT_TRUE(status.isOk());
+}
+
+/*
+ * TestGnssMeasurementSetCallbackWithOptions:
+ * 1. Gets the GnssMeasurementExtension and verifies that it returns a non-null extension.
+ * 2. Sets a GnssMeasurementCallback with intervalMillis option, waits for measurements reported,
+ *    and verifies mandatory fields are valid.
+ */
+TEST_P(GnssHalTest, TestGnssMeasurementSetCallbackWithOptions) {
+    if (aidl_gnss_hal_->getInterfaceVersion() == 1) {
+        return;
+    }
+    const int kFirstGnssMeasurementTimeoutSeconds = 10;
+    const int kNumMeasurementEvents = 5;
+
+    sp<IGnssMeasurementInterface> iGnssMeasurement;
+    auto status = aidl_gnss_hal_->getExtensionGnssMeasurement(&iGnssMeasurement);
+    ASSERT_TRUE(status.isOk());
+    ASSERT_TRUE(iGnssMeasurement != nullptr);
+
+    auto callback = sp<GnssMeasurementCallbackAidl>::make();
+    IGnssMeasurementInterface::Options options;
+    options.intervalMs = 2000;
+    status = iGnssMeasurement->setCallbackWithOptions(callback, options);
+    ASSERT_TRUE(status.isOk());
+
+    for (int i = 0; i < kNumMeasurementEvents; i++) {
+        GnssData lastMeasurement;
+        ASSERT_TRUE(callback->gnss_data_cbq_.retrieve(lastMeasurement,
+                                                      kFirstGnssMeasurementTimeoutSeconds));
+        EXPECT_EQ(callback->gnss_data_cbq_.calledCount(), i + 1);
+        ASSERT_TRUE(lastMeasurement.measurements.size() > 0);
+
+        // Validity check GnssData fields
+        CheckGnssMeasurementClockFields(lastMeasurement);
+    }
+
+    status = iGnssMeasurement->close();
     ASSERT_TRUE(status.isOk());
 }
diff --git a/gnss/common/utils/default/Utils.cpp b/gnss/common/utils/default/Utils.cpp
index c339e72..563c6d5 100644
--- a/gnss/common/utils/default/Utils.cpp
+++ b/gnss/common/utils/default/Utils.cpp
@@ -27,14 +27,17 @@
 
 using aidl::android::hardware::gnss::ElapsedRealtime;
 using aidl::android::hardware::gnss::GnssClock;
+using aidl::android::hardware::gnss::GnssConstellationType;
 using aidl::android::hardware::gnss::GnssData;
 using aidl::android::hardware::gnss::GnssLocation;
 using aidl::android::hardware::gnss::GnssMeasurement;
 using aidl::android::hardware::gnss::IGnss;
 using aidl::android::hardware::gnss::IGnssMeasurementCallback;
 using aidl::android::hardware::gnss::SatellitePvt;
+using GnssSvInfo = aidl::android::hardware::gnss::IGnssCallback::GnssSvInfo;
+using GnssSvFlags = aidl::android::hardware::gnss::IGnssCallback::GnssSvFlags;
 
-using GnssSvFlags = V1_0::IGnssCallback::GnssSvFlags;
+using GnssSvFlagsV1_0 = V1_0::IGnssCallback::GnssSvFlags;
 using GnssMeasurementFlagsV1_0 = V1_0::IGnssMeasurementCallback::GnssMeasurementFlags;
 using GnssMeasurementFlagsV2_1 = V2_1::IGnssMeasurementCallback::GnssMeasurementFlags;
 using GnssMeasurementStateV2_0 = V2_0::IGnssMeasurementCallback::GnssMeasurementState;
@@ -144,7 +147,7 @@
 
 GnssData Utils::getMockMeasurement(const bool enableCorrVecOutputs) {
     aidl::android::hardware::gnss::GnssSignalType signalType = {
-            .constellation = aidl::android::hardware::gnss::GnssConstellationType::GLONASS,
+            .constellation = GnssConstellationType::GLONASS,
             .carrierFrequencyHz = 1.59975e+09,
             .codeType = aidl::android::hardware::gnss::GnssSignalType::CODE_TYPE_C,
     };
@@ -289,6 +292,40 @@
     return location;
 }
 
+namespace {
+GnssSvInfo getMockSvInfo(int svid, GnssConstellationType type, float cN0DbHz, float basebandCN0DbHz,
+                         float elevationDegrees, float azimuthDegrees, long carrierFrequencyHz) {
+    GnssSvInfo svInfo = {
+            .svid = svid,
+            .constellation = type,
+            .cN0Dbhz = cN0DbHz,
+            .basebandCN0DbHz = basebandCN0DbHz,
+            .elevationDegrees = elevationDegrees,
+            .azimuthDegrees = azimuthDegrees,
+            .carrierFrequencyHz = carrierFrequencyHz,
+            .svFlag = (int)GnssSvFlags::USED_IN_FIX | (int)GnssSvFlags::HAS_EPHEMERIS_DATA |
+                      (int)GnssSvFlags::HAS_ALMANAC_DATA | (int)GnssSvFlags::HAS_CARRIER_FREQUENCY};
+    return svInfo;
+}
+}  // anonymous namespace
+
+std::vector<GnssSvInfo> Utils::getMockSvInfoList() {
+    std::vector<GnssSvInfo> gnssSvInfoList = {
+            getMockSvInfo(3, GnssConstellationType::GPS, 32.5, 27.5, 59.1, 166.5, kGpsL1FreqHz),
+            getMockSvInfo(5, GnssConstellationType::GPS, 27.0, 22.0, 29.0, 56.5, kGpsL1FreqHz),
+            getMockSvInfo(17, GnssConstellationType::GPS, 30.5, 25.5, 71.0, 77.0, kGpsL5FreqHz),
+            getMockSvInfo(26, GnssConstellationType::GPS, 24.1, 19.1, 28.0, 253.0, kGpsL5FreqHz),
+            getMockSvInfo(5, GnssConstellationType::GLONASS, 20.5, 15.5, 11.5, 116.0, kGloG1FreqHz),
+            getMockSvInfo(17, GnssConstellationType::GLONASS, 21.5, 16.5, 28.5, 186.0,
+                          kGloG1FreqHz),
+            getMockSvInfo(18, GnssConstellationType::GLONASS, 28.3, 25.3, 38.8, 69.0, kGloG1FreqHz),
+            getMockSvInfo(10, GnssConstellationType::GLONASS, 25.0, 20.0, 66.0, 247.0,
+                          kGloG1FreqHz),
+            getMockSvInfo(3, GnssConstellationType::IRNSS, 22.0, 19.7, 35.0, 112.0, kIrnssL5FreqHz),
+    };
+    return gnssSvInfoList;
+}
+
 hidl_vec<GnssSvInfoV2_1> Utils::getMockSvInfoListV2_1() {
     GnssSvInfoV1_0 gnssSvInfoV1_0 = Utils::getMockSvInfoV1_0(3, V1_0::GnssConstellationType::GPS,
                                                              32.5, 59.1, 166.5, kGpsL1FreqHz);
@@ -360,15 +397,15 @@
 GnssSvInfoV1_0 Utils::getMockSvInfoV1_0(int16_t svid, V1_0::GnssConstellationType type,
                                         float cN0DbHz, float elevationDegrees, float azimuthDegrees,
                                         float carrierFrequencyHz) {
-    GnssSvInfoV1_0 svInfo = {.svid = svid,
-                             .constellation = type,
-                             .cN0Dbhz = cN0DbHz,
-                             .elevationDegrees = elevationDegrees,
-                             .azimuthDegrees = azimuthDegrees,
-                             .carrierFrequencyHz = carrierFrequencyHz,
-                             .svFlag = GnssSvFlags::USED_IN_FIX | GnssSvFlags::HAS_EPHEMERIS_DATA |
-                                       GnssSvFlags::HAS_ALMANAC_DATA |
-                                       GnssSvFlags::HAS_CARRIER_FREQUENCY};
+    GnssSvInfoV1_0 svInfo = {
+            .svid = svid,
+            .constellation = type,
+            .cN0Dbhz = cN0DbHz,
+            .elevationDegrees = elevationDegrees,
+            .azimuthDegrees = azimuthDegrees,
+            .carrierFrequencyHz = carrierFrequencyHz,
+            .svFlag = GnssSvFlagsV1_0::USED_IN_FIX | GnssSvFlagsV1_0::HAS_EPHEMERIS_DATA |
+                      GnssSvFlagsV1_0::HAS_ALMANAC_DATA | GnssSvFlagsV1_0::HAS_CARRIER_FREQUENCY};
     return svInfo;
 }
 
diff --git a/gnss/common/utils/default/include/Utils.h b/gnss/common/utils/default/include/Utils.h
index 4500ee6..7065a6fb 100644
--- a/gnss/common/utils/default/include/Utils.h
+++ b/gnss/common/utils/default/include/Utils.h
@@ -35,9 +35,13 @@
             const bool enableCorrVecOutputs);
     static V2_0::IGnssMeasurementCallback::GnssData getMockMeasurementV2_0();
     static V2_1::IGnssMeasurementCallback::GnssData getMockMeasurementV2_1();
+
     static aidl::android::hardware::gnss::GnssLocation getMockLocation();
     static V2_0::GnssLocation getMockLocationV2_0();
     static V1_0::GnssLocation getMockLocationV1_0();
+
+    static std::vector<aidl::android::hardware::gnss::IGnssCallback::GnssSvInfo>
+    getMockSvInfoList();
     static hidl_vec<V2_1::IGnssCallback::GnssSvInfo> getMockSvInfoListV2_1();
     static V2_1::IGnssCallback::GnssSvInfo getMockSvInfoV2_1(
             V2_0::IGnssCallback::GnssSvInfo gnssSvInfoV2_0, float basebandCN0DbHz);
@@ -48,6 +52,7 @@
                                                              float cN0DbHz, float elevationDegrees,
                                                              float azimuthDegrees,
                                                              float carrierFrequencyHz);
+
     static hidl_vec<V2_1::IGnssAntennaInfoCallback::GnssAntennaInfo> getMockAntennaInfos();
 };
 
diff --git a/gnss/common/utils/vts/Android.bp b/gnss/common/utils/vts/Android.bp
index 47eff2e..f92e609 100644
--- a/gnss/common/utils/vts/Android.bp
+++ b/gnss/common/utils/vts/Android.bp
@@ -44,6 +44,7 @@
         "android.hardware.gnss@2.1",
         "android.hardware.gnss.measurement_corrections@1.0",
         "android.hardware.gnss.measurement_corrections@1.1",
+        "android.hardware.gnss-V2-cpp",
     ],
     static_libs: [
         "libgtest",
diff --git a/gnss/common/utils/vts/Utils.cpp b/gnss/common/utils/vts/Utils.cpp
index be22ff6..06bce9d 100644
--- a/gnss/common/utils/vts/Utils.cpp
+++ b/gnss/common/utils/vts/Utils.cpp
@@ -15,6 +15,7 @@
  */
 
 #include <Utils.h>
+#include <android/hardware/gnss/IGnss.h>
 #include "gtest/gtest.h"
 
 #include <cutils/properties.h>
@@ -27,71 +28,14 @@
 using namespace measurement_corrections::V1_0;
 using V1_0::GnssLocationFlags;
 
-void Utils::checkLocation(const V1_0::GnssLocation& location, bool check_speed,
-                          bool check_more_accuracies) {
-    EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_LAT_LONG);
-    EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_ALTITUDE);
-    if (check_speed) {
-        EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_SPEED);
-    }
-    EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_HORIZONTAL_ACCURACY);
-    // New uncertainties available in O must be provided,
-    // at least when paired with modern hardware (2017+)
-    if (check_more_accuracies) {
-        EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_VERTICAL_ACCURACY);
-        if (check_speed) {
-            EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_SPEED_ACCURACY);
-            if (location.gnssLocationFlags & GnssLocationFlags::HAS_BEARING) {
-                EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_BEARING_ACCURACY);
-            }
-        }
-    }
-    EXPECT_GE(location.latitudeDegrees, -90.0);
-    EXPECT_LE(location.latitudeDegrees, 90.0);
-    EXPECT_GE(location.longitudeDegrees, -180.0);
-    EXPECT_LE(location.longitudeDegrees, 180.0);
-    EXPECT_GE(location.altitudeMeters, -1000.0);
-    EXPECT_LE(location.altitudeMeters, 30000.0);
-    if (check_speed) {
-        EXPECT_GE(location.speedMetersPerSec, 0.0);
-        EXPECT_LE(location.speedMetersPerSec, 5.0);  // VTS tests are stationary.
+template <>
+int64_t Utils::getLocationTimestampMillis(const android::hardware::gnss::GnssLocation& location) {
+    return location.timestampMillis;
+}
 
-        // Non-zero speeds must be reported with an associated bearing
-        if (location.speedMetersPerSec > 0.0) {
-            EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_BEARING);
-        }
-    }
-
-    /*
-     * Tolerating some especially high values for accuracy estimate, in case of
-     * first fix with especially poor geometry (happens occasionally)
-     */
-    EXPECT_GT(location.horizontalAccuracyMeters, 0.0);
-    EXPECT_LE(location.horizontalAccuracyMeters, 250.0);
-
-    /*
-     * Some devices may define bearing as -180 to +180, others as 0 to 360.
-     * Both are okay & understandable.
-     */
-    if (location.gnssLocationFlags & GnssLocationFlags::HAS_BEARING) {
-        EXPECT_GE(location.bearingDegrees, -180.0);
-        EXPECT_LE(location.bearingDegrees, 360.0);
-    }
-    if (location.gnssLocationFlags & GnssLocationFlags::HAS_VERTICAL_ACCURACY) {
-        EXPECT_GT(location.verticalAccuracyMeters, 0.0);
-        EXPECT_LE(location.verticalAccuracyMeters, 500.0);
-    }
-    if (location.gnssLocationFlags & GnssLocationFlags::HAS_SPEED_ACCURACY) {
-        EXPECT_GT(location.speedAccuracyMetersPerSecond, 0.0);
-        EXPECT_LE(location.speedAccuracyMetersPerSecond, 50.0);
-    }
-    if (location.gnssLocationFlags & GnssLocationFlags::HAS_BEARING_ACCURACY) {
-        EXPECT_GT(location.bearingAccuracyDegrees, 0.0);
-        EXPECT_LE(location.bearingAccuracyDegrees, 360.0);
-    }
-
-    // Check timestamp > 1.48e12 (47 years in msec - 1970->2017+)
-    EXPECT_GT(location.timestamp, 1.48e12);
+template <>
+int64_t Utils::getLocationTimestampMillis(const V1_0::GnssLocation& location) {
+    return location.timestamp;
 }
 
 const MeasurementCorrections Utils::getMockMeasurementCorrections() {
diff --git a/gnss/common/utils/vts/include/Utils.h b/gnss/common/utils/vts/include/Utils.h
index 91c1167..40f31d2 100644
--- a/gnss/common/utils/vts/include/Utils.h
+++ b/gnss/common/utils/vts/include/Utils.h
@@ -21,6 +21,7 @@
 #include <android/hardware/gnss/2.0/IGnss.h>
 #include <android/hardware/gnss/measurement_corrections/1.0/IMeasurementCorrections.h>
 #include <android/hardware/gnss/measurement_corrections/1.1/IMeasurementCorrections.h>
+#include <gtest/gtest.h>
 
 namespace android {
 namespace hardware {
@@ -28,8 +29,9 @@
 namespace common {
 
 struct Utils {
-    static void checkLocation(const V1_0::GnssLocation& location, bool check_speed,
-                              bool check_more_accuracies);
+  public:
+    template <class T>
+    static void checkLocation(const T& location, bool check_speed, bool check_more_accuracies);
     static const measurement_corrections::V1_0::MeasurementCorrections
     getMockMeasurementCorrections();
     static const measurement_corrections::V1_1::MeasurementCorrections
@@ -39,8 +41,80 @@
             V2_0::GnssConstellationType constellation);
 
     static bool isAutomotiveDevice();
+
+  private:
+    template <class T>
+    static int64_t getLocationTimestampMillis(const T&);
 };
 
+template <class T>
+void Utils::checkLocation(const T& location, bool check_speed, bool check_more_accuracies) {
+    EXPECT_TRUE(location.gnssLocationFlags & V1_0::GnssLocationFlags::HAS_LAT_LONG);
+    EXPECT_TRUE(location.gnssLocationFlags & V1_0::GnssLocationFlags::HAS_ALTITUDE);
+    if (check_speed) {
+        EXPECT_TRUE(location.gnssLocationFlags & V1_0::GnssLocationFlags::HAS_SPEED);
+    }
+    EXPECT_TRUE(location.gnssLocationFlags & V1_0::GnssLocationFlags::HAS_HORIZONTAL_ACCURACY);
+    // New uncertainties available in O must be provided,
+    // at least when paired with modern hardware (2017+)
+    if (check_more_accuracies) {
+        EXPECT_TRUE(location.gnssLocationFlags & V1_0::GnssLocationFlags::HAS_VERTICAL_ACCURACY);
+        if (check_speed) {
+            EXPECT_TRUE(location.gnssLocationFlags & V1_0::GnssLocationFlags::HAS_SPEED_ACCURACY);
+            if (location.gnssLocationFlags & V1_0::GnssLocationFlags::HAS_BEARING) {
+                EXPECT_TRUE(location.gnssLocationFlags &
+                            V1_0::GnssLocationFlags::HAS_BEARING_ACCURACY);
+            }
+        }
+    }
+    EXPECT_GE(location.latitudeDegrees, -90.0);
+    EXPECT_LE(location.latitudeDegrees, 90.0);
+    EXPECT_GE(location.longitudeDegrees, -180.0);
+    EXPECT_LE(location.longitudeDegrees, 180.0);
+    EXPECT_GE(location.altitudeMeters, -1000.0);
+    EXPECT_LE(location.altitudeMeters, 30000.0);
+    if (check_speed) {
+        EXPECT_GE(location.speedMetersPerSec, 0.0);
+        EXPECT_LE(location.speedMetersPerSec, 5.0);  // VTS tests are stationary.
+
+        // Non-zero speeds must be reported with an associated bearing
+        if (location.speedMetersPerSec > 0.0) {
+            EXPECT_TRUE(location.gnssLocationFlags & V1_0::GnssLocationFlags::HAS_BEARING);
+        }
+    }
+
+    /*
+     * Tolerating some especially high values for accuracy estimate, in case of
+     * first fix with especially poor geometry (happens occasionally)
+     */
+    EXPECT_GT(location.horizontalAccuracyMeters, 0.0);
+    EXPECT_LE(location.horizontalAccuracyMeters, 250.0);
+
+    /*
+     * Some devices may define bearing as -180 to +180, others as 0 to 360.
+     * Both are okay & understandable.
+     */
+    if (location.gnssLocationFlags & V1_0::GnssLocationFlags::HAS_BEARING) {
+        EXPECT_GE(location.bearingDegrees, -180.0);
+        EXPECT_LE(location.bearingDegrees, 360.0);
+    }
+    if (location.gnssLocationFlags & V1_0::GnssLocationFlags::HAS_VERTICAL_ACCURACY) {
+        EXPECT_GT(location.verticalAccuracyMeters, 0.0);
+        EXPECT_LE(location.verticalAccuracyMeters, 500.0);
+    }
+    if (location.gnssLocationFlags & V1_0::GnssLocationFlags::HAS_SPEED_ACCURACY) {
+        EXPECT_GT(location.speedAccuracyMetersPerSecond, 0.0);
+        EXPECT_LE(location.speedAccuracyMetersPerSecond, 50.0);
+    }
+    if (location.gnssLocationFlags & V1_0::GnssLocationFlags::HAS_BEARING_ACCURACY) {
+        EXPECT_GT(location.bearingAccuracyDegrees, 0.0);
+        EXPECT_LE(location.bearingAccuracyDegrees, 360.0);
+    }
+
+    // Check timestamp > 1.48e12 (47 years in msec - 1970->2017+)
+    EXPECT_GT(getLocationTimestampMillis(location), 1.48e12);
+}
+
 }  // namespace common
 }  // namespace gnss
 }  // namespace hardware
diff --git a/gnss/common/utils/vts/include/v2_1/GnssCallback.h b/gnss/common/utils/vts/include/v2_1/GnssCallback.h
index ab1375d..09a67de 100644
--- a/gnss/common/utils/vts/include/v2_1/GnssCallback.h
+++ b/gnss/common/utils/vts/include/v2_1/GnssCallback.h
@@ -28,7 +28,6 @@
 using android::hardware::gnss::common::GnssCallbackEventQueue;
 using android::hardware::gnss::measurement_corrections::V1_0::IMeasurementCorrectionsCallback;
 using android::hardware::gnss::V1_0::GnssLocationFlags;
-using android::hardware::gnss::V2_0::GnssConstellationType;
 
 using GnssLocation_1_0 = android::hardware::gnss::V1_0::GnssLocation;
 using GnssLocation_2_0 = android::hardware::gnss::V2_0::GnssLocation;
diff --git a/graphics/composer/2.1/utils/vts/GraphicsComposerCallback.cpp b/graphics/composer/2.1/utils/vts/GraphicsComposerCallback.cpp
index 1ead138..ccbc5b1 100644
--- a/graphics/composer/2.1/utils/vts/GraphicsComposerCallback.cpp
+++ b/graphics/composer/2.1/utils/vts/GraphicsComposerCallback.cpp
@@ -30,7 +30,7 @@
 
 std::vector<Display> GraphicsComposerCallback::getDisplays() const {
     std::lock_guard<std::mutex> lock(mMutex);
-    return std::vector<Display>(mDisplays.begin(), mDisplays.end());
+    return mDisplays;
 }
 
 int GraphicsComposerCallback::getInvalidHotplugCount() const {
@@ -51,12 +51,17 @@
 Return<void> GraphicsComposerCallback::onHotplug(Display display, Connection connection) {
     std::lock_guard<std::mutex> lock(mMutex);
 
+    auto it = std::find(mDisplays.begin(), mDisplays.end(), display);
     if (connection == Connection::CONNECTED) {
-        if (!mDisplays.insert(display).second) {
+        if (it == mDisplays.end()) {
+            mDisplays.push_back(display);
+        } else {
             mInvalidHotplugCount++;
         }
     } else if (connection == Connection::DISCONNECTED) {
-        if (!mDisplays.erase(display)) {
+        if (it != mDisplays.end()) {
+            mDisplays.erase(it);
+        } else {
             mInvalidHotplugCount++;
         }
     }
@@ -67,7 +72,8 @@
 Return<void> GraphicsComposerCallback::onRefresh(Display display) {
     std::lock_guard<std::mutex> lock(mMutex);
 
-    if (mDisplays.count(display) == 0) {
+    auto it = std::find(mDisplays.begin(), mDisplays.end(), display);
+    if (it == mDisplays.end()) {
         mInvalidRefreshCount++;
     }
 
@@ -77,7 +83,8 @@
 Return<void> GraphicsComposerCallback::onVsync(Display display, int64_t) {
     std::lock_guard<std::mutex> lock(mMutex);
 
-    if (!mVsyncAllowed || mDisplays.count(display) == 0) {
+    auto it = std::find(mDisplays.begin(), mDisplays.end(), display);
+    if (!mVsyncAllowed || it == mDisplays.end()) {
         mInvalidVsyncCount++;
     }
 
diff --git a/graphics/composer/2.1/utils/vts/include/composer-vts/2.1/GraphicsComposerCallback.h b/graphics/composer/2.1/utils/vts/include/composer-vts/2.1/GraphicsComposerCallback.h
index e3c348f..da64052 100644
--- a/graphics/composer/2.1/utils/vts/include/composer-vts/2.1/GraphicsComposerCallback.h
+++ b/graphics/composer/2.1/utils/vts/include/composer-vts/2.1/GraphicsComposerCallback.h
@@ -19,7 +19,7 @@
 #include <android/hardware/graphics/composer/2.1/IComposerCallback.h>
 
 #include <mutex>
-#include <unordered_set>
+#include <vector>
 
 namespace android {
 namespace hardware {
@@ -48,7 +48,7 @@
 
     mutable std::mutex mMutex;
     // the set of all currently connected displays
-    std::unordered_set<Display> mDisplays;
+    std::vector<Display> mDisplays;
     // true only when vsync is enabled
     bool mVsyncAllowed = true;
 
diff --git a/graphics/composer/2.4/utils/vts/GraphicsComposerCallback.cpp b/graphics/composer/2.4/utils/vts/GraphicsComposerCallback.cpp
index c9366a8..51e1ab7 100644
--- a/graphics/composer/2.4/utils/vts/GraphicsComposerCallback.cpp
+++ b/graphics/composer/2.4/utils/vts/GraphicsComposerCallback.cpp
@@ -25,7 +25,7 @@
 
 std::vector<Display> GraphicsComposerCallback::getDisplays() const {
     std::lock_guard<std::mutex> lock(mMutex);
-    return std::vector<Display>(mDisplays.begin(), mDisplays.end());
+    return mDisplays;
 }
 
 int32_t GraphicsComposerCallback::getInvalidHotplugCount() const {
@@ -71,12 +71,17 @@
 Return<void> GraphicsComposerCallback::onHotplug(Display display, Connection connection) {
     std::lock_guard<std::mutex> lock(mMutex);
 
+    auto it = std::find(mDisplays.begin(), mDisplays.end(), display);
     if (connection == Connection::CONNECTED) {
-        if (!mDisplays.insert(display).second) {
+        if (it == mDisplays.end()) {
+            mDisplays.push_back(display);
+        } else {
             mInvalidHotplugCount++;
         }
     } else if (connection == Connection::DISCONNECTED) {
-        if (!mDisplays.erase(display)) {
+        if (it != mDisplays.end()) {
+            mDisplays.erase(it);
+        } else {
             mInvalidHotplugCount++;
         }
     }
@@ -87,7 +92,8 @@
 Return<void> GraphicsComposerCallback::onRefresh(Display display) {
     std::lock_guard<std::mutex> lock(mMutex);
 
-    if (mDisplays.count(display) == 0) {
+    auto it = std::find(mDisplays.begin(), mDisplays.end(), display);
+    if (it == mDisplays.end()) {
         mInvalidRefreshCount++;
     }
 
@@ -106,7 +112,8 @@
 Return<void> GraphicsComposerCallback::onVsync_2_4(Display display, int64_t, VsyncPeriodNanos) {
     std::lock_guard<std::mutex> lock(mMutex);
 
-    if (!mVsyncAllowed || mDisplays.count(display) == 0) {
+    auto it = std::find(mDisplays.begin(), mDisplays.end(), display);
+    if (!mVsyncAllowed || it == mDisplays.end()) {
         mInvalidVsync_2_4Count++;
     }
 
@@ -117,7 +124,8 @@
         Display display, const VsyncPeriodChangeTimeline& updatedTimeline) {
     std::lock_guard<std::mutex> lock(mMutex);
 
-    if (mDisplays.count(display) == 0) {
+    auto it = std::find(mDisplays.begin(), mDisplays.end(), display);
+    if (it == mDisplays.end()) {
         mInvalidVsyncPeriodChangeCount++;
     }
 
@@ -134,4 +142,4 @@
     return Void();
 }
 
-}  // namespace android::hardware::graphics::composer::V2_4::vts
\ No newline at end of file
+}  // namespace android::hardware::graphics::composer::V2_4::vts
diff --git a/graphics/composer/2.4/utils/vts/include/composer-vts/2.4/GraphicsComposerCallback.h b/graphics/composer/2.4/utils/vts/include/composer-vts/2.4/GraphicsComposerCallback.h
index f4e23ae..c03070b 100644
--- a/graphics/composer/2.4/utils/vts/include/composer-vts/2.4/GraphicsComposerCallback.h
+++ b/graphics/composer/2.4/utils/vts/include/composer-vts/2.4/GraphicsComposerCallback.h
@@ -18,7 +18,7 @@
 #include <android/hardware/graphics/composer/2.4/IComposerCallback.h>
 
 #include <mutex>
-#include <unordered_set>
+#include <vector>
 
 namespace android::hardware::graphics::composer::V2_4::vts {
 
@@ -56,7 +56,7 @@
 
     mutable std::mutex mMutex;
     // the set of all currently connected displays
-    std::unordered_set<Display> mDisplays;
+    std::vector<Display> mDisplays;
     // true only when vsync is enabled
     bool mVsyncAllowed = true;
 
diff --git a/graphics/composer/aidl/Android.bp b/graphics/composer/aidl/Android.bp
index 5f5b54e..2532a7a 100644
--- a/graphics/composer/aidl/Android.bp
+++ b/graphics/composer/aidl/Android.bp
@@ -55,20 +55,6 @@
     },
 }
 
-cc_library {
-    name: "android.hardware.graphics.composer3-translate-ndk",
-    vendor_available: true,
-    srcs: ["android/hardware/graphics/composer3/translate-ndk.cpp"],
-    shared_libs: [
-        "libbinder_ndk",
-        "libhidlbase",
-        "android.hardware.graphics.composer3-V1-ndk",
-        "android.hardware.graphics.composer@2.1",
-        "android.hardware.graphics.composer@2.4",
-    ],
-    export_include_dirs: ["include"],
-}
-
 cc_library_headers {
     name: "android.hardware.graphics.composer3-command-buffer",
     vendor_available: true,
@@ -88,3 +74,16 @@
     ],
     export_include_dirs: ["include"],
 }
+
+cc_test {
+    name: "android.hardware.graphics.composer3-hidl2aidl-asserts",
+    vendor_available: true,
+    srcs: ["android/hardware/graphics/composer3/Hidl2AidlAsserts.cpp"],
+    shared_libs: [
+        "libbinder_ndk",
+        "libhidlbase",
+        "android.hardware.graphics.composer3-V1-ndk",
+        "android.hardware.graphics.composer@2.1",
+        "android.hardware.graphics.composer@2.4",
+    ],
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/WhitePointNits.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ClockMonotonicTimestamp.aidl
similarity index 96%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/WhitePointNits.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ClockMonotonicTimestamp.aidl
index c3925d2..480a85c 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/WhitePointNits.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ClockMonotonicTimestamp.aidl
@@ -33,6 +33,6 @@
 
 package android.hardware.graphics.composer3;
 @VintfStability
-parcelable WhitePointNits {
-  float nits;
+parcelable ClockMonotonicTimestamp {
+  long timestampNanos;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Color.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Color.aidl
index 7733deb..8222909 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Color.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Color.aidl
@@ -34,8 +34,8 @@
 package android.hardware.graphics.composer3;
 @VintfStability
 parcelable Color {
-  byte r;
-  byte g;
-  byte b;
-  byte a;
+  float r;
+  float g;
+  float b;
+  float a;
 }
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/WhitePointNits.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayBrightness.aidl
similarity index 94%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/WhitePointNits.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayBrightness.aidl
index c3925d2..be623df 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/WhitePointNits.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayBrightness.aidl
@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2021, The Android Open Source Project
+ * 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.
@@ -33,6 +33,6 @@
 
 package android.hardware.graphics.composer3;
 @VintfStability
-parcelable WhitePointNits {
-  float nits;
+parcelable DisplayBrightness {
+  float brightness;
 }
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 9f5342e..fdf1100 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
@@ -41,4 +41,5 @@
   PROTECTED_CONTENTS = 4,
   AUTO_LOW_LATENCY_MODE = 5,
   SUSPEND = 6,
+  DISPLAY_DECORATION = 7,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayCommand.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayCommand.aidl
index 2f5d00f..662240e 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayCommand.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayCommand.aidl
@@ -36,9 +36,11 @@
 parcelable DisplayCommand {
   long display;
   android.hardware.graphics.composer3.LayerCommand[] layers;
-  @nullable android.hardware.graphics.composer3.ColorTransformPayload colorTransform;
+  @nullable float[] colorTransformMatrix;
+  @nullable android.hardware.graphics.composer3.DisplayBrightness brightness;
   @nullable android.hardware.graphics.composer3.ClientTarget clientTarget;
   @nullable android.hardware.graphics.composer3.Buffer virtualDisplayOutputBuffer;
+  @nullable android.hardware.graphics.composer3.ClockMonotonicTimestamp expectedPresentTime;
   boolean validateDisplay;
   boolean acceptDisplayChanges;
   boolean presentDisplay;
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/GenericMetadata.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/GenericMetadata.aidl
deleted file mode 100644
index c18529b..0000000
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/GenericMetadata.aidl
+++ /dev/null
@@ -1,39 +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;
-@VintfStability
-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 2bdbc9f..e9d9745 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
@@ -52,11 +52,10 @@
   android.hardware.graphics.composer3.DisplayContentSample getDisplayedContentSample(long display, long maxFrames, long timestamp);
   android.hardware.graphics.composer3.DisplayContentSamplingAttributes getDisplayedContentSamplingAttributes(long display);
   android.hardware.graphics.composer3.HdrCapabilities getHdrCapabilities(long display);
-  android.hardware.graphics.composer3.LayerGenericMetadataKey[] getLayerGenericMetadataKeys();
   int getMaxVirtualDisplayCount();
   android.hardware.graphics.composer3.PerFrameMetadataKey[] getPerFrameMetadataKeys(long display);
   android.hardware.graphics.composer3.ReadbackBufferAttributes getReadbackBufferAttributes(long display);
-  ParcelFileDescriptor getReadbackBufferFence(long display);
+  @nullable ParcelFileDescriptor getReadbackBufferFence(long display);
   android.hardware.graphics.composer3.RenderIntent[] getRenderIntents(long display, android.hardware.graphics.composer3.ColorMode mode);
   android.hardware.graphics.composer3.ContentType[] getSupportedContentTypes(long display);
   void registerCallback(in android.hardware.graphics.composer3.IComposerCallback callback);
@@ -66,10 +65,9 @@
   void setClientTargetSlotCount(long display, int clientTargetSlotCount);
   void setColorMode(long display, android.hardware.graphics.composer3.ColorMode mode, android.hardware.graphics.composer3.RenderIntent intent);
   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 setPowerMode(long display, android.hardware.graphics.composer3.PowerMode mode);
-  void setReadbackBuffer(long display, in android.hardware.common.NativeHandle buffer, in ParcelFileDescriptor releaseFence);
+  void setReadbackBuffer(long display, in android.hardware.common.NativeHandle buffer, in @nullable ParcelFileDescriptor releaseFence);
   void setVsyncEnabled(long display, boolean enabled);
   const int EX_BAD_CONFIG = 1;
   const int EX_BAD_DISPLAY = 2;
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
index bad72fc..c1c0117 100644
--- 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
@@ -40,7 +40,6 @@
   @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;
@@ -51,8 +50,8 @@
   @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.Luminance whitePointNits;
   @nullable android.hardware.graphics.composer3.PerFrameMetadata[] perFrameMetadata;
   @nullable android.hardware.graphics.composer3.PerFrameMetadataBlob[] perFrameMetadataBlob;
+  @nullable android.hardware.graphics.common.Rect[] blockingRegion;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/WhitePointNits.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Luminance.aidl
similarity index 98%
rename from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/WhitePointNits.aidl
rename to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Luminance.aidl
index c3925d2..adb49a8 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/WhitePointNits.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Luminance.aidl
@@ -33,6 +33,6 @@
 
 package android.hardware.graphics.composer3;
 @VintfStability
-parcelable WhitePointNits {
+parcelable Luminance {
   float nits;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/PresentOrValidate.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/PresentOrValidate.aidl
index 3514e53..e6ddeba 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/PresentOrValidate.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/PresentOrValidate.aidl
@@ -38,7 +38,7 @@
   android.hardware.graphics.composer3.PresentOrValidate.Result result;
   @VintfStability
   enum Result {
-    Presented = 0,
-    Validated = 1,
+    Validated = 0,
+    Presented = 1,
   }
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/ClockMonotonicTimestamp.aidl
similarity index 81%
rename from graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
rename to graphics/composer/aidl/android/hardware/graphics/composer3/ClockMonotonicTimestamp.aidl
index a0a1d4b..0cfd1c4 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/ClockMonotonicTimestamp.aidl
@@ -17,13 +17,9 @@
 package android.hardware.graphics.composer3;
 
 /**
- * Color representation as a floating point number in the range [0.0 - 1.0]
+ * Represents a nanoseconds timestamp in CLOCK_MONOTONIC.
  */
-
 @VintfStability
-parcelable FloatColor {
-    float r;
-    float g;
-    float b;
-    float a;
+parcelable ClockMonotonicTimestamp {
+    long timestampNanos;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/Color.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/Color.aidl
index 979f677..151a854 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/Color.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/Color.aidl
@@ -16,10 +16,13 @@
 
 package android.hardware.graphics.composer3;
 
+/**
+ * Color representation as a floating point number in the range [0.0 - 1.0]
+ */
 @VintfStability
 parcelable Color {
-    byte r;
-    byte g;
-    byte b;
-    byte a;
+    float r;
+    float g;
+    float b;
+    float a;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/ColorTransformPayload.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/ColorTransformPayload.aidl
deleted file mode 100644
index 8bb0711..0000000
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/ColorTransformPayload.aidl
+++ /dev/null
@@ -1,33 +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.common.ColorTransform;
-
-@VintfStability
-parcelable ColorTransformPayload {
-    /**
-     * 4x4 transform matrix (16 floats) as described in DisplayCommand.colorTransform.
-     */
-    float[] matrix;
-
-    /**
-     * Hint value which may be used instead of the given matrix unless it
-     * is ColorTransform::ARBITRARY.
-     */
-    ColorTransform hint;
-}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/Composition.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/Composition.aidl
index ea22af2..803de06 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/Composition.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/Composition.aidl
@@ -66,11 +66,25 @@
     /**
      * 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 used to provide
+     * anti-aliasing on the cutout region/rounded corners on the top and
+     * bottom of a display.
+     *
+     * Pixels in the buffer with an alpha of 0 (transparent) will show the
+     * content underneath, and pixels with a max alpha value will be rendered in
+     * black. An alpha in between will show the underlying content blended with
+     * black.
+     *
+     * Upon validateDisplay, the device may request a change from this type
+     * to either DEVICE or CLIENT.
+     */
+    DISPLAY_DECORATION = 6,
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayBrightness.aidl
similarity index 71%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
copy to graphics/composer/aidl/android/hardware/graphics/composer3/DisplayBrightness.aidl
index a0a1d4b..f66b235 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayBrightness.aidl
@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2021, The Android Open Source Project
+ * 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.
@@ -16,14 +16,11 @@
 
 package android.hardware.graphics.composer3;
 
-/**
- * Color representation as a floating point number in the range [0.0 - 1.0]
- */
-
 @VintfStability
-parcelable FloatColor {
-    float r;
-    float g;
-    float b;
-    float a;
+parcelable DisplayBrightness {
+    /**
+     * A number between 0.0f (minimum brightness) and 1.0f (maximum brightness), a negative value to
+     * turn the backlight off.
+     */
+    float brightness;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCapability.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCapability.aidl
index bfaa15b..249fed0 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCapability.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCapability.aidl
@@ -41,15 +41,15 @@
      */
     SKIP_CLIENT_COLOR_TRANSFORM = 1,
     /**
-     * Indicates that the display supports PowerMode::DOZE and
-     * potentially PowerMode::DOZE_SUSPEND if DisplayCapability.SUSPEND is also
+     * 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,
     /**
@@ -75,4 +75,8 @@
      * PowerMode.ON_SUSPEND and PowerMode.DOZE_SUSPEND must be supported.
      */
     SUSPEND = 6,
+    /**
+     * Indicates that the display supports Composition.DISPLAY_DECORATION.
+     */
+    DISPLAY_DECORATION = 7,
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCommand.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCommand.aidl
index cdc4759..f1ce1a7 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCommand.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCommand.aidl
@@ -18,7 +18,8 @@
 
 import android.hardware.graphics.composer3.Buffer;
 import android.hardware.graphics.composer3.ClientTarget;
-import android.hardware.graphics.composer3.ColorTransformPayload;
+import android.hardware.graphics.composer3.ClockMonotonicTimestamp;
+import android.hardware.graphics.composer3.DisplayBrightness;
 import android.hardware.graphics.composer3.LayerCommand;
 
 @VintfStability
@@ -38,15 +39,11 @@
     /**
      * 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
+     * If the device is not capable of either using 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
+     * 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.
      *
@@ -70,13 +67,36 @@
      * B_out = R_in * r.b + G_in * g.b + B_in * b.b + Tb
      *
      */
-    @nullable ColorTransformPayload colorTransform;
+    @nullable float[] colorTransformMatrix;
+
+    /**
+     * Sets the desired brightness of the display.
+     *
+     * Ideally, the brightness of the display will take effect within this frame so that it can be
+     * aligned with color transforms. Some display architectures may take multiple frames to apply
+     * the display brightness, for example when internally switching the display between multiple
+     * power modes to achieve higher luminance. In those cases, the underlying display panel's real
+     * brightness may not be applied atomically; however, layer dimming when mixing HDR and SDR
+     * content must be synchronized.
+     *
+     * As an illustrative example: suppose two layers have white
+     * points of 200 nits and 1000 nits respectively, the old display luminance is 200 nits, and the
+     * new display luminance is 1000 nits. If the new display luminance takes two frames to apply,
+     * then: In the first frame, there must not be any relative dimming of layers (treat both layers
+     * as 200 nits as the maximum luminance of the display is 200 nits). In the second frame, there
+     * dimming should be applied to ensure that the first layer does not become perceptually
+     * brighter during the transition.
+     *
+     * The display luminance must be updated by this command even if there is not pending validate
+     * or present command.
+     */
+    @nullable DisplayBrightness brightness;
 
     /**
      * Sets the buffer handle which will receive the output of client
-     * composition.  Layers marked as Composition::CLIENT must be composited
+     * 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
+     * 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
@@ -94,7 +114,7 @@
      * 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
+     * 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.
      */
@@ -115,6 +135,14 @@
     @nullable Buffer virtualDisplayOutputBuffer;
 
     /**
+     * Sets the expected present time to present the current content on screen.
+     * The implementation should try to present the display as close as possible
+     * to the given expectedPresentTime. If expectedPresentTime is 0, the
+     * implementation should present the display as soon as possible.
+     */
+    @nullable ClockMonotonicTimestamp expectedPresentTime;
+
+    /**
      * 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
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayRequest.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayRequest.aidl
index ea7745d..27fe1e6 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayRequest.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayRequest.aidl
@@ -27,7 +27,7 @@
     /**
      * 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.
      */
     const int WRITE_CLIENT_TARGET_TO_OUTPUT = 1 << 1;
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/GenericMetadata.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/GenericMetadata.aidl
deleted file mode 100644
index d0254dd..0000000
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/GenericMetadata.aidl
+++ /dev/null
@@ -1,33 +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.LayerGenericMetadataKey;
-
-@VintfStability
-parcelable GenericMetadata {
-    /**
-     * Indicates which metadata value should be set.
-     */
-    LayerGenericMetadataKey key;
-    /**
-     * The binary representation of a AIDL struct corresponding to
-     * the key as described above.
-     * TODO(b/209691612): revisit the use of byte[]
-     */
-    byte[] value;
-}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/translate-ndk.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/Hidl2AidlAsserts.cpp
similarity index 78%
rename from graphics/composer/aidl/android/hardware/graphics/composer3/translate-ndk.cpp
rename to graphics/composer/aidl/android/hardware/graphics/composer3/Hidl2AidlAsserts.cpp
index a3c8176..d2cabff 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/translate-ndk.cpp
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/Hidl2AidlAsserts.cpp
@@ -14,7 +14,32 @@
  * limitations under the License.
  */
 
-#include "android/hardware/graphics/composer3/translate-ndk.h"
+#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/Capability.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/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/FormatColorComponent.h"
+#include "aidl/android/hardware/graphics/composer3/IComposer.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"
+#include "aidl/android/hardware/graphics/composer3/PowerMode.h"
+#include "aidl/android/hardware/graphics/composer3/VsyncPeriodChangeConstraints.h"
+#include "aidl/android/hardware/graphics/composer3/VsyncPeriodChangeTimeline.h"
+#include "android/hardware/graphics/composer/2.1/IComposer.h"
+#include "android/hardware/graphics/composer/2.1/IComposerCallback.h"
+#include "android/hardware/graphics/composer/2.1/IComposerClient.h"
+#include "android/hardware/graphics/composer/2.2/IComposerClient.h"
+#include "android/hardware/graphics/composer/2.3/IComposerClient.h"
+#include "android/hardware/graphics/composer/2.4/IComposerClient.h"
+#include "android/hardware/graphics/composer/2.4/types.h"
 
 namespace android::h2a {
 
@@ -129,15 +154,6 @@
               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>(
-                      ::android::hardware::graphics::composer::V2_1::IComposerClient::HandleIndex::
-                              EMPTY));
-static_assert(aidl::android::hardware::graphics::composer3::HandleIndex::CACHED ==
-              static_cast<aidl::android::hardware::graphics::composer3::HandleIndex>(
-                      ::android::hardware::graphics::composer::V2_1::IComposerClient::HandleIndex::
-                              CACHED));
-
 static_assert(
         aidl::android::hardware::graphics::composer3::PowerMode::OFF ==
         static_cast<aidl::android::hardware::graphics::composer3::PowerMode>(
@@ -327,131 +343,11 @@
         static_cast<aidl::android::hardware::graphics::composer3::ContentType>(
                 ::android::hardware::graphics::composer::V2_4::IComposerClient::ContentType::GAME));
 
-__attribute__((warn_unused_result)) bool translate(
-        const ::android::hardware::graphics::composer::V2_4::VsyncPeriodChangeTimeline& in,
-        aidl::android::hardware::graphics::composer3::VsyncPeriodChangeTimeline* out) {
-    out->newVsyncAppliedTimeNanos = static_cast<int64_t>(in.newVsyncAppliedTimeNanos);
-    out->refreshRequired = static_cast<bool>(in.refreshRequired);
-    out->refreshTimeNanos = static_cast<int64_t>(in.refreshTimeNanos);
-    return true;
-}
-
-__attribute__((warn_unused_result)) bool translate(
-        const ::android::hardware::graphics::composer::V2_1::IComposerClient::Rect& in,
-        aidl::android::hardware::graphics::common::Rect* out) {
-    out->left = static_cast<int32_t>(in.left);
-    out->top = static_cast<int32_t>(in.top);
-    out->right = static_cast<int32_t>(in.right);
-    out->bottom = static_cast<int32_t>(in.bottom);
-    return true;
-}
-
-__attribute__((warn_unused_result)) bool translate(
-        const ::android::hardware::graphics::composer::V2_1::IComposerClient::FRect& in,
-        aidl::android::hardware::graphics::common::FRect* out) {
-    out->left = static_cast<float>(in.left);
-    out->top = static_cast<float>(in.top);
-    out->right = static_cast<float>(in.right);
-    out->bottom = static_cast<float>(in.bottom);
-    return true;
-}
-
-__attribute__((warn_unused_result)) bool translate(
-        const ::android::hardware::graphics::composer::V2_1::IComposerClient::Color& in,
-        aidl::android::hardware::graphics::composer3::Color* out) {
-    // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit
-    // your needs.
-    if (in.r > std::numeric_limits<int8_t>::max() || in.r < 0) {
-        return false;
-    }
-    out->r = static_cast<int8_t>(in.r);
-    // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit
-    // your needs.
-    if (in.g > std::numeric_limits<int8_t>::max() || in.g < 0) {
-        return false;
-    }
-    out->g = static_cast<int8_t>(in.g);
-    // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit
-    // your needs.
-    if (in.b > std::numeric_limits<int8_t>::max() || in.b < 0) {
-        return false;
-    }
-    out->b = static_cast<int8_t>(in.b);
-    // FIXME This requires conversion between signed and unsigned. Change this if it doesn't suit
-    // your needs.
-    if (in.a > std::numeric_limits<int8_t>::max() || in.a < 0) {
-        return false;
-    }
-    out->a = static_cast<int8_t>(in.a);
-    return true;
-}
-
-__attribute__((warn_unused_result)) bool translate(
-        const ::android::hardware::graphics::composer::V2_3::IComposerClient::PerFrameMetadata& in,
-        aidl::android::hardware::graphics::composer3::PerFrameMetadata* out) {
-    out->key =
-            static_cast<aidl::android::hardware::graphics::composer3::PerFrameMetadataKey>(in.key);
-    out->value = static_cast<float>(in.value);
-    return true;
-}
-
-__attribute__((warn_unused_result)) bool translate(
-        const ::android::hardware::graphics::composer::V2_2::IComposerClient::FloatColor& in,
-        aidl::android::hardware::graphics::composer3::FloatColor* out) {
-    out->r = static_cast<float>(in.r);
-    out->g = static_cast<float>(in.g);
-    out->b = static_cast<float>(in.b);
-    out->a = static_cast<float>(in.a);
-    return true;
-}
-
-__attribute__((warn_unused_result)) bool translate(
-        const ::android::hardware::graphics::composer::V2_3::IComposerClient::PerFrameMetadataBlob&
-                in,
-        aidl::android::hardware::graphics::composer3::PerFrameMetadataBlob* out) {
-    out->key =
-            static_cast<aidl::android::hardware::graphics::composer3::PerFrameMetadataKey>(in.key);
-    {
-        size_t size = in.blob.size();
-        for (size_t i = 0; i < size; i++) {
-            // FIXME This requires conversion between signed and unsigned. Change this if it doesn't
-            // suit your needs.
-            if (in.blob[i] > std::numeric_limits<int8_t>::max() || in.blob[i] < 0) {
-                return false;
-            }
-            out->blob.push_back(static_cast<int8_t>(in.blob[i]));
-        }
-    }
-    return true;
-}
-
-__attribute__((warn_unused_result)) bool translate(
-        const ::android::hardware::graphics::composer::V2_4::IComposerClient::
-                VsyncPeriodChangeConstraints& in,
-        aidl::android::hardware::graphics::composer3::VsyncPeriodChangeConstraints* out) {
-    out->desiredTimeNanos = static_cast<int64_t>(in.desiredTimeNanos);
-    out->seamlessRequired = static_cast<bool>(in.seamlessRequired);
-    return true;
-}
-
-__attribute__((warn_unused_result)) bool translate(
-        const ::android::hardware::graphics::composer::V2_4::IComposerClient::ClientTargetProperty&
-                in,
-        aidl::android::hardware::graphics::composer3::ClientTargetProperty* out) {
-    out->pixelFormat =
-            static_cast<aidl::android::hardware::graphics::common::PixelFormat>(in.pixelFormat);
-    out->dataspace =
-            static_cast<aidl::android::hardware::graphics::common::Dataspace>(in.dataspace);
-    return true;
-}
-
-__attribute__((warn_unused_result)) bool translate(
-        const ::android::hardware::graphics::composer::V2_4::IComposerClient::
-                LayerGenericMetadataKey& in,
-        aidl::android::hardware::graphics::composer3::LayerGenericMetadataKey* out) {
-    out->name = in.name;
-    out->mandatory = static_cast<bool>(in.mandatory);
-    return true;
-}
+static_assert(
+        aidl::android::hardware::graphics::composer3::PresentOrValidate::Result::Presented ==
+        static_cast<aidl::android::hardware::graphics::composer3::PresentOrValidate::Result>(1));
+static_assert(
+        aidl::android::hardware::graphics::composer3::PresentOrValidate::Result::Validated ==
+        static_cast<aidl::android::hardware::graphics::composer3::PresentOrValidate::Result>(0));
 
 }  // namespace android::h2a
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 b89b4c4..3ab6329 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl
@@ -30,7 +30,6 @@
 import android.hardware.graphics.composer3.FormatColorComponent;
 import android.hardware.graphics.composer3.HdrCapabilities;
 import android.hardware.graphics.composer3.IComposerCallback;
-import android.hardware.graphics.composer3.LayerGenericMetadataKey;
 import android.hardware.graphics.composer3.PerFrameMetadataKey;
 import android.hardware.graphics.composer3.PowerMode;
 import android.hardware.graphics.composer3.ReadbackBufferAttributes;
@@ -185,7 +184,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.
      *
@@ -201,7 +200,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.
      *
@@ -369,20 +368,6 @@
     HdrCapabilities getHdrCapabilities(long display);
 
     /**
-     * Retrieves the set of keys that may be passed into setLayerGenericMetadata
-     *
-     * Key names must meet the following requirements:
-     * - Must be specified in reverse domain name notation
-     * - Must not start with 'com.android' or 'android'
-     * - Must be unique within the returned vector
-     * - Must correspond to a matching HIDL struct type, which defines the
-     *   structure of its values. For example, the key 'com.example.V1-3.Foo'
-     *   should correspond to a value of type com.example@1.3::Foo, which is
-     *   defined in a vendor HAL extension
-     */
-    LayerGenericMetadataKey[] getLayerGenericMetadataKeys();
-
-    /**
      * Returns the maximum number of virtual displays supported by this device
      * (which may be 0). The client must not attempt to create more than this
      * many virtual displays on this device. This number must not change for
@@ -409,8 +394,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
@@ -479,14 +464,14 @@
      *   getReadbackBufferAttributes
      *   setReadbackBuffer
      */
-    ParcelFileDescriptor getReadbackBufferFence(long display);
+    @nullable ParcelFileDescriptor getReadbackBufferFence(long display);
 
     /**
      * 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.
@@ -500,11 +485,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.
      *
@@ -571,7 +556,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
@@ -595,8 +580,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.
@@ -631,25 +616,6 @@
     void setContentType(long display, ContentType type);
 
     /**
-     * Sets the brightness of a display.
-     *
-     * Ideally, the brightness change should take effect in the next frame post (so that it can be
-     * aligned with color transforms).
-     *
-     * @param display
-     *      The display whose brightness is set.
-     * @param brightness
-     *      A number between 0.0f (minimum brightness) and 1.0f (maximum brightness), or -1.0 to
-     *      turn the backlight off.
-     *
-     * @exception EX_BAD_DISPLAY   when the display is invalid, or
-     * @exception EX_UNSUPPORTED   when brightness operations are not supported, or
-     * @exception EX_BAD_PARAMETER when the brightness is invalid, or
-     * @exception EX_NO_RESOURCES  when the brightness cannot be applied.
-     */
-    void setDisplayBrightness(long display, float brightness);
-
-    /**
      * Enables or disables the collection of color content statistics
      * on this display.
      *
@@ -682,8 +648,8 @@
      * 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.
@@ -702,13 +668,15 @@
      * This buffer must have been allocated as described in
      * getReadbackBufferAttributes and is in the dataspace provided by the same.
      *
+     * Also provides a file descriptor referring to a release sync fence
+     * object, which must be signaled when it is safe to write to the readback
+     * buffer. If it is already safe to write to the readback buffer, null may be passed instead.
+     *
      * If there is hardware protected content on the display at the time of the next
      * composition, the area of the readback buffer covered by such content must be
      * completely black. Any areas of the buffer not covered by such content may
      * optionally be black as well.
      *
-     * The release fence file descriptor provided works identically to the one
-     * described for setOutputBuffer.
      *
      * This function must not be called between any call to validateDisplay and a
      * subsequent call to presentDisplay.
@@ -716,7 +684,8 @@
      * Parameters:
      * @param display - the display on which to create the layer.
      * @param buffer - the new readback buffer
-     * @param releaseFence - a sync fence file descriptor as described in setOutputBuffer
+     * @param releaseFence - a sync fence file descriptor as described above or null if it is
+     *                       already safe to write to the readback buffer.
      *
      * @exception EX_BAD_DISPLAY - an invalid display handle was passed in
      * @exception EX_BAD_PARAMETER - the new readback buffer handle was invalid
@@ -726,7 +695,7 @@
      *   getReadbackBufferFence
      */
     void setReadbackBuffer(long display, in android.hardware.common.NativeHandle buffer,
-            in ParcelFileDescriptor releaseFence);
+            in @nullable ParcelFileDescriptor releaseFence);
 
     /**
      * Enables or disables the vsync signal for the given display. Virtual
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl
index 130e3b1..0a2711b 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl
@@ -22,8 +22,7 @@
 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.Luminance;
 import android.hardware.graphics.composer3.ParcelableBlendMode;
 import android.hardware.graphics.composer3.ParcelableComposition;
 import android.hardware.graphics.composer3.ParcelableDataspace;
@@ -31,7 +30,6 @@
 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
@@ -45,7 +43,7 @@
     /**
      * Asynchronously sets the position of a cursor layer.
      *
-     * Prior to validateDisplay, a layer may be marked as Composition::CURSOR.
+     * 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
@@ -73,8 +71,8 @@
      * 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
+     * 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).
      */
@@ -109,19 +107,12 @@
 
     /**
      * 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
+     * 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
@@ -149,20 +140,20 @@
      * 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)
+     *   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.
+     * 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
+     * given layer is not Composition.SIDEBAND, this call must succeed and
      * have no other effect.
      */
     @nullable NativeHandle sidebandStream;
@@ -174,7 +165,7 @@
      *
      * 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
+     * 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
@@ -244,34 +235,7 @@
      * 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;
+    @nullable Luminance whitePointNits;
 
     /**
      * Sets the PerFrameMetadata for the display. This metadata must be used
@@ -292,4 +256,15 @@
      * This command may be called every frame.
      */
     @nullable PerFrameMetadataBlob[] perFrameMetadataBlob;
+
+    /**
+     * Specifies a region of the layer that is transparent and may be skipped
+     * by the DPU, e.g. using a blocking region, in order to save power. This
+     * is only a hint, so the composition of the layer must look the same
+     * whether or not this region is skipped.
+     *
+     * The region is in screen space and must not exceed the dimensions of
+     * the screen.
+     */
+    @nullable Rect[] blockingRegion;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerGenericMetadataKey.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/LayerGenericMetadataKey.aidl
deleted file mode 100644
index 17704b8..0000000
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerGenericMetadataKey.aidl
+++ /dev/null
@@ -1,31 +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;
-
-@VintfStability
-parcelable LayerGenericMetadataKey {
-    /**
-     * Key names must comply with the requirements specified for
-     * getLayerGenericMetadataKeys below
-     */
-    String name;
-    /**
-     * The mandatory flag is defined in the description of
-     * setLayerGenericMetadata above
-     */
-    boolean mandatory;
-}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/Luminance.aidl
similarity index 80%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
copy to graphics/composer/aidl/android/hardware/graphics/composer3/Luminance.aidl
index a0a1d4b..5b1c1b4 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/Luminance.aidl
@@ -16,14 +16,11 @@
 
 package android.hardware.graphics.composer3;
 
-/**
- * Color representation as a floating point number in the range [0.0 - 1.0]
- */
-
 @VintfStability
-parcelable FloatColor {
-    float r;
-    float g;
-    float b;
-    float a;
+parcelable Luminance {
+    /**
+     * Photometric measure of luminous intensity per unit area of light.
+     * Units are nits, or cd/m^2.
+     */
+    float nits;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/PresentOrValidate.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/PresentOrValidate.aidl
index f3153bd..5ae8940 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/PresentOrValidate.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/PresentOrValidate.aidl
@@ -27,6 +27,6 @@
     /**
      * Whether PresentOrValidate presented or validated the display.
      */
-    @VintfStability enum Result { Presented, Validated }
+    @VintfStability enum Result { Validated, Presented }
     Result result;
 }
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/WhitePointNits.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/WhitePointNits.aidl
deleted file mode 100644
index 2a1d1c6..0000000
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/WhitePointNits.aidl
+++ /dev/null
@@ -1,29 +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;
-
-@VintfStability
-parcelable WhitePointNits {
-    /**
-     * 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.
-     */
-    float nits;
-}
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 8726043..e519221 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
@@ -19,6 +19,7 @@
 #include <aidl/Gtest.h>
 #include <aidl/Vintf.h>
 #include <aidl/android/hardware/graphics/common/BufferUsage.h>
+#include <aidl/android/hardware/graphics/composer3/IComposer.h>
 #include <android/binder_manager.h>
 #include <composer-vts/include/ReadbackVts.h>
 #include <composer-vts/include/RenderEngineVts.h>
@@ -103,13 +104,8 @@
         ASSERT_NO_FATAL_FAILURE(mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::OFF));
         const auto errors = mReader.takeErrors();
         ASSERT_TRUE(mReader.takeErrors().empty());
+        ASSERT_TRUE(mReader.takeChangedCompositionTypes(mPrimaryDisplay).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());
@@ -118,12 +114,14 @@
     }
 
     ::android::sp<::android::GraphicBuffer> allocate() {
+        const auto width = static_cast<uint32_t>(mDisplayWidth);
+        const auto height = static_cast<uint32_t>(mDisplayHeight);
+        const auto usage = static_cast<uint32_t>(common::BufferUsage::CPU_WRITE_OFTEN) |
+                           static_cast<uint32_t>(common::BufferUsage::CPU_READ_OFTEN);
+
         return ::android::sp<::android::GraphicBuffer>::make(
-                mDisplayWidth, mDisplayHeight, ::android::PIXEL_FORMAT_RGBA_8888,
-                /*layerCount*/ 1,
-                static_cast<uint64_t>(static_cast<int>(common::BufferUsage::CPU_WRITE_OFTEN) |
-                                      static_cast<int>(common::BufferUsage::CPU_READ_OFTEN)),
-                "VtsHalGraphicsComposer3_ReadbackTest");
+                width, height, ::android::PIXEL_FORMAT_RGBA_8888,
+                /*layerCount*/ 1u, usage, "VtsHalGraphicsComposer3_ReadbackTest");
     }
 
     void writeLayers(const std::vector<std::shared_ptr<TestLayer>>& layers) {
@@ -141,10 +139,10 @@
         }
 
         std::vector<CommandResultPayload> results;
-        const auto status = mComposerClient->executeCommands(commands, &results);
+        auto status = mComposerClient->executeCommands(commands, &results);
         ASSERT_TRUE(status.isOk()) << "executeCommands failed " << status.getDescription();
 
-        mReader.parse(results);
+        mReader.parse(std::move(results));
         mWriter.reset();
     }
 
@@ -167,8 +165,8 @@
     int32_t mDisplayWidth;
     int32_t mDisplayHeight;
     std::vector<ColorMode> mTestColorModes;
-    CommandWriterBase mWriter;
-    CommandReaderBase mReader;
+    ComposerClientWriter mWriter;
+    ComposerClientReader mReader;
     ::android::sp<::android::GraphicBuffer> mGraphicBuffer;
     std::unique_ptr<TestRenderEngine> mTestRenderEngine;
 
@@ -258,15 +256,11 @@
 
         writeLayers(layers);
         ASSERT_TRUE(mReader.takeErrors().empty());
-        mWriter.validateDisplay(mPrimaryDisplay);
+        mWriter.validateDisplay(mPrimaryDisplay, ComposerClientWriter::kNoTimestamp);
         execute();
         // if hwc cannot handle and asks for composition change,
         // just succeed the test
-        std::vector<int64_t> changedCompositionLayers;
-        std::vector<Composition> changedCompositionTypes;
-        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
-                                            &changedCompositionTypes);
-        if (!changedCompositionLayers.empty()) {
+        if (!mReader.takeChangedCompositionTypes(mPrimaryDisplay).empty()) {
             GTEST_SUCCEED();
             return;
         }
@@ -317,14 +311,10 @@
 
         writeLayers(layers);
         ASSERT_TRUE(mReader.takeErrors().empty());
-        mWriter.validateDisplay(mPrimaryDisplay);
+        mWriter.validateDisplay(mPrimaryDisplay, ComposerClientWriter::kNoTimestamp);
         execute();
 
-        std::vector<int64_t> changedCompositionLayers;
-        std::vector<Composition> changedCompositionTypes;
-        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
-                                            &changedCompositionTypes);
-        if (!changedCompositionLayers.empty()) {
+        if (!mReader.takeChangedCompositionTypes(mPrimaryDisplay).empty()) {
             GTEST_SUCCEED();
             return;
         }
@@ -377,14 +367,10 @@
                                       mDisplayWidth, mDisplayHeight, mPixelFormat, mDataspace);
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
 
-        mWriter.validateDisplay(mPrimaryDisplay);
+        mWriter.validateDisplay(mPrimaryDisplay, ComposerClientWriter::kNoTimestamp);
         execute();
 
-        std::vector<int64_t> changedCompositionLayers;
-        std::vector<Composition> changedCompositionTypes;
-        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
-                                            &changedCompositionTypes);
-        if (!changedCompositionLayers.empty()) {
+        if (!mReader.takeChangedCompositionTypes(mPrimaryDisplay).empty()) {
             GTEST_SUCCEED();
             return;
         }
@@ -433,7 +419,8 @@
         return;
     }
 
-    aidl::android::hardware::common::NativeHandle bufferHandle = ::android::dupToAidl(nullptr);
+    aidl::android::hardware::common::NativeHandle bufferHandle =
+            ::android::dupToAidl(mGraphicBuffer->handle);
     ndk::ScopedFileDescriptor releaseFence = ndk::ScopedFileDescriptor(-1);
     const auto error =
             mComposerClient->setReadbackBuffer(mPrimaryDisplay, bufferHandle, releaseFence);
@@ -492,17 +479,13 @@
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
         writeLayers(layers);
         ASSERT_TRUE(mReader.takeErrors().empty());
-        mWriter.validateDisplay(mPrimaryDisplay);
+        mWriter.validateDisplay(mPrimaryDisplay, ComposerClientWriter::kNoTimestamp);
         execute();
 
-        std::vector<int64_t> changedCompositionLayers;
-        std::vector<Composition> changedCompositionTypes;
-        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
-                                            &changedCompositionTypes);
-        if (!changedCompositionLayers.empty()) {
-            ASSERT_EQ(1, changedCompositionLayers.size());
+        auto changedCompositionTypes = mReader.takeChangedCompositionTypes(mPrimaryDisplay);
+        if (!changedCompositionTypes.empty()) {
             ASSERT_EQ(1, changedCompositionTypes.size());
-            ASSERT_EQ(Composition::CLIENT, changedCompositionTypes[0]);
+            ASSERT_EQ(Composition::CLIENT, changedCompositionTypes[0].composition);
 
             PixelFormat clientFormat = PixelFormat::RGBA_8888;
             auto clientUsage = static_cast<uint32_t>(
@@ -537,9 +520,8 @@
             mWriter.setClientTarget(mPrimaryDisplay, 0, mGraphicBuffer->handle, fenceHandle.get(),
                                     clientDataspace, std::vector<common::Rect>(1, damage));
             execute();
-            mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
-                                                &changedCompositionTypes);
-            ASSERT_TRUE(changedCompositionLayers.empty());
+            changedCompositionTypes = mReader.takeChangedCompositionTypes(mPrimaryDisplay);
+            ASSERT_TRUE(changedCompositionTypes.empty());
         }
         ASSERT_TRUE(mReader.takeErrors().empty());
 
@@ -606,18 +588,15 @@
         clientLayer->setDisplayFrame(clientFrame);
         clientLayer->setZOrder(0);
         clientLayer->write(mWriter);
-        mWriter.validateDisplay(mPrimaryDisplay);
+        mWriter.validateDisplay(mPrimaryDisplay, ComposerClientWriter::kNoTimestamp);
         execute();
 
-        std::vector<int64_t> changedCompositionLayers;
-        std::vector<Composition> changedCompositionTypes;
-        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
-                                            &changedCompositionTypes);
+        auto changedCompositionTypes = mReader.takeChangedCompositionTypes(mPrimaryDisplay);
         if (changedCompositionTypes.size() != 1) {
             continue;
         }
         // create client target buffer
-        ASSERT_EQ(Composition::CLIENT, changedCompositionTypes[0]);
+        ASSERT_EQ(Composition::CLIENT, changedCompositionTypes[0].composition);
         mGraphicBuffer->reallocate(static_cast<uint32_t>(mDisplayWidth),
                                    static_cast<uint32_t>(mDisplayHeight),
                                    static_cast<int32_t>(common::PixelFormat::RGBA_8888),
@@ -642,9 +621,8 @@
         mWriter.setClientTarget(mPrimaryDisplay, 0, mGraphicBuffer->handle, fenceHandle.get(),
                                 clientDataspace, std::vector<common::Rect>(1, clientFrame));
         execute();
-        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
-                                            &changedCompositionTypes);
-        ASSERT_EQ(0, changedCompositionLayers.size());
+        changedCompositionTypes = mReader.takeChangedCompositionTypes(mPrimaryDisplay);
+        ASSERT_TRUE(changedCompositionTypes.empty());
         ASSERT_TRUE(mReader.takeErrors().empty());
 
         mWriter.presentDisplay(mPrimaryDisplay);
@@ -685,13 +663,9 @@
 
         writeLayers(layers);
         ASSERT_TRUE(mReader.takeErrors().empty());
-        mWriter.validateDisplay(mPrimaryDisplay);
+        mWriter.validateDisplay(mPrimaryDisplay, ComposerClientWriter::kNoTimestamp);
         execute();
-        std::vector<int64_t> changedCompositionLayers;
-        std::vector<Composition> changedCompositionTypes;
-        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
-                                            &changedCompositionTypes);
-        if (!changedCompositionLayers.empty()) {
+        if (!mReader.takeChangedCompositionTypes(mPrimaryDisplay).empty()) {
             GTEST_SUCCEED();
             return;
         }
@@ -715,13 +689,10 @@
 
         writeLayers(layers);
         ASSERT_TRUE(mReader.takeErrors().empty());
-        mWriter.validateDisplay(mPrimaryDisplay);
+        mWriter.validateDisplay(mPrimaryDisplay, ComposerClientWriter::kNoTimestamp);
         execute();
         ASSERT_TRUE(mReader.takeErrors().empty());
-        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
-                                            &changedCompositionTypes);
-        ASSERT_TRUE(changedCompositionLayers.empty());
-        ASSERT_TRUE(changedCompositionTypes.empty());
+        ASSERT_TRUE(mReader.takeChangedCompositionTypes(mPrimaryDisplay).empty());
         mWriter.presentDisplay(mPrimaryDisplay);
         execute();
         ASSERT_TRUE(mReader.takeErrors().empty());
@@ -756,13 +727,9 @@
 
         writeLayers(layers);
         ASSERT_TRUE(mReader.takeErrors().empty());
-        mWriter.validateDisplay(mPrimaryDisplay);
+        mWriter.validateDisplay(mPrimaryDisplay, ComposerClientWriter::kNoTimestamp);
         execute();
-        std::vector<int64_t> changedCompositionLayers;
-        std::vector<Composition> changedCompositionTypes;
-        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
-                                            &changedCompositionTypes);
-        if (!changedCompositionLayers.empty()) {
+        if (!mReader.takeChangedCompositionTypes(mPrimaryDisplay).empty()) {
             GTEST_SUCCEED();
             return;
         }
@@ -819,13 +786,9 @@
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
         writeLayers(layers);
         ASSERT_TRUE(mReader.takeErrors().empty());
-        mWriter.validateDisplay(mPrimaryDisplay);
+        mWriter.validateDisplay(mPrimaryDisplay, ComposerClientWriter::kNoTimestamp);
         execute();
-        std::vector<int64_t> changedCompositionLayers;
-        std::vector<Composition> changedCompositionTypes;
-        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
-                                            &changedCompositionTypes);
-        if (!changedCompositionLayers.empty()) {
+        if (!mReader.takeChangedCompositionTypes(mPrimaryDisplay).empty()) {
             GTEST_SUCCEED();
             return;
         }
@@ -877,13 +840,9 @@
 
         writeLayers(layers);
         ASSERT_TRUE(mReader.takeErrors().empty());
-        mWriter.validateDisplay(mPrimaryDisplay);
+        mWriter.validateDisplay(mPrimaryDisplay, ComposerClientWriter::kNoTimestamp);
         execute();
-        std::vector<int64_t> changedCompositionLayers;
-        std::vector<Composition> changedCompositionTypes;
-        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
-                                            &changedCompositionTypes);
-        if (!changedCompositionLayers.empty()) {
+        if (!mReader.takeChangedCompositionTypes(mPrimaryDisplay).empty()) {
             GTEST_SUCCEED();
             return;
         }
@@ -902,12 +861,9 @@
 
         writeLayers(layers);
         ASSERT_TRUE(mReader.takeErrors().empty());
-        mWriter.validateDisplay(mPrimaryDisplay);
+        mWriter.validateDisplay(mPrimaryDisplay, ComposerClientWriter::kNoTimestamp);
         execute();
-        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
-                                            &changedCompositionTypes);
-        ASSERT_TRUE(changedCompositionLayers.empty());
-        ASSERT_TRUE(changedCompositionTypes.empty());
+        ASSERT_TRUE(mReader.takeChangedCompositionTypes(mPrimaryDisplay).empty());
         ASSERT_TRUE(mReader.takeErrors().empty());
         mWriter.presentDisplay(mPrimaryDisplay);
         execute();
@@ -966,35 +922,30 @@
 
         auto layer = mLayers[1];
         BlendMode blendMode = layer->getBlendMode();
-        float alpha = mTopLayerColor.a / 255.0f * layer->getAlpha();
+        float alpha = mTopLayerColor.a * layer->getAlpha();
         if (blendMode == BlendMode::NONE) {
             for (auto& expectedColor : expectedColors) {
-                expectedColor.r = mTopLayerColor.r * static_cast<int8_t>(layer->getAlpha());
-                expectedColor.g = mTopLayerColor.g * static_cast<int8_t>(layer->getAlpha());
-                expectedColor.b = mTopLayerColor.b * static_cast<int8_t>(layer->getAlpha());
-                expectedColor.a = static_cast<int8_t>(alpha * 255.0);
+                expectedColor.r = mTopLayerColor.r * layer->getAlpha();
+                expectedColor.g = mTopLayerColor.g * layer->getAlpha();
+                expectedColor.b = mTopLayerColor.b * layer->getAlpha();
+                expectedColor.a = alpha;
             }
         } else if (blendMode == BlendMode::PREMULTIPLIED) {
             for (auto& expectedColor : expectedColors) {
-                expectedColor.r = static_cast<int8_t>(
-                        mTopLayerColor.r * static_cast<int8_t>(layer->getAlpha()) +
-                        mBackgroundColor.r * (1.0 - alpha));
-                expectedColor.g = static_cast<int8_t>(mTopLayerColor.g * layer->getAlpha() +
-                                                      mBackgroundColor.g * (1.0 - alpha));
-                expectedColor.b = static_cast<int8_t>(mTopLayerColor.b * layer->getAlpha() +
-                                                      mBackgroundColor.b * (1.0 - alpha));
-                expectedColor.a = static_cast<int8_t>(alpha + mBackgroundColor.a * (1.0 - alpha));
+                expectedColor.r =
+                        mTopLayerColor.r * layer->getAlpha() + mBackgroundColor.r * (1.0f - alpha);
+                expectedColor.g =
+                        mTopLayerColor.g * layer->getAlpha() + mBackgroundColor.g * (1.0f - alpha);
+                expectedColor.b =
+                        mTopLayerColor.b * layer->getAlpha() + mBackgroundColor.b * (1.0f - alpha);
+                expectedColor.a = alpha + mBackgroundColor.a * (1.0f - alpha);
             }
         } else if (blendMode == BlendMode::COVERAGE) {
             for (auto& expectedColor : expectedColors) {
-                expectedColor.r = static_cast<int8_t>(mTopLayerColor.r * alpha +
-                                                      mBackgroundColor.r * (1.0 - alpha));
-                expectedColor.g = static_cast<int8_t>(mTopLayerColor.g * alpha +
-                                                      mBackgroundColor.g * (1.0 - alpha));
-                expectedColor.b = static_cast<int8_t>(mTopLayerColor.b * alpha +
-                                                      mBackgroundColor.b * (1.0 - alpha));
-                expectedColor.a = static_cast<int8_t>(mTopLayerColor.a * alpha +
-                                                      mBackgroundColor.a * (1.0 - alpha));
+                expectedColor.r = mTopLayerColor.r * alpha + mBackgroundColor.r * (1.0f - alpha);
+                expectedColor.g = mTopLayerColor.g * alpha + mBackgroundColor.g * (1.0f - alpha);
+                expectedColor.b = mTopLayerColor.b * alpha + mBackgroundColor.b * (1.0f - alpha);
+                expectedColor.a = mTopLayerColor.a * alpha + mBackgroundColor.a * (1.0f - alpha);
             }
         }
     }
@@ -1027,13 +978,9 @@
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
         writeLayers(mLayers);
         ASSERT_TRUE(mReader.takeErrors().empty());
-        mWriter.validateDisplay(mPrimaryDisplay);
+        mWriter.validateDisplay(mPrimaryDisplay, ComposerClientWriter::kNoTimestamp);
         execute();
-        std::vector<int64_t> changedCompositionLayers;
-        std::vector<Composition> changedCompositionTypes;
-        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
-                                            &changedCompositionTypes);
-        if (!changedCompositionLayers.empty()) {
+        if (!mReader.takeChangedCompositionTypes(mPrimaryDisplay).empty()) {
             GTEST_SUCCEED();
             return;
         }
@@ -1072,13 +1019,9 @@
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
         writeLayers(mLayers);
         ASSERT_TRUE(mReader.takeErrors().empty());
-        mWriter.validateDisplay(mPrimaryDisplay);
+        mWriter.validateDisplay(mPrimaryDisplay, ComposerClientWriter::kNoTimestamp);
         execute();
-        std::vector<int64_t> changedCompositionLayers;
-        std::vector<Composition> changedCompositionTypes;
-        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
-                                            &changedCompositionTypes);
-        if (!changedCompositionLayers.empty()) {
+        if (!mReader.takeChangedCompositionTypes(mPrimaryDisplay).empty()) {
             GTEST_SUCCEED();
             return;
         }
@@ -1112,13 +1055,9 @@
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
         writeLayers(mLayers);
         ASSERT_TRUE(mReader.takeErrors().empty());
-        mWriter.validateDisplay(mPrimaryDisplay);
+        mWriter.validateDisplay(mPrimaryDisplay, ComposerClientWriter::kNoTimestamp);
         execute();
-        std::vector<int64_t> changedCompositionLayers;
-        std::vector<Composition> changedCompositionTypes;
-        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
-                                            &changedCompositionTypes);
-        if (!changedCompositionLayers.empty()) {
+        if (!mReader.takeChangedCompositionTypes(mPrimaryDisplay).empty()) {
             GTEST_SUCCEED();
             return;
         }
@@ -1139,7 +1078,7 @@
         GraphicsCompositionTest::SetUp();
 
         auto backgroundLayer = std::make_shared<TestColorLayer>(mComposerClient, mPrimaryDisplay);
-        backgroundLayer->setColor({0, 0, 0, 0});
+        backgroundLayer->setColor({0.0f, 0.0f, 0.0f, 0.0f});
         backgroundLayer->setDisplayFrame({0, 0, mDisplayWidth, mDisplayHeight});
         backgroundLayer->setZOrder(0);
 
@@ -1195,13 +1134,9 @@
 
         writeLayers(mLayers);
         ASSERT_TRUE(mReader.takeErrors().empty());
-        mWriter.validateDisplay(mPrimaryDisplay);
+        mWriter.validateDisplay(mPrimaryDisplay, ComposerClientWriter::kNoTimestamp);
         execute();
-        std::vector<int64_t> changedCompositionLayers;
-        std::vector<Composition> changedCompositionTypes;
-        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
-                                            &changedCompositionTypes);
-        if (!changedCompositionLayers.empty()) {
+        if (!mReader.takeChangedCompositionTypes(mPrimaryDisplay).empty()) {
             GTEST_SUCCEED();
             return;
         }
@@ -1241,13 +1176,9 @@
 
         writeLayers(mLayers);
         ASSERT_TRUE(mReader.takeErrors().empty());
-        mWriter.validateDisplay(mPrimaryDisplay);
+        mWriter.validateDisplay(mPrimaryDisplay, ComposerClientWriter::kNoTimestamp);
         execute();
-        std::vector<int64_t> changedCompositionLayers;
-        std::vector<Composition> changedCompositionTypes;
-        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &changedCompositionLayers,
-                                            &changedCompositionTypes);
-        if (!changedCompositionLayers.empty()) {
+        if (!mReader.takeChangedCompositionTypes(mPrimaryDisplay).empty()) {
             GTEST_SUCCEED();
             return;
         }
@@ -1287,12 +1218,9 @@
 
         writeLayers(mLayers);
         ASSERT_TRUE(mReader.takeErrors().empty());
-        mWriter.validateDisplay(mPrimaryDisplay);
+        mWriter.validateDisplay(mPrimaryDisplay, ComposerClientWriter::kNoTimestamp);
         execute();
-        std::vector<int64_t> layers;
-        std::vector<Composition> types;
-        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &layers, &types);
-        if (!layers.empty()) {
+        if (!mReader.takeChangedCompositionTypes(mPrimaryDisplay).empty()) {
             GTEST_SUCCEED();
             return;
         }
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 20fffa9..829b0ff 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
@@ -13,9 +13,11 @@
 #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/Fence.h>
 #include <ui/GraphicBuffer.h>
 #include <ui/PixelFormat.h>
 #include <algorithm>
@@ -566,37 +568,6 @@
     }
 }
 
-/*
- * Test that if brightness operations are supported, setDisplayBrightness works as expected.
- */
-TEST_P(GraphicsComposerAidlTest, setDisplayBrightness) {
-    std::vector<DisplayCapability> capabilities;
-    auto error = mComposerClient->getDisplayCapabilities(mPrimaryDisplay, &capabilities);
-    ASSERT_TRUE(error.isOk());
-    bool brightnessSupport = std::find(capabilities.begin(), capabilities.end(),
-                                       DisplayCapability::BRIGHTNESS) != capabilities.end();
-    if (!brightnessSupport) {
-        EXPECT_EQ(mComposerClient->setDisplayBrightness(mPrimaryDisplay, 0.5f)
-                          .getServiceSpecificError(),
-                  IComposerClient::EX_UNSUPPORTED);
-        GTEST_SUCCEED() << "Brightness operations are not supported";
-        return;
-    }
-
-    EXPECT_TRUE(mComposerClient->setDisplayBrightness(mPrimaryDisplay, 0.0f).isOk());
-    EXPECT_TRUE(mComposerClient->setDisplayBrightness(mPrimaryDisplay, 0.5f).isOk());
-    EXPECT_TRUE(mComposerClient->setDisplayBrightness(mPrimaryDisplay, 1.0f).isOk());
-    EXPECT_TRUE(mComposerClient->setDisplayBrightness(mPrimaryDisplay, -1.0f).isOk());
-
-    error = mComposerClient->setDisplayBrightness(mPrimaryDisplay, +2.0f);
-    EXPECT_FALSE(error.isOk());
-    EXPECT_EQ(error.getServiceSpecificError(), IComposerClient::EX_BAD_PARAMETER);
-
-    error = mComposerClient->setDisplayBrightness(mPrimaryDisplay, -2.0f);
-    EXPECT_FALSE(error.isOk());
-    EXPECT_EQ(error.getServiceSpecificError(), IComposerClient::EX_BAD_PARAMETER);
-}
-
 TEST_P(GraphicsComposerAidlTest, getDisplayConnectionType) {
     DisplayConnectionType type;
     EXPECT_FALSE(mComposerClient->getDisplayConnectionType(mInvalidDisplayId, &type).isOk());
@@ -839,28 +810,6 @@
     Test_setContentType(ContentType::GAME, "GAME");
 }
 
-TEST_P(GraphicsComposerAidlTest, getLayerGenericMetadataKeys) {
-    std::vector<LayerGenericMetadataKey> keys;
-    EXPECT_TRUE(mComposerClient->getLayerGenericMetadataKeys(&keys).isOk());
-
-    std::regex reverseDomainName("^[a-zA-Z-]{2,}(\\.[a-zA-Z0-9-]+)+$");
-    std::unordered_set<std::string> uniqueNames;
-    for (const auto& key : keys) {
-        std::string name(key.name);
-
-        // Keys must not start with 'android' or 'com.android'
-        EXPECT_FALSE(name.find("android") == 0);
-        EXPECT_FALSE(name.find("com.android") == 0);
-
-        // Keys must be in reverse domain name format
-        EXPECT_TRUE(std::regex_match(name, reverseDomainName));
-
-        // Keys must be unique within this list
-        const auto& [iter, inserted] = uniqueNames.insert(name);
-        EXPECT_TRUE(inserted);
-    }
-}
-
 TEST_P(GraphicsComposerAidlTest, CreateVirtualDisplay) {
     int32_t maxVirtualDisplayCount;
     EXPECT_TRUE(mComposerClient->getMaxVirtualDisplayCount(&maxVirtualDisplayCount).isOk());
@@ -992,14 +941,14 @@
 
 TEST_P(GraphicsComposerAidlTest, SetPowerModeUnsupported) {
     std::vector<DisplayCapability> capabilities;
-    const auto error = mComposerClient->getDisplayCapabilities(mPrimaryDisplay, &capabilities);
+    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);
+        error = mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::DOZE);
         EXPECT_FALSE(error.isOk());
         EXPECT_EQ(IComposerClient::EX_UNSUPPORTED, error.getServiceSpecificError());
 
@@ -1009,7 +958,7 @@
     }
 
     if (!isSuspendSupported) {
-        auto error = mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::ON_SUSPEND);
+        error = mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::ON_SUSPEND);
         EXPECT_FALSE(error.isOk());
         EXPECT_EQ(IComposerClient::EX_UNSUPPORTED, error.getServiceSpecificError());
 
@@ -1162,13 +1111,7 @@
     void TearDown() override {
         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_TRUE(mReader.takeChangedCompositionTypes(mPrimaryDisplay).empty());
 
         ASSERT_NO_FATAL_FAILURE(GraphicsComposerAidlTest::TearDown());
     }
@@ -1184,7 +1127,7 @@
         const auto status = mComposerClient->executeCommands(commands, &results);
         ASSERT_TRUE(status.isOk()) << "executeCommands failed " << status.getDescription();
 
-        mReader.parse(results);
+        mReader.parse(std::move(results));
         mWriter.reset();
     }
 
@@ -1263,7 +1206,7 @@
         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);
@@ -1282,7 +1225,7 @@
             mWriter.setLayerBuffer(display.get(), layer, 0, buffer->handle, -1);
             mWriter.setLayerDataspace(display.get(), layer, common::Dataspace::UNKNOWN);
 
-            mWriter.validateDisplay(display.get());
+            mWriter.validateDisplay(display.get(), ComposerClientWriter::kNoTimestamp);
             execute();
             ASSERT_TRUE(mReader.takeErrors().empty());
 
@@ -1292,13 +1235,13 @@
         }
 
         {
-            auto buffer = allocate();
+            const auto buffer = allocate();
             ASSERT_NE(nullptr, buffer->handle);
 
             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());
+            mWriter.validateDisplay(display.get(), ComposerClientWriter::kNoTimestamp);
             execute();
             ASSERT_TRUE(mReader.takeErrors().empty());
 
@@ -1309,6 +1252,55 @@
         ASSERT_NO_FATAL_FAILURE(destroyLayer(display, layer));
     }
 
+    sp<::android::Fence> presentAndGetFence(
+            std::optional<ClockMonotonicTimestamp> expectedPresentTime) {
+        mWriter.validateDisplay(mPrimaryDisplay, expectedPresentTime);
+        execute();
+        EXPECT_TRUE(mReader.takeErrors().empty());
+
+        mWriter.presentDisplay(mPrimaryDisplay);
+        execute();
+        EXPECT_TRUE(mReader.takeErrors().empty());
+
+        auto presentFence = mReader.takePresentFence(mPrimaryDisplay);
+        // take ownership
+        const int fenceOwner = presentFence.get();
+        *presentFence.getR() = -1;
+        EXPECT_NE(-1, fenceOwner);
+        return sp<::android::Fence>::make(fenceOwner);
+    }
+
+    int32_t getVsyncPeriod() {
+        int32_t activeConfig;
+        EXPECT_TRUE(mComposerClient->getActiveConfig(mPrimaryDisplay, &activeConfig).isOk());
+
+        int32_t vsyncPeriod;
+        EXPECT_TRUE(mComposerClient
+                            ->getDisplayAttribute(mPrimaryDisplay, activeConfig,
+                                                  DisplayAttribute::VSYNC_PERIOD, &vsyncPeriod)
+                            .isOk());
+        return vsyncPeriod;
+    }
+
+    int64_t createOnScreenLayer() {
+        const int64_t layer = createLayer(mDisplays[0]);
+        mWriter.setLayerCompositionType(mPrimaryDisplay, layer, Composition::DEVICE);
+        mWriter.setLayerDisplayFrame(mPrimaryDisplay, layer, {0, 0, mDisplayWidth, mDisplayHeight});
+        mWriter.setLayerPlaneAlpha(mPrimaryDisplay, layer, 1);
+        mWriter.setLayerSourceCrop(
+                mPrimaryDisplay, layer,
+                {0, 0, static_cast<float>(mDisplayWidth), static_cast<float>(mDisplayHeight)});
+        mWriter.setLayerTransform(mPrimaryDisplay, layer, static_cast<Transform>(0));
+        mWriter.setLayerVisibleRegion(mPrimaryDisplay, layer,
+                                      std::vector<Rect>(1, {0, 0, mDisplayWidth, mDisplayHeight}));
+        mWriter.setLayerZOrder(mPrimaryDisplay, layer, 10);
+        mWriter.setLayerBlendMode(mPrimaryDisplay, layer, BlendMode::NONE);
+        mWriter.setLayerSurfaceDamage(mPrimaryDisplay, layer,
+                                      std::vector<Rect>(1, {0, 0, mDisplayWidth, mDisplayHeight}));
+        mWriter.setLayerDataspace(mPrimaryDisplay, layer, common::Dataspace::UNKNOWN);
+        return layer;
+    }
+
     void Test_setActiveConfigWithConstraints(const TestParameters& params) {
         for (VtsDisplay& display : mDisplays) {
             forEachTwoConfigs(display.get(), [&](int32_t config1, int32_t config2) {
@@ -1399,6 +1391,46 @@
         }
     }
 
+    void Test_expectedPresentTime(std::optional<int> framesDelay) {
+        ASSERT_TRUE(mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::ON).isOk());
+
+        const auto vsyncPeriod = getVsyncPeriod();
+
+        const auto buffer1 = allocate();
+        const auto buffer2 = allocate();
+        ASSERT_NE(nullptr, buffer1);
+        ASSERT_NE(nullptr, buffer2);
+
+        const auto layer = createOnScreenLayer();
+        mWriter.setLayerBuffer(mPrimaryDisplay, layer, 0, buffer1->handle, -1);
+        const sp<::android::Fence> presentFence1 =
+                presentAndGetFence(ComposerClientWriter::kNoTimestamp);
+        presentFence1->waitForever(LOG_TAG);
+
+        auto expectedPresentTime = presentFence1->getSignalTime() + vsyncPeriod;
+        if (framesDelay.has_value()) {
+            expectedPresentTime += *framesDelay * vsyncPeriod;
+        }
+
+        mWriter.setLayerBuffer(mPrimaryDisplay, layer, 0, buffer2->handle, -1);
+        const auto setExpectedPresentTime = [&]() -> std::optional<ClockMonotonicTimestamp> {
+            if (!framesDelay.has_value()) {
+                return ComposerClientWriter::kNoTimestamp;
+            } else if (*framesDelay == 0) {
+                return ClockMonotonicTimestamp{0};
+            }
+            return ClockMonotonicTimestamp{expectedPresentTime};
+        }();
+
+        const sp<::android::Fence> presentFence2 = presentAndGetFence(setExpectedPresentTime);
+        presentFence2->waitForever(LOG_TAG);
+
+        const auto actualPresentTime = presentFence2->getSignalTime();
+        EXPECT_GE(actualPresentTime, expectedPresentTime - vsyncPeriod / 2);
+
+        ASSERT_TRUE(mComposerClient->setPowerMode(mPrimaryDisplay, PowerMode::OFF).isOk());
+    }
+
     // clang-format off
     const std::array<float, 16> kIdentity = {{
             1.0f, 0.0f, 0.0f, 0.0f,
@@ -1408,12 +1440,12 @@
     }};
     // clang-format on
 
-    CommandWriterBase mWriter;
-    CommandReaderBase mReader;
+    ComposerClientWriter mWriter;
+    ComposerClientReader mReader;
 };
 
 TEST_P(GraphicsComposerAidlCommandTest, SET_COLOR_TRANSFORM) {
-    mWriter.setColorTransform(mPrimaryDisplay, kIdentity.data(), ColorTransform::IDENTITY);
+    mWriter.setColorTransform(mPrimaryDisplay, kIdentity.data());
     execute();
 }
 
@@ -1430,6 +1462,55 @@
     }
 }
 
+TEST_P(GraphicsComposerAidlCommandTest, SetDisplayBrightness) {
+    std::vector<DisplayCapability> capabilities;
+    auto error = mComposerClient->getDisplayCapabilities(mPrimaryDisplay, &capabilities);
+    ASSERT_TRUE(error.isOk());
+    bool brightnessSupport = std::find(capabilities.begin(), capabilities.end(),
+                                       DisplayCapability::BRIGHTNESS) != capabilities.end();
+    if (!brightnessSupport) {
+        mWriter.setDisplayBrightness(mPrimaryDisplay, 0.5f);
+        execute();
+        const auto errors = mReader.takeErrors();
+        EXPECT_EQ(1, errors.size());
+        EXPECT_EQ(EX_UNSUPPORTED_OPERATION, errors[0].errorCode);
+        GTEST_SUCCEED() << "SetDisplayBrightness is not supported";
+        return;
+    }
+
+    mWriter.setDisplayBrightness(mPrimaryDisplay, 0.0f);
+    execute();
+    EXPECT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setDisplayBrightness(mPrimaryDisplay, 0.5f);
+    execute();
+    EXPECT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setDisplayBrightness(mPrimaryDisplay, 1.0f);
+    execute();
+    EXPECT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setDisplayBrightness(mPrimaryDisplay, -1.0f);
+    execute();
+    EXPECT_TRUE(mReader.takeErrors().empty());
+
+    mWriter.setDisplayBrightness(mPrimaryDisplay, 2.0f);
+    execute();
+    {
+        const auto errors = mReader.takeErrors();
+        ASSERT_EQ(1, errors.size());
+        EXPECT_EQ(IComposerClient::EX_BAD_PARAMETER, errors[0].errorCode);
+    }
+
+    mWriter.setDisplayBrightness(mPrimaryDisplay, -2.0f);
+    execute();
+    {
+        const auto errors = mReader.takeErrors();
+        ASSERT_EQ(1, errors.size());
+        EXPECT_EQ(IComposerClient::EX_BAD_PARAMETER, errors[0].errorCode);
+    }
+}
+
 TEST_P(GraphicsComposerAidlCommandTest, SET_CLIENT_TARGET) {
     EXPECT_TRUE(
             mComposerClient->setClientTargetSlotCount(mPrimaryDisplay, kBufferSlotCount).isOk());
@@ -1454,25 +1535,26 @@
                                                kBufferSlotCount, &display)
                         .isOk());
 
-    auto handle = allocate()->handle;
+    const auto buffer = allocate();
+    const auto handle = buffer->handle;
     mWriter.setOutputBuffer(display.display, 0, handle, -1);
     execute();
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, VALIDATE_DISPLAY) {
-    mWriter.validateDisplay(mPrimaryDisplay);
+    mWriter.validateDisplay(mPrimaryDisplay, ComposerClientWriter::kNoTimestamp);
     execute();
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, ACCEPT_DISPLAY_CHANGES) {
-    mWriter.validateDisplay(mPrimaryDisplay);
+    mWriter.validateDisplay(mPrimaryDisplay, ComposerClientWriter::kNoTimestamp);
     mWriter.acceptDisplayChanges(mPrimaryDisplay);
     execute();
 }
 
 // TODO(b/208441745) fix the test failure
 TEST_P(GraphicsComposerAidlCommandTest, PRESENT_DISPLAY) {
-    mWriter.validateDisplay(mPrimaryDisplay);
+    mWriter.validateDisplay(mPrimaryDisplay, ComposerClientWriter::kNoTimestamp);
     mWriter.presentDisplay(mPrimaryDisplay);
     execute();
 }
@@ -1500,7 +1582,8 @@
     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};
@@ -1520,12 +1603,9 @@
         mWriter.setLayerBuffer(mPrimaryDisplay, layer, 0, handle, -1);
         mWriter.setLayerDataspace(mPrimaryDisplay, layer, Dataspace::UNKNOWN);
 
-        mWriter.validateDisplay(mPrimaryDisplay);
+        mWriter.validateDisplay(mPrimaryDisplay, ComposerClientWriter::kNoTimestamp);
         execute();
-        std::vector<int64_t> layers;
-        std::vector<Composition> types;
-        mReader.takeChangedCompositionTypes(mPrimaryDisplay, &layers, &types);
-        if (!layers.empty()) {
+        if (!mReader.takeChangedCompositionTypes(mPrimaryDisplay).empty()) {
             GTEST_SUCCEED() << "Composition change requested, skipping test";
             return;
         }
@@ -1535,7 +1615,8 @@
         execute();
         ASSERT_TRUE(mReader.takeErrors().empty());
 
-        auto handle2 = allocate()->handle;
+        const auto buffer2 = allocate();
+        const auto handle2 = buffer2->handle;
         ASSERT_NE(nullptr, handle2);
         mWriter.setLayerBuffer(mPrimaryDisplay, layer, 0, handle2, -1);
         mWriter.setLayerSurfaceDamage(mPrimaryDisplay, layer, std::vector<Rect>(1, {0, 0, 10, 10}));
@@ -1549,7 +1630,8 @@
     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};
 
@@ -1565,13 +1647,11 @@
     mWriter.setLayerBlendMode(mPrimaryDisplay, layer, BlendMode::NONE);
     mWriter.setLayerSurfaceDamage(mPrimaryDisplay, layer, std::vector<Rect>(1, displayFrame));
     mWriter.setLayerDataspace(mPrimaryDisplay, layer, Dataspace::UNKNOWN);
-    mWriter.validateDisplay(mPrimaryDisplay);
+    mWriter.validateDisplay(mPrimaryDisplay, ComposerClientWriter::kNoTimestamp);
 
     execute();
-    std::vector<int64_t> layers;
-    std::vector<Composition> types;
-    mReader.takeChangedCompositionTypes(mPrimaryDisplay, &layers, &types);
-    if (!layers.empty()) {
+
+    if (!mReader.takeChangedCompositionTypes(mPrimaryDisplay).empty()) {
         GTEST_SUCCEED() << "Composition change requested, skipping test";
         return;
     }
@@ -1582,13 +1662,14 @@
     execute();
 
     mWriter.setLayerCursorPosition(mPrimaryDisplay, layer, 0, 0);
-    mWriter.validateDisplay(mPrimaryDisplay);
+    mWriter.validateDisplay(mPrimaryDisplay, ComposerClientWriter::kNoTimestamp);
     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;
@@ -1638,13 +1719,11 @@
     int64_t layer;
     EXPECT_TRUE(mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount, &layer).isOk());
 
-    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)});
+    mWriter.setLayerColor(mPrimaryDisplay, layer, Color{1.0f, 1.0f, 1.0f, 1.0f});
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
 
-    mWriter.setLayerColor(mPrimaryDisplay, layer, Color{0, 0, 0, 0});
+    mWriter.setLayerColor(mPrimaryDisplay, layer, Color{0.0f, 0.0f, 0.0f, 0.0f});
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
 }
@@ -1708,7 +1787,8 @@
         return;
     }
 
-    auto handle = allocate()->handle;
+    const auto buffer = allocate();
+    const auto handle = buffer->handle;
     ASSERT_NE(nullptr, handle);
 
     int64_t layer;
@@ -1940,6 +2020,18 @@
     }
 }
 
+TEST_P(GraphicsComposerAidlCommandTest, expectedPresentTime_NoTimestamp) {
+    ASSERT_NO_FATAL_FAILURE(Test_expectedPresentTime(std::nullopt));
+}
+
+TEST_P(GraphicsComposerAidlCommandTest, expectedPresentTime_0) {
+    ASSERT_NO_FATAL_FAILURE(Test_expectedPresentTime(0));
+}
+
+TEST_P(GraphicsComposerAidlCommandTest, expectedPresentTime_5) {
+    ASSERT_NO_FATAL_FAILURE(Test_expectedPresentTime(5));
+}
+
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerAidlCommandTest);
 INSTANTIATE_TEST_SUITE_P(
         PerInstance, GraphicsComposerAidlCommandTest,
@@ -1962,5 +2054,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/ReadbackVts.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/ReadbackVts.cpp
index a6954b4..deb5ac3 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,7 +32,7 @@
 const std::vector<Dataspace> ReadbackHelper::dataspaces = {common::Dataspace::SRGB,
                                                            common::Dataspace::DISPLAY_P3};
 
-void TestLayer::write(CommandWriterBase& writer) {
+void TestLayer::write(ComposerClientWriter& writer) {
     writer.setLayerDisplayFrame(mDisplay, mLayer, mDisplayFrame);
     writer.setLayerSourceCrop(mDisplay, mLayer, mSourceCrop);
     writer.setLayerZOrder(mDisplay, mLayer, mZOrder);
@@ -131,12 +131,12 @@
 
             int offset = (row * static_cast<int32_t>(stride) + col) * bytesPerPixel;
             uint8_t* pixelColor = (uint8_t*)bufferData + offset;
-            pixelColor[0] = static_cast<uint8_t>(srcColor.r);
-            pixelColor[1] = static_cast<uint8_t>(srcColor.g);
-            pixelColor[2] = static_cast<uint8_t>(srcColor.b);
+            pixelColor[0] = static_cast<uint8_t>(std::round(255.0f * srcColor.r));
+            pixelColor[1] = static_cast<uint8_t>(std::round(255.0f * srcColor.g));
+            pixelColor[2] = static_cast<uint8_t>(std::round(255.0f * srcColor.b));
 
             if (bytesPerPixel == 4) {
-                pixelColor[3] = static_cast<uint8_t>(srcColor.a);
+                pixelColor[3] = static_cast<uint8_t>(std::round(255.0f * srcColor.a));
             }
         }
     }
@@ -184,13 +184,11 @@
             auto pixel = row * static_cast<int32_t>(width) + col;
             int offset = (row * stride + col) * bytesPerPixel;
             uint8_t* pixelColor = (uint8_t*)bufferData + offset;
+            const Color expectedColor = expectedColors[static_cast<size_t>(pixel)];
 
-            ASSERT_EQ(static_cast<int8_t>(expectedColors[static_cast<size_t>(pixel)].r),
-                      pixelColor[0]);
-            ASSERT_EQ(static_cast<int8_t>(expectedColors[static_cast<size_t>(pixel)].g),
-                      pixelColor[1]);
-            ASSERT_EQ(static_cast<int8_t>(expectedColors[static_cast<size_t>(pixel)].b),
-                      pixelColor[2]);
+            ASSERT_EQ(std::round(255.0f * expectedColor.r), pixelColor[0]);
+            ASSERT_EQ(std::round(255.0f * expectedColor.g), pixelColor[1]);
+            ASSERT_EQ(std::round(255.0f * expectedColor.b), pixelColor[2]);
         }
     }
 }
@@ -242,18 +240,18 @@
 
     int outBytesPerPixel;
     int outBytesPerStride;
-    auto status = mGraphicBuffer->lockAsync(mUsage, mAccessRegion, nullptr, fenceHandle.get(),
+    void* bufData = nullptr;
+    auto status = mGraphicBuffer->lockAsync(mUsage, mAccessRegion, &bufData, fenceHandle.get(),
                                             &outBytesPerPixel, &outBytesPerStride);
     EXPECT_EQ(::android::OK, status);
     ASSERT_TRUE(mPixelFormat == PixelFormat::RGB_888 || mPixelFormat == PixelFormat::RGBA_8888);
-    ReadbackHelper::compareColorBuffers(expectedColors, mGraphicBuffer.get(),
-                                        static_cast<int32_t>(mStride), mWidth, mHeight,
-                                        mPixelFormat);
+    ReadbackHelper::compareColorBuffers(expectedColors, bufData, static_cast<int32_t>(mStride),
+                                        mWidth, mHeight, mPixelFormat);
     status = mGraphicBuffer->unlock();
     EXPECT_EQ(::android::OK, status);
 }
 
-void TestColorLayer::write(CommandWriterBase& writer) {
+void TestColorLayer::write(ComposerClientWriter& writer) {
     TestLayer::write(writer);
     writer.setLayerCompositionType(mDisplay, mLayer, Composition::SOLID_COLOR);
     writer.setLayerColor(mDisplay, mLayer, mColor);
@@ -262,12 +260,8 @@
 LayerSettings TestColorLayer::toRenderEngineLayerSettings() {
     LayerSettings layerSettings = TestLayer::toRenderEngineLayerSettings();
 
-    layerSettings.source.solidColor =
-            ::android::half3(static_cast<::android::half>(mColor.r) / 255.0,
-                             static_cast<::android::half>(mColor.g) / 255.0,
-                             static_cast<::android::half>(mColor.b) / 255.0);
-    layerSettings.alpha =
-            mAlpha * static_cast<float>((static_cast<::android::half>(mColor.a) / 255.0));
+    layerSettings.source.solidColor = ::android::half3(mColor.r, mColor.g, mColor.b);
+    layerSettings.alpha = mAlpha * mColor.a;
     return layerSettings;
 }
 
@@ -296,7 +290,7 @@
     setSourceCrop({0, 0, (float)width, (float)height});
 }
 
-void TestBufferLayer::write(CommandWriterBase& writer) {
+void TestBufferLayer::write(ComposerClientWriter& writer) {
     TestLayer::write(writer);
     writer.setLayerCompositionType(mDisplay, mLayer, mComposition);
     writer.setLayerVisibleRegion(mDisplay, mLayer, std::vector<Rect>(1, mDisplayFrame));
@@ -345,11 +339,11 @@
     ASSERT_EQ(::android::OK, mGraphicBuffer->initCheck());
 }
 
-void TestBufferLayer::setDataspace(common::Dataspace dataspace, CommandWriterBase& writer) {
+void TestBufferLayer::setDataspace(common::Dataspace dataspace, ComposerClientWriter& writer) {
     writer.setLayerDataspace(mDisplay, mLayer, dataspace);
 }
 
-void TestBufferLayer::setToClientComposition(CommandWriterBase& writer) {
+void TestBufferLayer::setToClientComposition(ComposerClientWriter& writer) {
     writer.setLayerCompositionType(mDisplay, mLayer, Composition::CLIENT);
 }
 
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 d40e3d2..0fac2b3 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
@@ -23,7 +23,8 @@
 #include <GraphicsComposerCallback.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>
@@ -40,13 +41,12 @@
 using common::PixelFormat;
 using IMapper2_1 = ::android::hardware::graphics::mapper::V2_1::IMapper;
 
-static const Color BLACK = {0, 0, 0, static_cast<int8_t>(0xff)};
-static const Color RED = {static_cast<int8_t>(0xff), 0, 0, static_cast<int8_t>(0xff)};
-static const Color TRANSLUCENT_RED = {static_cast<int8_t>(0xff), 0, 0, 0x33};
-static const Color GREEN = {0, static_cast<int8_t>(0xff), 0, static_cast<int8_t>(0xff)};
-static const Color BLUE = {0, 0, static_cast<int8_t>(0xff), static_cast<int8_t>(0xff)};
-static const Color WHITE = {static_cast<int8_t>(0xff), static_cast<int8_t>(0xff),
-                            static_cast<int8_t>(0xff), static_cast<int8_t>(0xff)};
+static const Color BLACK = {0.0f, 0.0f, 0.0f, 1.0f};
+static const Color RED = {1.0f, 0.0f, 0.0f, 1.0f};
+static const Color TRANSLUCENT_RED = {1.0f, 0.0f, 0.0f, 0.3f};
+static const Color GREEN = {0.0f, 1.0f, 0.0f, 1.0f};
+static const Color BLUE = {0.0f, 0.0f, 1.0f, 1.0f};
+static const Color WHITE = {1.0f, 1.0f, 1.0f, 1.0f};
 
 class TestRenderEngine;
 
@@ -61,7 +61,7 @@
     // call destroyLayers here
     virtual ~TestLayer(){};
 
-    virtual void write(CommandWriterBase& writer);
+    virtual void write(ComposerClientWriter& writer);
     virtual LayerSettings toRenderEngineLayerSettings();
 
     void setDisplayFrame(Rect frame) { mDisplayFrame = frame; }
@@ -105,7 +105,7 @@
     TestColorLayer(const std::shared_ptr<IComposerClient>& client, int64_t display)
         : TestLayer{client, display} {}
 
-    void write(CommandWriterBase& writer) override;
+    void write(ComposerClientWriter& writer) override;
 
     LayerSettings toRenderEngineLayerSettings() override;
 
@@ -123,7 +123,7 @@
                     uint32_t height, common::PixelFormat format,
                     Composition composition = Composition::DEVICE);
 
-    void write(CommandWriterBase& writer) override;
+    void write(ComposerClientWriter& writer) override;
 
     LayerSettings toRenderEngineLayerSettings() override;
 
@@ -131,9 +131,9 @@
 
     void setBuffer(std::vector<Color> colors);
 
-    void setDataspace(Dataspace dataspace, CommandWriterBase& writer);
+    void setDataspace(Dataspace dataspace, ComposerClientWriter& writer);
 
-    void setToClientComposition(CommandWriterBase& writer);
+    void setToClientComposition(ComposerClientWriter& writer);
 
     uint32_t getWidth() const { return mWidth; }
 
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..f9e35e9
--- /dev/null
+++ b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientReader.h
@@ -0,0 +1,226 @@
+/*
+ * 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/composer3/ClientTargetProperty.h>
+#include <aidl/android/hardware/graphics/composer3/Composition.h>
+#include <aidl/android/hardware/graphics/composer3/CommandResultPayload.h>
+
+
+#include <log/log.h>
+#include <sync/sync.h>
+
+
+using aidl::android::hardware::graphics::common::Dataspace;
+
+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(std::vector<CommandResultPayload>&& results) {
+        resetData();
+
+        for (auto& result : results) {
+            switch (result.getTag()) {
+                case CommandResultPayload::Tag::error:
+                    parseSetError(std::move(result.get<CommandResultPayload::Tag::error>()));
+                    break;
+                case CommandResultPayload::Tag::changedCompositionTypes:
+                    parseSetChangedCompositionTypes(std::move(
+                            result.get<CommandResultPayload::Tag::changedCompositionTypes>()));
+                    break;
+                case CommandResultPayload::Tag::displayRequest:
+                    parseSetDisplayRequests(
+                            std::move(result.get<CommandResultPayload::Tag::displayRequest>()));
+                    break;
+                case CommandResultPayload::Tag::presentFence:
+                    parseSetPresentFence(
+                            std::move(result.get<CommandResultPayload::Tag::presentFence>()));
+                    break;
+                case CommandResultPayload::Tag::releaseFences:
+                    parseSetReleaseFences(
+                            std::move(result.get<CommandResultPayload::Tag::releaseFences>()));
+                    break;
+                case CommandResultPayload::Tag::presentOrValidateResult:
+                    parseSetPresentOrValidateDisplayResult(std::move(
+                            result.get<CommandResultPayload::Tag::presentOrValidateResult>()));
+                    break;
+                case CommandResultPayload::Tag::clientTargetProperty:
+                    parseSetClientTargetProperty(std::move(
+                            result.get<CommandResultPayload::Tag::clientTargetProperty>()));
+                    break;
+            }
+        }
+    }
+
+    std::vector<CommandError> takeErrors() { return std::move(mErrors); }
+
+    void 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;
+        }
+
+        const ReturnData& data = found->second;
+
+        *outNumChangedCompositionTypes = static_cast<uint32_t>(data.changedLayers.size());
+        *outNumLayerRequestMasks = static_cast<uint32_t>(data.displayRequests.layerRequests.size());
+    }
+
+    // Get and clear saved changed composition types.
+    std::vector<ChangedCompositionLayer> takeChangedCompositionTypes(int64_t display) {
+        auto found = mReturnData.find(display);
+        if (found == mReturnData.end()) {
+            return {};
+        }
+
+        ReturnData& data = found->second;
+        return std::move(data.changedLayers);
+    }
+
+    // Get and clear saved display requests.
+    DisplayRequest takeDisplayRequests(int64_t display) {
+        auto found = mReturnData.find(display);
+        if (found == mReturnData.end()) {
+            return {};
+        }
+
+        ReturnData& data = found->second;
+        return std::move(data.displayRequests);
+    }
+
+    // Get and clear saved release fences.
+    std::vector<ReleaseFences::Layer> takeReleaseFences(int64_t display) {
+        auto found = mReturnData.find(display);
+        if (found == mReturnData.end()) {
+            return {};
+        }
+
+        ReturnData& data = found->second;
+        return std::move(data.releasedLayers);
+    }
+
+    // Get and clear saved present fence.
+    ndk::ScopedFileDescriptor takePresentFence(int64_t display) {
+        auto found = mReturnData.find(display);
+        if (found == mReturnData.end()) {
+            return {};
+        }
+
+        ReturnData& data = found->second;
+        return std::move(data.presentFence);
+    }
+
+    // Get what stage succeeded during PresentOrValidate: Present or Validate
+    std::optional<PresentOrValidate::Result> takePresentOrValidateStage(int64_t display) {
+        auto found = mReturnData.find(display);
+        if (found == mReturnData.end()) {
+            return std::nullopt;
+        }
+        ReturnData& data = found->second;
+        return data.presentOrValidateState;
+    }
+
+    // Get the client target properties requested by hardware composer.
+    ClientTargetPropertyWithNits takeClientTargetProperty(int64_t display) {
+        auto found = mReturnData.find(display);
+
+        // If not found, return the default values.
+        if (found == mReturnData.end()) {
+            return ClientTargetPropertyWithNits{
+                    .clientTargetProperty = {common::PixelFormat::RGBA_8888, Dataspace::UNKNOWN},
+                    .whitePointNits = -1.f,
+            };
+        }
+
+        ReturnData& data = found->second;
+        return std::move(data.clientTargetProperty);
+    }
+
+  private:
+    void resetData() {
+        mErrors.clear();
+        mReturnData.clear();
+    }
+
+    void parseSetError(CommandError&& error) { mErrors.emplace_back(error); }
+
+    void parseSetChangedCompositionTypes(ChangedCompositionTypes&& changedCompositionTypes) {
+        auto& data = mReturnData[changedCompositionTypes.display];
+        data.changedLayers = std::move(changedCompositionTypes.layers);
+    }
+
+    void parseSetDisplayRequests(DisplayRequest&& displayRequest) {
+        auto& data = mReturnData[displayRequest.display];
+        data.displayRequests = std::move(displayRequest);
+    }
+
+    void parseSetPresentFence(PresentFence&& presentFence) {
+        auto& data = mReturnData[presentFence.display];
+        data.presentFence = std::move(presentFence.fence);
+    }
+
+    void parseSetReleaseFences(ReleaseFences&& releaseFences) {
+        auto& data = mReturnData[releaseFences.display];
+        data.releasedLayers = std::move(releaseFences.layers);
+    }
+
+    void parseSetPresentOrValidateDisplayResult(const PresentOrValidate&& presentOrValidate) {
+        auto& data = mReturnData[presentOrValidate.display];
+        data.presentOrValidateState = std::move(presentOrValidate.result);
+    }
+
+    void parseSetClientTargetProperty(const ClientTargetPropertyWithNits&& clientTargetProperty) {
+        auto& data = mReturnData[clientTargetProperty.display];
+        data.clientTargetProperty = std::move(clientTargetProperty);
+    }
+
+    struct ReturnData {
+        DisplayRequest displayRequests;
+        std::vector<ChangedCompositionLayer> changedLayers;
+        ndk::ScopedFileDescriptor presentFence;
+        std::vector<ReleaseFences::Layer> releasedLayers;
+        PresentOrValidate::Result presentOrValidateState;
+
+        ClientTargetPropertyWithNits clientTargetProperty = {
+                .clientTargetProperty = {common::PixelFormat::RGBA_8888, Dataspace::UNKNOWN},
+                .whitePointNits = -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..d3266e7
--- /dev/null
+++ b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h
@@ -0,0 +1,274 @@
+/*
+ * 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/DisplayBrightness.h>
+#include <aidl/android/hardware/graphics/composer3/Luminance.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:
+    static constexpr std::optional<ClockMonotonicTimestamp> kNoTimestamp = std::nullopt;
+
+    ComposerClientWriter() { reset(); }
+
+    virtual ~ComposerClientWriter() { reset(); }
+
+    void reset() {
+        mDisplayCommand.reset();
+        mLayerCommand.reset();
+        mCommands.clear();
+    }
+
+    void setColorTransform(int64_t display, const float* matrix) {
+        std::vector<float> matVec;
+        matVec.reserve(16);
+        matVec.assign(matrix, matrix + 16);
+        getDisplayCommand(display).colorTransformMatrix.emplace(std::move(matVec));
+    }
+
+    void setDisplayBrightness(int64_t display, float brightness) {
+        getDisplayCommand(display).brightness.emplace(DisplayBrightness{.brightness = brightness});
+    }
+
+    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,
+                         std::optional<ClockMonotonicTimestamp> expectedPresentTime) {
+        auto& command = getDisplayCommand(display);
+        command.expectedPresentTime = expectedPresentTime;
+        command.validateDisplay = true;
+    }
+
+    void presentOrvalidateDisplay(int64_t display,
+                                  std::optional<ClockMonotonicTimestamp> expectedPresentTime) {
+        auto& command = getDisplayCommand(display);
+        command.expectedPresentTime = expectedPresentTime;
+        command.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 setLayerWhitePointNits(int64_t display, int64_t layer, float whitePointNits) {
+        getLayerCommand(display, layer).whitePointNits.emplace(Luminance{.nits = whitePointNits});
+    }
+
+    void setLayerBlockingRegion(int64_t display, int64_t layer, const std::vector<Rect>& blocking) {
+        getLayerCommand(display, layer).blockingRegion.emplace(blocking.begin(), blocking.end());
+    }
+
+    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 fcf2a34..0000000
--- a/graphics/composer/aidl/include/android/hardware/graphics/composer3/command-buffer.h
+++ /dev/null
@@ -1,614 +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 <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 {
-
-// This class helps build a command queue.  Note that all sizes/lengths are in
-// units of uint32_t's.
-class CommandWriterBase {
-  public:
-    CommandWriterBase() { reset(); }
-
-    virtual ~CommandWriterBase() { reset(); }
-
-    void reset() {
-        mDisplayCommand.reset();
-        mLayerCommand.reset();
-        mCommands.clear();
-        mCommandsResults.clear();
-    }
-
-    void setError(int32_t index, int32_t errorCode) {
-        CommandError error;
-        error.commandIndex = index;
-        error.errorCode = errorCode;
-        mCommandsResults.emplace_back(std::move(error));
-    }
-
-    void setPresentOrValidateResult(int64_t display, PresentOrValidate::Result result) {
-        PresentOrValidate presentOrValidate;
-        presentOrValidate.display = display;
-        presentOrValidate.result = result;
-        mCommandsResults.emplace_back(std::move(presentOrValidate));
-    }
-
-    void setChangedCompositionTypes(int64_t display, const std::vector<int64_t>& layers,
-                                    const std::vector<Composition>& types) {
-        ChangedCompositionTypes changedCompositionTypes;
-        changedCompositionTypes.display = display;
-        changedCompositionTypes.layers.reserve(layers.size());
-        for (int i = 0; i < layers.size(); i++) {
-            auto layer = ChangedCompositionLayer{.layer = layers[i], .composition = types[i]};
-            changedCompositionTypes.layers.emplace_back(std::move(layer));
-        }
-        mCommandsResults.emplace_back(std::move(changedCompositionTypes));
-    }
-
-    void setDisplayRequests(int64_t display, int32_t displayRequestMask,
-                            const std::vector<int64_t>& layers,
-                            const std::vector<int32_t>& layerRequestMasks) {
-        DisplayRequest displayRequest;
-        displayRequest.display = display;
-        displayRequest.mask = displayRequestMask;
-        displayRequest.layerRequests.reserve(layers.size());
-        for (int i = 0; i < layers.size(); i++) {
-            auto layerRequest =
-                    DisplayRequest::LayerRequest{.layer = layers[i], .mask = layerRequestMasks[i]};
-            displayRequest.layerRequests.emplace_back(std::move(layerRequest));
-        }
-        mCommandsResults.emplace_back(std::move(displayRequest));
-    }
-
-    void setPresentFence(int64_t display, ::ndk::ScopedFileDescriptor presentFence) {
-        if (presentFence.get() >= 0) {
-            PresentFence presentFenceCommand;
-            presentFenceCommand.fence = std::move(presentFence);
-            presentFenceCommand.display = display;
-            mCommandsResults.emplace_back(std::move(presentFenceCommand));
-        } else {
-            ALOGW("%s: invalid present fence %d", __func__, presentFence.get());
-        }
-    }
-
-    void setReleaseFences(int64_t display, const std::vector<int64_t>& layers,
-                          std::vector<::ndk::ScopedFileDescriptor> releaseFences) {
-        ReleaseFences releaseFencesCommand;
-        releaseFencesCommand.display = display;
-        for (int i = 0; i < layers.size(); i++) {
-            if (releaseFences[i].get() >= 0) {
-                ReleaseFences::Layer layer;
-                layer.layer = layers[i];
-                layer.fence = std::move(releaseFences[i]);
-                releaseFencesCommand.layers.emplace_back(std::move(layer));
-            } else {
-                ALOGW("%s: invalid release fence %d", __func__, releaseFences[i].get());
-            }
-        }
-        mCommandsResults.emplace_back(std::move(releaseFencesCommand));
-    }
-
-    void setClientTargetProperty(int64_t display, const ClientTargetProperty& clientTargetProperty,
-                                 float whitePointNits) {
-        ClientTargetPropertyWithNits clientTargetPropertyWithNits;
-        clientTargetPropertyWithNits.display = display;
-        clientTargetPropertyWithNits.clientTargetProperty = clientTargetProperty;
-        clientTargetPropertyWithNits.whitePointNits = whitePointNits;
-        mCommandsResults.emplace_back(std::move(clientTargetPropertyWithNits));
-    }
-
-    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;
-    }
-
-    std::vector<CommandResultPayload> getPendingCommandResults() {
-        return std::move(mCommandsResults);
-    }
-
-  protected:
-    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;
-    }
-
-    std::optional<DisplayCommand> mDisplayCommand;
-    std::optional<LayerCommand> mLayerCommand;
-    std::vector<DisplayCommand> mCommands;
-    std::vector<CommandResultPayload> mCommandsResults;
-
-  private:
-    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;
-    }
-};
-
-class CommandReaderBase {
-  public:
-    ~CommandReaderBase() { 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/translate-ndk.h b/graphics/composer/aidl/include/android/hardware/graphics/composer3/translate-ndk.h
deleted file mode 100644
index 7004955..0000000
--- a/graphics/composer/aidl/include/android/hardware/graphics/composer3/translate-ndk.h
+++ /dev/null
@@ -1,87 +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
-
-#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/Capability.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/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/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/PerFrameMetadata.h"
-#include "aidl/android/hardware/graphics/composer3/PerFrameMetadataBlob.h"
-#include "aidl/android/hardware/graphics/composer3/PerFrameMetadataKey.h"
-#include "aidl/android/hardware/graphics/composer3/PowerMode.h"
-#include "aidl/android/hardware/graphics/composer3/VsyncPeriodChangeConstraints.h"
-#include "aidl/android/hardware/graphics/composer3/VsyncPeriodChangeTimeline.h"
-#include "android/hardware/graphics/composer/2.1/IComposer.h"
-#include "android/hardware/graphics/composer/2.1/IComposerCallback.h"
-#include "android/hardware/graphics/composer/2.1/IComposerClient.h"
-#include "android/hardware/graphics/composer/2.2/IComposerClient.h"
-#include "android/hardware/graphics/composer/2.3/IComposerClient.h"
-#include "android/hardware/graphics/composer/2.4/IComposerClient.h"
-#include "android/hardware/graphics/composer/2.4/types.h"
-
-namespace android::h2a {
-
-__attribute__((warn_unused_result)) bool translate(
-        const ::android::hardware::graphics::composer::V2_4::VsyncPeriodChangeTimeline& in,
-        aidl::android::hardware::graphics::composer3::VsyncPeriodChangeTimeline* out);
-__attribute__((warn_unused_result)) bool translate(
-        const ::android::hardware::graphics::composer::V2_1::IComposerClient::Rect& in,
-        aidl::android::hardware::graphics::common::Rect* out);
-__attribute__((warn_unused_result)) bool translate(
-        const ::android::hardware::graphics::composer::V2_1::IComposerClient::FRect& in,
-        aidl::android::hardware::graphics::common::FRect* out);
-__attribute__((warn_unused_result)) bool translate(
-        const ::android::hardware::graphics::composer::V2_1::IComposerClient::Color& in,
-        aidl::android::hardware::graphics::composer3::Color* out);
-__attribute__((warn_unused_result)) bool translate(
-        const ::android::hardware::graphics::composer::V2_3::IComposerClient::PerFrameMetadata& in,
-        aidl::android::hardware::graphics::composer3::PerFrameMetadata* out);
-__attribute__((warn_unused_result)) bool translate(
-        const ::android::hardware::graphics::composer::V2_2::IComposerClient::FloatColor& in,
-        aidl::android::hardware::graphics::composer3::FloatColor* out);
-__attribute__((warn_unused_result)) bool translate(
-        const ::android::hardware::graphics::composer::V2_3::IComposerClient::PerFrameMetadataBlob&
-                in,
-        aidl::android::hardware::graphics::composer3::PerFrameMetadataBlob* out);
-__attribute__((warn_unused_result)) bool translate(
-        const ::android::hardware::graphics::composer::V2_4::IComposerClient::
-                VsyncPeriodChangeConstraints& in,
-        aidl::android::hardware::graphics::composer3::VsyncPeriodChangeConstraints* out);
-__attribute__((warn_unused_result)) bool translate(
-        const ::android::hardware::graphics::composer::V2_4::IComposerClient::ClientTargetProperty&
-                in,
-        aidl::android::hardware::graphics::composer3::ClientTargetProperty* out);
-__attribute__((warn_unused_result)) bool translate(
-        const ::android::hardware::graphics::composer::V2_4::IComposerClient::
-                LayerGenericMetadataKey& in,
-        aidl::android::hardware::graphics::composer3::LayerGenericMetadataKey* out);
-
-}  // namespace android::h2a
diff --git a/health/2.1/vts/OWNERS b/health/2.1/vts/OWNERS
index 20450ba..a6803cd 100644
--- a/health/2.1/vts/OWNERS
+++ b/health/2.1/vts/OWNERS
@@ -1,3 +1,2 @@
 elsk@google.com
-hridya@google.com
 sspatil@google.com
diff --git a/health/aidl/Android.bp b/health/aidl/Android.bp
index 6e2f1d4..22bb4fa 100644
--- a/health/aidl/Android.bp
+++ b/health/aidl/Android.bp
@@ -37,7 +37,6 @@
             sdk_version: "module_current",
         },
         ndk: {
-            separate_platform_variant: false,
             vndk: {
                 enabled: true,
             },
diff --git a/health/aidl/default/Android.bp b/health/aidl/default/Android.bp
index 8aa7638..8eab997 100644
--- a/health/aidl/default/Android.bp
+++ b/health/aidl/default/Android.bp
@@ -120,6 +120,15 @@
     },
 }
 
+// Users of libhealth_aidl_impl should use this defaults.
+cc_defaults {
+    name: "libhealth_aidl_impl_user",
+    defaults: [
+        "libhealth_aidl_common_defaults",
+        "libhealth_aidl_charger_defaults",
+    ],
+}
+
 // AIDL version of android.hardware.health@2.1-service.
 // Default binder service of the health HAL.
 cc_defaults {
@@ -127,8 +136,7 @@
     relative_install_path: "hw",
     vintf_fragments: ["android.hardware.health-service.example.xml"],
     defaults: [
-        "libhealth_aidl_common_defaults",
-        "libhealth_aidl_charger_defaults",
+        "libhealth_aidl_impl_user",
     ],
     static_libs: [
         "libhealth_aidl_impl",
diff --git a/health/aidl/vts/functional/Android.bp b/health/aidl/vts/functional/Android.bp
index 434f565..d315c60 100644
--- a/health/aidl/vts/functional/Android.bp
+++ b/health/aidl/vts/functional/Android.bp
@@ -43,6 +43,7 @@
         "libhealthtest_headers",
     ],
     test_suites: [
+        "general-tests",
         "vts",
     ],
 }
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/input/classifier/1.0/vts/functional/Android.bp b/input/classifier/1.0/vts/functional/Android.bp
index 58945d3..5ff1457 100644
--- a/input/classifier/1.0/vts/functional/Android.bp
+++ b/input/classifier/1.0/vts/functional/Android.bp
@@ -30,7 +30,10 @@
         ":inputconstants_aidl",
         "VtsHalInputClassifierV1_0TargetTest.cpp",
     ],
-    header_libs: ["jni_headers"],
+    header_libs: [
+        "jni_headers",
+        "libbinder_headers",
+    ],
     static_libs: [
         "android.hardware.input.classifier@1.0",
         "android.hardware.input.common@1.0",
diff --git a/ir/OWNERS b/ir/OWNERS
new file mode 100644
index 0000000..04de9ef
--- /dev/null
+++ b/ir/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 163905
+connoro@google.com
diff --git a/ir/aidl/Android.bp b/ir/aidl/Android.bp
new file mode 100644
index 0000000..a623491
--- /dev/null
+++ b/ir/aidl/Android.bp
@@ -0,0 +1,43 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_interfaces_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+aidl_interface {
+    name: "android.hardware.ir",
+    vendor_available: true,
+    srcs: ["android/hardware/ir/*.aidl"],
+    stability: "vintf",
+    backend: {
+        cpp: {
+            enabled: false,
+        },
+        java: {
+            sdk_version: "module_current",
+        },
+        ndk: {
+            vndk: {
+                // TODO(b/206116595) enable this
+                enabled: false,
+            },
+        },
+    },
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/WhitePointNits.aidl b/ir/aidl/aidl_api/android.hardware.ir/current/android/hardware/ir/ConsumerIrFreqRange.aidl
similarity index 88%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/WhitePointNits.aidl
copy to ir/aidl/aidl_api/android.hardware.ir/current/android/hardware/ir/ConsumerIrFreqRange.aidl
index c3925d2..4a0d286 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/WhitePointNits.aidl
+++ b/ir/aidl/aidl_api/android.hardware.ir/current/android/hardware/ir/ConsumerIrFreqRange.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.ir;
 @VintfStability
-parcelable WhitePointNits {
-  float nits;
+parcelable ConsumerIrFreqRange {
+  int minHz;
+  int maxHz;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl b/ir/aidl/aidl_api/android.hardware.ir/current/android/hardware/ir/IConsumerIr.aidl
similarity index 84%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl
copy to ir/aidl/aidl_api/android.hardware.ir/current/android/hardware/ir/IConsumerIr.aidl
index df07c9c..07bf4b4 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl
+++ b/ir/aidl/aidl_api/android.hardware.ir/current/android/hardware/ir/IConsumerIr.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,9 +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.ir;
 @VintfStability
-parcelable ColorTransformPayload {
-  float[] matrix;
-  android.hardware.graphics.common.ColorTransform hint;
+interface IConsumerIr {
+  android.hardware.ir.ConsumerIrFreqRange[] getCarrierFreqs();
+  void transmit(in int carrierFreqHz, in int[] pattern);
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl b/ir/aidl/android/hardware/ir/ConsumerIrFreqRange.aidl
similarity index 62%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
copy to ir/aidl/android/hardware/ir/ConsumerIrFreqRange.aidl
index a0a1d4b..ab0276a 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
+++ b/ir/aidl/android/hardware/ir/ConsumerIrFreqRange.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,
@@ -14,16 +14,10 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
-
-/**
- * Color representation as a floating point number in the range [0.0 - 1.0]
- */
+package android.hardware.ir;
 
 @VintfStability
-parcelable FloatColor {
-    float r;
-    float g;
-    float b;
-    float a;
+parcelable ConsumerIrFreqRange {
+    int minHz;
+    int maxHz;
 }
diff --git a/ir/aidl/android/hardware/ir/IConsumerIr.aidl b/ir/aidl/android/hardware/ir/IConsumerIr.aidl
new file mode 100644
index 0000000..f6f9742
--- /dev/null
+++ b/ir/aidl/android/hardware/ir/IConsumerIr.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.ir;
+
+import android.hardware.ir.ConsumerIrFreqRange;
+
+@VintfStability
+interface IConsumerIr {
+    /**
+     * Enumerates which frequencies the IR transmitter supports.
+     *
+     * @return - an array of all supported frequency ranges.
+     */
+    ConsumerIrFreqRange[] getCarrierFreqs();
+
+    /**
+     * Sends an IR pattern at a given frequency in HZ.
+     * This call must return when the transmit is complete or encounters an error.
+     *
+     * @param carrierFreq - Frequency of the transmission in HZ.
+     *
+     * @param pattern - Alternating series of on and off periods measured in
+     * microseconds. The carrier should be turned off at the end of a transmit
+     * even if there are an odd number of entries in the pattern array.
+     *
+     * @throws EX_UNSUPPORTED_OPERATION when the frequency is not supported.
+     */
+    void transmit(in int carrierFreqHz, in int[] pattern);
+}
diff --git a/ir/aidl/default/Android.bp b/ir/aidl/default/Android.bp
new file mode 100644
index 0000000..a4fb439
--- /dev/null
+++ b/ir/aidl/default/Android.bp
@@ -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.
+
+// Example binder service of the ir HAL.
+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.ir-service.example",
+    relative_install_path: "hw",
+    init_rc: ["android.hardware.ir-service.example.rc"],
+    vendor: true,
+    vintf_fragments: ["android.hardware.ir-service.example.xml"],
+
+    shared_libs: [
+        "libbase",
+        "libbinder_ndk",
+        "libcutils",
+        "liblog",
+        "libutils",
+        "android.hardware.ir-V1-ndk",
+    ],
+
+    srcs: ["main.cpp"],
+}
diff --git a/ir/aidl/default/android.hardware.ir-service.example.rc b/ir/aidl/default/android.hardware.ir-service.example.rc
new file mode 100644
index 0000000..56def64
--- /dev/null
+++ b/ir/aidl/default/android.hardware.ir-service.example.rc
@@ -0,0 +1,4 @@
+service vendor.ir-default /vendor/bin/hw/android.hardware.ir-service.example
+    class hal
+    user nobody
+    group nobody
diff --git a/ir/aidl/default/android.hardware.ir-service.example.xml b/ir/aidl/default/android.hardware.ir-service.example.xml
new file mode 100644
index 0000000..1a63520
--- /dev/null
+++ b/ir/aidl/default/android.hardware.ir-service.example.xml
@@ -0,0 +1,7 @@
+<manifest version="1.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.ir</name>
+        <version>1</version>
+        <fqname>IConsumerIr/default</fqname>
+    </hal>
+</manifest>
diff --git a/ir/aidl/default/main.cpp b/ir/aidl/default/main.cpp
new file mode 100644
index 0000000..7c4a816
--- /dev/null
+++ b/ir/aidl/default/main.cpp
@@ -0,0 +1,77 @@
+/*
+ * 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/ir/BnConsumerIr.h>
+#include <android-base/logging.h>
+#include <android/binder_interface_utils.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <numeric>
+
+namespace aidl::android::hardware::ir {
+
+const std::vector<ConsumerIrFreqRange> kSupportedFreqs = {
+        {2000, 4000},
+        {10000, 30000},
+};
+
+class ConsumerIr : public BnConsumerIr {
+    ::ndk::ScopedAStatus getCarrierFreqs(std::vector<ConsumerIrFreqRange>* _aidl_return) override;
+    ::ndk::ScopedAStatus transmit(int32_t in_carrierFreqHz,
+                                  const std::vector<int32_t>& in_pattern) override;
+};
+
+::ndk::ScopedAStatus ConsumerIr::getCarrierFreqs(std::vector<ConsumerIrFreqRange>* _aidl_return) {
+    *_aidl_return = kSupportedFreqs;
+    return ::ndk::ScopedAStatus::ok();
+}
+
+bool isSupportedFreq(int32_t freq) {
+    for (const auto& range : kSupportedFreqs) {
+        if (freq >= range.minHz && freq <= range.maxHz) return true;
+    }
+    return false;
+}
+
+::ndk::ScopedAStatus ConsumerIr::transmit(int32_t in_carrierFreqHz,
+                                          const std::vector<int32_t>& in_pattern) {
+    if (isSupportedFreq(in_carrierFreqHz)) {
+        // trasmit the pattern, each integer is number of microseconds in an
+        // alternating on/off state.
+        usleep(std::accumulate(in_pattern.begin(), in_pattern.end(), 0));
+        return ::ndk::ScopedAStatus::ok();
+    } else {
+        // unsupported operation
+        return ::ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+    }
+    return ::ndk::ScopedAStatus::ok();
+}
+
+}  // namespace aidl::android::hardware::ir
+
+using aidl::android::hardware::ir::ConsumerIr;
+
+int main() {
+    auto binder = ::ndk::SharedRefBase::make<ConsumerIr>();
+    const std::string name = std::string() + ConsumerIr::descriptor + "/default";
+    CHECK_EQ(STATUS_OK, AServiceManager_addService(binder->asBinder().get(), name.c_str()))
+            << "Failed to register " << name;
+
+    ABinderProcess_setThreadPoolMaxThreadCount(0);
+    ABinderProcess_joinThreadPool();
+
+    return EXIT_FAILURE;  // should not reached
+}
diff --git a/ir/aidl/vts/Android.bp b/ir/aidl/vts/Android.bp
new file mode 100644
index 0000000..c2491b8
--- /dev/null
+++ b/ir/aidl/vts/Android.bp
@@ -0,0 +1,43 @@
+//
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_interfaces_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_test {
+    name: "VtsHalIrTargetTest",
+    defaults: [
+        "VtsHalTargetTestDefaults",
+        "use_libaidlvintf_gtest_helper_static",
+    ],
+    srcs: ["VtsHalIrTargetTest.cpp"],
+    shared_libs: [
+        "libbinder_ndk",
+    ],
+    static_libs: [
+        "android.hardware.ir-V1-ndk",
+    ],
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
+}
diff --git a/ir/aidl/vts/VtsHalIrTargetTest.cpp b/ir/aidl/vts/VtsHalIrTargetTest.cpp
new file mode 100644
index 0000000..3527625
--- /dev/null
+++ b/ir/aidl/vts/VtsHalIrTargetTest.cpp
@@ -0,0 +1,77 @@
+/*
+ * 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 "ir_aidl_hal_test"
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/ir/IConsumerIr.h>
+#include <android-base/logging.h>
+#include <android/binder_auto_utils.h>
+#include <android/binder_manager.h>
+#include <gtest/gtest.h>
+#include <algorithm>
+#include <vector>
+
+using ::aidl::android::hardware::ir::ConsumerIrFreqRange;
+using ::aidl::android::hardware::ir::IConsumerIr;
+using ::ndk::SpAIBinder;
+
+class ConsumerIrTest : public ::testing::TestWithParam<std::string> {
+  public:
+    virtual void SetUp() override {
+        mIr = IConsumerIr::fromBinder(
+                SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
+        ASSERT_NE(mIr, nullptr);
+    }
+
+    std::shared_ptr<IConsumerIr> mIr;
+};
+
+// Test transmit() for the min and max frequency of every available range
+TEST_P(ConsumerIrTest, TransmitTest) {
+    std::vector<ConsumerIrFreqRange> ranges;
+    const auto& ret = mIr->getCarrierFreqs(&ranges);
+    ASSERT_TRUE(ret.isOk());
+
+    if (ranges.size() > 0) {
+        uint32_t len = 16;
+        std::vector<int32_t> vec;
+        vec.resize(len);
+        std::fill(vec.begin(), vec.end(), 1000);
+        for (auto range = ranges.begin(); range != ranges.end(); range++) {
+            EXPECT_TRUE(mIr->transmit(range->minHz, vec).isOk());
+            EXPECT_TRUE(mIr->transmit(range->maxHz, vec).isOk());
+        }
+    }
+}
+
+// Test transmit() when called with invalid frequencies
+TEST_P(ConsumerIrTest, BadFreqTest) {
+    uint32_t len = 16;
+    std::vector<int32_t> vec;
+    vec.resize(len);
+    std::fill(vec.begin(), vec.end(), 1);
+    const auto& res = mIr->transmit(-1, vec);
+    EXPECT_FALSE(res.isOk());
+    EXPECT_EQ(res.getExceptionCode(), EX_UNSUPPORTED_OPERATION);
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ConsumerIrTest);
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, ConsumerIrTest,
+        testing::ValuesIn(android::getAidlHalInstanceNames(IConsumerIr::descriptor)),
+        ::android::PrintInstanceNameToString);
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/OWNERS b/memtrack/OWNERS
new file mode 100644
index 0000000..a182ed9
--- /dev/null
+++ b/memtrack/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 30545
+connoro@google.com
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/1.3/vts/functional/MemoryDomainTests.cpp b/neuralnetworks/1.3/vts/functional/MemoryDomainTests.cpp
index e2fa6e4..af3641a 100644
--- a/neuralnetworks/1.3/vts/functional/MemoryDomainTests.cpp
+++ b/neuralnetworks/1.3/vts/functional/MemoryDomainTests.cpp
@@ -1158,12 +1158,15 @@
     auto [buffer, token] = allocateBuffer(preparedModel, {0}, {0}, kTestOperand.dimensions);
     if (buffer == nullptr) return;
 
-    Request::MemoryPool sharedMemory = createSharedMemoryPool(kTestOperandDataSize);
-    Request::MemoryPool deviceMemory = createDeviceMemoryPool(token);
+    // Use an incompatible dimension and make sure the length matches with the bad dimension.
     auto badDimensions = kTestOperand.dimensions;
     badDimensions[0] = 2;
+    const uint32_t badTestOperandDataSize = kTestOperandDataSize * 2;
+
+    Request::MemoryPool sharedMemory = createSharedMemoryPool(badTestOperandDataSize);
+    Request::MemoryPool deviceMemory = createDeviceMemoryPool(token);
     RequestArgument sharedMemoryArg = {
-            .location = {.poolIndex = 0, .offset = 0, .length = kTestOperandDataSize},
+            .location = {.poolIndex = 0, .offset = 0, .length = badTestOperandDataSize},
             .dimensions = badDimensions};
     RequestArgument deviceMemoryArg = {.location = {.poolIndex = 1}};
     RequestArgument deviceMemoryArgWithBadDimensions = {.location = {.poolIndex = 1},
diff --git a/neuralnetworks/OWNERS b/neuralnetworks/OWNERS
index def3ea9..04c5d72 100644
--- a/neuralnetworks/OWNERS
+++ b/neuralnetworks/OWNERS
@@ -1,10 +1,2 @@
 # Bug component: 195575
-# Neuralnetworks team
-butlermichael@google.com
-dgross@google.com
-galarragas@google.com
-ianhua@google.com
-jeanluc@google.com
-miaowang@google.com
-pszczepaniak@google.com
-xusongw@google.com
+include platform/packages/modules/NeuralNetworks:/NNAPI_OWNERS  # Neuralnetworks team
diff --git a/neuralnetworks/aidl/android/hardware/neuralnetworks/OperationType.aidl b/neuralnetworks/aidl/android/hardware/neuralnetworks/OperationType.aidl
index 0ad254d..5f7810b 100644
--- a/neuralnetworks/aidl/android/hardware/neuralnetworks/OperationType.aidl
+++ b/neuralnetworks/aidl/android/hardware/neuralnetworks/OperationType.aidl
@@ -5331,6 +5331,18 @@
     /**
      * Pads a tensor with mirrored values.
      *
+     * This operator specifies one of two padding modes: REFLECT or SYMMETRIC.
+     * In the case of REFLECT mode, the mirroring excludes the border element
+     * on the padding side.
+     * In the case of SYMMETRIC mode, the mirroring includes the border element
+     * on the padding side.
+     *
+     * For example, if the input is the 1-D tensor `[1, 2, 3]` and the padding
+     * is `[0, 2]` (i.e., pad no elements before the first (and only) dimension,
+     * and two elements after the first (and only) dimension), then:
+     *     - REFLECT mode produces the output `[1, 2, 3, 2, 1]`
+     *     - SYMMETRIC mode produces the output `[1, 2, 3, 3, 2]`
+     *
      * Supported tensor {@link OperandType}:
      * * {@link OperandType::TENSOR_FLOAT16}
      * * {@link OperandType::TENSOR_FLOAT32}
@@ -5349,6 +5361,11 @@
      *      front of dimension i.
      *      padding[i, 1] specifies the number of elements to be padded after the
      *      end of dimension i.
+     *      Each padding value must be nonnegative.
+     *      In the case of REFLECT mode, each padding value must be less than the
+     *      corresponding dimension.
+     *      In the case of SYMMETRIC mode, each padding value must be less than or
+     *      equal to the corresponding dimension.
      * * 2: An {@link OperandType::INT32} scalar, specifying the mode.
      *      Options are 0:REFLECT and 1:SYMMETRIC.
      *
diff --git a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Conversions.h b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Conversions.h
index 78433a7..477b311 100644
--- a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Conversions.h
+++ b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Conversions.h
@@ -112,11 +112,15 @@
 GeneralResult<Request> convert(const aidl_hal::Request& request);
 GeneralResult<Timing> convert(const aidl_hal::Timing& timing);
 GeneralResult<SharedHandle> convert(const ndk::ScopedFileDescriptor& handle);
+GeneralResult<BufferDesc> convert(const aidl_hal::BufferDesc& bufferDesc);
 
 GeneralResult<std::vector<Extension>> convert(const std::vector<aidl_hal::Extension>& extension);
 GeneralResult<std::vector<SharedMemory>> convert(const std::vector<aidl_hal::Memory>& memories);
 GeneralResult<std::vector<OutputShape>> convert(
         const std::vector<aidl_hal::OutputShape>& outputShapes);
+GeneralResult<std::vector<SharedHandle>> convert(
+        const std::vector<ndk::ScopedFileDescriptor>& handles);
+GeneralResult<std::vector<BufferRole>> convert(const std::vector<aidl_hal::BufferRole>& roles);
 
 GeneralResult<std::vector<uint32_t>> toUnsigned(const std::vector<int32_t>& vec);
 
@@ -129,6 +133,7 @@
 nn::GeneralResult<std::vector<uint8_t>> unvalidatedConvert(const nn::CacheToken& cacheToken);
 nn::GeneralResult<BufferDesc> unvalidatedConvert(const nn::BufferDesc& bufferDesc);
 nn::GeneralResult<BufferRole> unvalidatedConvert(const nn::BufferRole& bufferRole);
+nn::GeneralResult<DeviceType> unvalidatedConvert(const nn::DeviceType& deviceType);
 nn::GeneralResult<bool> unvalidatedConvert(const nn::MeasureTiming& measureTiming);
 nn::GeneralResult<Memory> unvalidatedConvert(const nn::SharedMemory& memory);
 nn::GeneralResult<OutputShape> unvalidatedConvert(const nn::OutputShape& outputShape);
@@ -154,14 +159,16 @@
 nn::GeneralResult<RequestArgument> unvalidatedConvert(const nn::Request::Argument& requestArgument);
 nn::GeneralResult<RequestMemoryPool> unvalidatedConvert(const nn::Request::MemoryPool& memoryPool);
 nn::GeneralResult<Timing> unvalidatedConvert(const nn::Timing& timing);
-nn::GeneralResult<int64_t> unvalidatedConvert(const nn::Duration& duration);
 nn::GeneralResult<int64_t> unvalidatedConvert(const nn::OptionalDuration& optionalDuration);
 nn::GeneralResult<int64_t> unvalidatedConvert(const nn::OptionalTimePoint& optionalTimePoint);
 nn::GeneralResult<ndk::ScopedFileDescriptor> unvalidatedConvert(const nn::SyncFence& syncFence);
 nn::GeneralResult<ndk::ScopedFileDescriptor> unvalidatedConvert(const nn::SharedHandle& handle);
+nn::GeneralResult<Capabilities> unvalidatedConvert(const nn::Capabilities& capabilities);
+nn::GeneralResult<Extension> unvalidatedConvert(const nn::Extension& extension);
 
 nn::GeneralResult<std::vector<uint8_t>> convert(const nn::CacheToken& cacheToken);
 nn::GeneralResult<BufferDesc> convert(const nn::BufferDesc& bufferDesc);
+nn::GeneralResult<DeviceType> convert(const nn::DeviceType& deviceType);
 nn::GeneralResult<bool> convert(const nn::MeasureTiming& measureTiming);
 nn::GeneralResult<Memory> convert(const nn::SharedMemory& memory);
 nn::GeneralResult<ErrorStatus> convert(const nn::ErrorStatus& errorStatus);
@@ -172,6 +179,8 @@
 nn::GeneralResult<Timing> convert(const nn::Timing& timing);
 nn::GeneralResult<int64_t> convert(const nn::OptionalDuration& optionalDuration);
 nn::GeneralResult<int64_t> convert(const nn::OptionalTimePoint& optionalTimePoint);
+nn::GeneralResult<Capabilities> convert(const nn::Capabilities& capabilities);
+nn::GeneralResult<Extension> convert(const nn::Extension& extension);
 
 nn::GeneralResult<std::vector<BufferRole>> convert(const std::vector<nn::BufferRole>& bufferRoles);
 nn::GeneralResult<std::vector<OutputShape>> convert(
@@ -180,6 +189,7 @@
         const std::vector<nn::SharedHandle>& handles);
 nn::GeneralResult<std::vector<ndk::ScopedFileDescriptor>> convert(
         const std::vector<nn::SyncFence>& syncFences);
+nn::GeneralResult<std::vector<Extension>> convert(const std::vector<nn::Extension>& extensions);
 
 nn::GeneralResult<std::vector<int32_t>> toSigned(const std::vector<uint32_t>& vec);
 
diff --git a/neuralnetworks/aidl/utils/src/Conversions.cpp b/neuralnetworks/aidl/utils/src/Conversions.cpp
index 45628c8..113d2da 100644
--- a/neuralnetworks/aidl/utils/src/Conversions.cpp
+++ b/neuralnetworks/aidl/utils/src/Conversions.cpp
@@ -551,6 +551,10 @@
     return validatedConvert(handle);
 }
 
+GeneralResult<BufferDesc> convert(const aidl_hal::BufferDesc& bufferDesc) {
+    return validatedConvert(bufferDesc);
+}
+
 GeneralResult<std::vector<Extension>> convert(const std::vector<aidl_hal::Extension>& extension) {
     return validatedConvert(extension);
 }
@@ -564,6 +568,15 @@
     return validatedConvert(outputShapes);
 }
 
+GeneralResult<std::vector<SharedHandle>> convert(
+        const std::vector<ndk::ScopedFileDescriptor>& handles) {
+    return validatedConvert(handles);
+}
+
+GeneralResult<std::vector<BufferRole>> convert(const std::vector<aidl_hal::BufferRole>& roles) {
+    return validatedConvert(roles);
+}
+
 GeneralResult<std::vector<uint32_t>> toUnsigned(const std::vector<int32_t>& vec) {
     if (!std::all_of(vec.begin(), vec.end(), [](int32_t v) { return v >= 0; })) {
         return NN_ERROR() << "Negative value passed to conversion from signed to unsigned";
@@ -576,42 +589,7 @@
 namespace aidl::android::hardware::neuralnetworks::utils {
 namespace {
 
-template <typename Input>
-using UnvalidatedConvertOutput =
-        std::decay_t<decltype(unvalidatedConvert(std::declval<Input>()).value())>;
-
-template <typename Type>
-nn::GeneralResult<std::vector<UnvalidatedConvertOutput<Type>>> unvalidatedConvertVec(
-        const std::vector<Type>& arguments) {
-    std::vector<UnvalidatedConvertOutput<Type>> halObject;
-    halObject.reserve(arguments.size());
-    for (const auto& argument : arguments) {
-        halObject.push_back(NN_TRY(unvalidatedConvert(argument)));
-    }
-    return halObject;
-}
-
-template <typename Type>
-nn::GeneralResult<std::vector<UnvalidatedConvertOutput<Type>>> unvalidatedConvert(
-        const std::vector<Type>& arguments) {
-    return unvalidatedConvertVec(arguments);
-}
-
-template <typename Type>
-nn::GeneralResult<UnvalidatedConvertOutput<Type>> validatedConvert(const Type& canonical) {
-    NN_TRY(compliantVersion(canonical));
-    return utils::unvalidatedConvert(canonical);
-}
-
-template <typename Type>
-nn::GeneralResult<std::vector<UnvalidatedConvertOutput<Type>>> validatedConvert(
-        const std::vector<Type>& arguments) {
-    std::vector<UnvalidatedConvertOutput<Type>> halObject(arguments.size());
-    for (size_t i = 0; i < arguments.size(); ++i) {
-        halObject[i] = NN_TRY(validatedConvert(arguments[i]));
-    }
-    return halObject;
-}
+using utils::unvalidatedConvert;
 
 // Helper template for std::visit
 template <class... Ts>
@@ -721,6 +699,74 @@
             operator nn::GeneralResult<Memory>();
 }
 
+nn::GeneralResult<PerformanceInfo> unvalidatedConvert(
+        const nn::Capabilities::PerformanceInfo& info) {
+    return PerformanceInfo{.execTime = info.execTime, .powerUsage = info.powerUsage};
+}
+
+nn::GeneralResult<OperandPerformance> unvalidatedConvert(
+        const nn::Capabilities::OperandPerformance& operandPerformance) {
+    return OperandPerformance{.type = NN_TRY(unvalidatedConvert(operandPerformance.type)),
+                              .info = NN_TRY(unvalidatedConvert(operandPerformance.info))};
+}
+
+nn::GeneralResult<std::vector<OperandPerformance>> unvalidatedConvert(
+        const nn::Capabilities::OperandPerformanceTable& table) {
+    std::vector<OperandPerformance> operandPerformances;
+    operandPerformances.reserve(table.asVector().size());
+    for (const auto& operandPerformance : table.asVector()) {
+        operandPerformances.push_back(NN_TRY(unvalidatedConvert(operandPerformance)));
+    }
+    return operandPerformances;
+}
+
+nn::GeneralResult<ExtensionOperandTypeInformation> unvalidatedConvert(
+        const nn::Extension::OperandTypeInformation& info) {
+    return ExtensionOperandTypeInformation{.type = info.type,
+                                           .isTensor = info.isTensor,
+                                           .byteSize = static_cast<int32_t>(info.byteSize)};
+}
+
+nn::GeneralResult<int64_t> unvalidatedConvert(const nn::Duration& duration) {
+    if (duration < nn::Duration::zero()) {
+        return NN_ERROR() << "Unable to convert invalid (negative) duration";
+    }
+    constexpr std::chrono::nanoseconds::rep kIntMax = std::numeric_limits<int64_t>::max();
+    const auto count = duration.count();
+    return static_cast<int64_t>(std::min(count, kIntMax));
+}
+
+template <typename Input>
+using UnvalidatedConvertOutput =
+        std::decay_t<decltype(unvalidatedConvert(std::declval<Input>()).value())>;
+
+template <typename Type>
+nn::GeneralResult<std::vector<UnvalidatedConvertOutput<Type>>> unvalidatedConvert(
+        const std::vector<Type>& arguments) {
+    std::vector<UnvalidatedConvertOutput<Type>> halObject;
+    halObject.reserve(arguments.size());
+    for (const auto& argument : arguments) {
+        halObject.push_back(NN_TRY(unvalidatedConvert(argument)));
+    }
+    return halObject;
+}
+
+template <typename Type>
+nn::GeneralResult<UnvalidatedConvertOutput<Type>> validatedConvert(const Type& canonical) {
+    NN_TRY(compliantVersion(canonical));
+    return utils::unvalidatedConvert(canonical);
+}
+
+template <typename Type>
+nn::GeneralResult<std::vector<UnvalidatedConvertOutput<Type>>> validatedConvert(
+        const std::vector<Type>& arguments) {
+    std::vector<UnvalidatedConvertOutput<Type>> halObject(arguments.size());
+    for (size_t i = 0; i < arguments.size(); ++i) {
+        halObject[i] = NN_TRY(validatedConvert(arguments[i]));
+    }
+    return halObject;
+}
+
 }  // namespace
 
 nn::GeneralResult<std::vector<uint8_t>> unvalidatedConvert(const nn::CacheToken& cacheToken) {
@@ -743,6 +789,19 @@
     };
 }
 
+nn::GeneralResult<DeviceType> unvalidatedConvert(const nn::DeviceType& deviceType) {
+    switch (deviceType) {
+        case nn::DeviceType::UNKNOWN:
+            break;
+        case nn::DeviceType::OTHER:
+        case nn::DeviceType::CPU:
+        case nn::DeviceType::GPU:
+        case nn::DeviceType::ACCELERATOR:
+            return static_cast<DeviceType>(deviceType);
+    }
+    return NN_ERROR() << "Invalid DeviceType " << deviceType;
+}
+
 nn::GeneralResult<bool> unvalidatedConvert(const nn::MeasureTiming& measureTiming) {
     return measureTiming == nn::MeasureTiming::YES;
 }
@@ -956,15 +1015,6 @@
     };
 }
 
-nn::GeneralResult<int64_t> unvalidatedConvert(const nn::Duration& duration) {
-    if (duration < nn::Duration::zero()) {
-        return NN_ERROR() << "Unable to convert invalid (negative) duration";
-    }
-    constexpr std::chrono::nanoseconds::rep kIntMax = std::numeric_limits<int64_t>::max();
-    const auto count = duration.count();
-    return static_cast<int64_t>(std::min(count, kIntMax));
-}
-
 nn::GeneralResult<int64_t> unvalidatedConvert(const nn::OptionalDuration& optionalDuration) {
     if (!optionalDuration.has_value()) {
         return kNoTiming;
@@ -989,6 +1039,23 @@
     return ndk::ScopedFileDescriptor(duplicatedFd.release());
 }
 
+nn::GeneralResult<Capabilities> unvalidatedConvert(const nn::Capabilities& capabilities) {
+    return Capabilities{
+            .relaxedFloat32toFloat16PerformanceTensor = NN_TRY(
+                    unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceTensor)),
+            .relaxedFloat32toFloat16PerformanceScalar = NN_TRY(
+                    unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceScalar)),
+            .operandPerformance = NN_TRY(unvalidatedConvert(capabilities.operandPerformance)),
+            .ifPerformance = NN_TRY(unvalidatedConvert(capabilities.ifPerformance)),
+            .whilePerformance = NN_TRY(unvalidatedConvert(capabilities.whilePerformance)),
+    };
+}
+
+nn::GeneralResult<Extension> unvalidatedConvert(const nn::Extension& extension) {
+    return Extension{.name = extension.name,
+                     .operandTypes = NN_TRY(unvalidatedConvert(extension.operandTypes))};
+}
+
 nn::GeneralResult<std::vector<uint8_t>> convert(const nn::CacheToken& cacheToken) {
     return validatedConvert(cacheToken);
 }
@@ -997,6 +1064,10 @@
     return validatedConvert(bufferDesc);
 }
 
+nn::GeneralResult<DeviceType> convert(const nn::DeviceType& deviceType) {
+    return validatedConvert(deviceType);
+}
+
 nn::GeneralResult<bool> convert(const nn::MeasureTiming& measureTiming) {
     return validatedConvert(measureTiming);
 }
@@ -1037,6 +1108,14 @@
     return validatedConvert(outputShapes);
 }
 
+nn::GeneralResult<Capabilities> convert(const nn::Capabilities& capabilities) {
+    return validatedConvert(capabilities);
+}
+
+nn::GeneralResult<Extension> convert(const nn::Extension& extension) {
+    return validatedConvert(extension);
+}
+
 nn::GeneralResult<std::vector<BufferRole>> convert(const std::vector<nn::BufferRole>& bufferRoles) {
     return validatedConvert(bufferRoles);
 }
@@ -1056,6 +1135,10 @@
     return validatedConvert(syncFences);
 }
 
+nn::GeneralResult<std::vector<Extension>> convert(const std::vector<nn::Extension>& extensions) {
+    return validatedConvert(extensions);
+}
+
 nn::GeneralResult<std::vector<int32_t>> toSigned(const std::vector<uint32_t>& vec) {
     if (!std::all_of(vec.begin(), vec.end(),
                      [](uint32_t v) { return v <= std::numeric_limits<int32_t>::max(); })) {
diff --git a/neuralnetworks/utils/adapter/aidl/Android.bp b/neuralnetworks/utils/adapter/aidl/Android.bp
new file mode 100644
index 0000000..8269a3d
--- /dev/null
+++ b/neuralnetworks/utils/adapter/aidl/Android.bp
@@ -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 {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_interfaces_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_library_static {
+    name: "neuralnetworks_utils_hal_adapter_aidl",
+    defaults: [
+        "neuralnetworks_use_latest_utils_hal_aidl",
+        "neuralnetworks_utils_defaults",
+    ],
+    srcs: ["src/*"],
+    local_include_dirs: ["include/nnapi/hal/aidl/"],
+    export_include_dirs: ["include"],
+    static_libs: [
+        "neuralnetworks_types",
+        "neuralnetworks_utils_hal_common",
+    ],
+    shared_libs: [
+        "libbinder_ndk",
+    ],
+}
diff --git a/neuralnetworks/utils/adapter/include/nnapi/hal/Adapter.h b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Adapter.h
similarity index 63%
copy from neuralnetworks/utils/adapter/include/nnapi/hal/Adapter.h
copy to neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Adapter.h
index da00a09..4c0b328 100644
--- a/neuralnetworks/utils/adapter/include/nnapi/hal/Adapter.h
+++ b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Adapter.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2020 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.
@@ -14,20 +14,20 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_ADAPTER_H
-#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_ADAPTER_H
+#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_ADAPTER_H
+#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_ADAPTER_H
 
-#include <android/hardware/neuralnetworks/1.3/IDevice.h>
+#include <aidl/android/hardware/neuralnetworks/BnDevice.h>
 #include <nnapi/IDevice.h>
 #include <nnapi/Types.h>
-#include <sys/types.h>
+
 #include <functional>
 #include <memory>
 
-// See hardware/interfaces/neuralnetworks/utils/README.md for more information on HIDL interface
-// lifetimes across processes and for protecting asynchronous calls across HIDL.
+// See hardware/interfaces/neuralnetworks/utils/README.md for more information on AIDL interface
+// lifetimes across processes and for protecting asynchronous calls across AIDL.
 
-namespace android::hardware::neuralnetworks::adapter {
+namespace aidl::android::hardware::neuralnetworks::adapter {
 
 /**
  * A self-contained unit of work to be executed.
@@ -37,25 +37,26 @@
 /**
  * A type-erased executor which executes a task asynchronously.
  *
- * This executor is also provided with an Application ID (Android User ID) and an optional deadline
- * for when the caller expects is the upper bound for the amount of time to complete the task.
+ * This executor is also provided an optional deadline for when the caller expects is the upper
+ * bound for the amount of time to complete the task. If needed, the Executor can retrieve the
+ * Application ID (Android User ID) by calling AIBinder_getCallingUid in android/binder_ibinder.h.
  */
-using Executor = std::function<void(Task, uid_t, nn::OptionalTimePoint)>;
+using Executor = std::function<void(Task, ::android::nn::OptionalTimePoint)>;
 
 /**
- * Adapt an NNAPI canonical interface object to a HIDL NN HAL interface object.
+ * Adapt an NNAPI canonical interface object to a AIDL NN HAL interface object.
  *
  * The IPreparedModel object created from IDevice::prepareModel or IDevice::preparedModelFromCache
  * must return "const nn::Model*" from IPreparedModel::getUnderlyingResource().
  *
  * @param device NNAPI canonical IDevice interface object to be adapted.
  * @param executor Type-erased executor to handle executing tasks asynchronously.
- * @return HIDL NN HAL IDevice interface object.
+ * @return AIDL NN HAL IDevice interface object.
  */
-sp<V1_3::IDevice> adapt(nn::SharedDevice device, Executor executor);
+std::shared_ptr<BnDevice> adapt(::android::nn::SharedDevice device, Executor executor);
 
 /**
- * Adapt an NNAPI canonical interface object to a HIDL NN HAL interface object.
+ * Adapt an NNAPI canonical interface object to a AIDL NN HAL interface object.
  *
  * The IPreparedModel object created from IDevice::prepareModel or IDevice::preparedModelFromCache
  * must return "const nn::Model*" from IPreparedModel::getUnderlyingResource().
@@ -63,10 +64,10 @@
  * This function uses a default executor, which will execute tasks from a detached thread.
  *
  * @param device NNAPI canonical IDevice interface object to be adapted.
- * @return HIDL NN HAL IDevice interface object.
+ * @return AIDL NN HAL IDevice interface object.
  */
-sp<V1_3::IDevice> adapt(nn::SharedDevice device);
+std::shared_ptr<BnDevice> adapt(::android::nn::SharedDevice device);
 
-}  // namespace android::hardware::neuralnetworks::adapter
+}  // namespace aidl::android::hardware::neuralnetworks::adapter
 
-#endif  // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_ADAPTER_H
+#endif  // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_ADAPTER_H
diff --git a/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Buffer.h b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Buffer.h
new file mode 100644
index 0000000..701e43e
--- /dev/null
+++ b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Buffer.h
@@ -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.
+ */
+
+#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_BUFFER_H
+#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_BUFFER_H
+
+#include <aidl/android/hardware/neuralnetworks/BnBuffer.h>
+#include <aidl/android/hardware/neuralnetworks/Memory.h>
+#include <android/binder_auto_utils.h>
+#include <nnapi/IBuffer.h>
+
+#include <memory>
+#include <vector>
+
+// See hardware/interfaces/neuralnetworks/utils/README.md for more information on AIDL interface
+// lifetimes across processes and for protecting asynchronous calls across AIDL.
+
+namespace aidl::android::hardware::neuralnetworks::adapter {
+
+// Class that adapts nn::IBuffer to BnBuffer.
+class Buffer : public BnBuffer {
+  public:
+    explicit Buffer(::android::nn::SharedBuffer buffer);
+
+    ndk::ScopedAStatus copyFrom(const Memory& src, const std::vector<int32_t>& dimensions) override;
+    ndk::ScopedAStatus copyTo(const Memory& dst) override;
+
+  private:
+    const ::android::nn::SharedBuffer kBuffer;
+};
+
+}  // namespace aidl::android::hardware::neuralnetworks::adapter
+
+#endif  // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_BUFFER_H
diff --git a/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Burst.h b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Burst.h
new file mode 100644
index 0000000..f2687c4
--- /dev/null
+++ b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Burst.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_BURST_H
+#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_BURST_H
+
+#include <aidl/android/hardware/neuralnetworks/BnBurst.h>
+#include <aidl/android/hardware/neuralnetworks/ExecutionResult.h>
+#include <aidl/android/hardware/neuralnetworks/Request.h>
+#include <android-base/thread_annotations.h>
+#include <android/binder_auto_utils.h>
+#include <nnapi/IBurst.h>
+#include <nnapi/Types.h>
+
+#include <memory>
+#include <mutex>
+#include <unordered_map>
+#include <vector>
+
+// See hardware/interfaces/neuralnetworks/utils/README.md for more information on AIDL interface
+// lifetimes across processes and for protecting asynchronous calls across AIDL.
+
+namespace aidl::android::hardware::neuralnetworks::adapter {
+
+// Class that adapts nn::Burst to BnBurst.
+class Burst : public BnBurst {
+  public:
+    // Precondition: burst != nullptr
+    explicit Burst(::android::nn::SharedBurst burst);
+
+    ndk::ScopedAStatus executeSynchronously(const Request& request,
+                                            const std::vector<int64_t>& memoryIdentifierTokens,
+                                            bool measureTiming, int64_t deadlineNs,
+                                            int64_t loopTimeoutDurationNs,
+                                            ExecutionResult* executionResult) override;
+    ndk::ScopedAStatus releaseMemoryResource(int64_t memoryIdentifierToken) override;
+
+    class ThreadSafeMemoryCache {
+      public:
+        using Value =
+                std::pair<::android::nn::SharedMemory, ::android::nn::IBurst::OptionalCacheHold>;
+
+        Value add(int64_t token, const ::android::nn::SharedMemory& memory,
+                  const ::android::nn::IBurst& burst) const;
+        void remove(int64_t token) const;
+
+      private:
+        mutable std::mutex mMutex;
+        mutable std::unordered_map<int64_t, Value> mCache GUARDED_BY(mMutex);
+    };
+
+  private:
+    const ::android::nn::SharedBurst kBurst;
+    const ThreadSafeMemoryCache kMemoryCache;
+};
+
+}  // namespace aidl::android::hardware::neuralnetworks::adapter
+
+#endif  // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_BURST_H
diff --git a/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Device.h b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Device.h
new file mode 100644
index 0000000..aa29d63
--- /dev/null
+++ b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Device.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_DEVICE_H
+#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_DEVICE_H
+
+#include "nnapi/hal/aidl/Adapter.h"
+
+#include <aidl/android/hardware/neuralnetworks/BnDevice.h>
+#include <aidl/android/hardware/neuralnetworks/BufferDesc.h>
+#include <aidl/android/hardware/neuralnetworks/BufferRole.h>
+#include <aidl/android/hardware/neuralnetworks/Capabilities.h>
+#include <aidl/android/hardware/neuralnetworks/DeviceBuffer.h>
+#include <aidl/android/hardware/neuralnetworks/DeviceType.h>
+#include <aidl/android/hardware/neuralnetworks/ExecutionPreference.h>
+#include <aidl/android/hardware/neuralnetworks/Extension.h>
+#include <aidl/android/hardware/neuralnetworks/IPreparedModelCallback.h>
+#include <aidl/android/hardware/neuralnetworks/IPreparedModelParcel.h>
+#include <aidl/android/hardware/neuralnetworks/Model.h>
+#include <aidl/android/hardware/neuralnetworks/NumberOfCacheFiles.h>
+#include <aidl/android/hardware/neuralnetworks/Priority.h>
+#include <android/binder_auto_utils.h>
+#include <nnapi/IDevice.h>
+
+#include <memory>
+#include <string>
+#include <vector>
+
+// See hardware/interfaces/neuralnetworks/utils/README.md for more information on AIDL interface
+// lifetimes across processes and for protecting asynchronous calls across AIDL.
+
+namespace aidl::android::hardware::neuralnetworks::adapter {
+
+// Class that adapts nn::IDevice to BnDevice.
+class Device : public BnDevice {
+  public:
+    Device(::android::nn::SharedDevice device, Executor executor);
+
+    ndk::ScopedAStatus allocate(const BufferDesc& desc,
+                                const std::vector<IPreparedModelParcel>& preparedModels,
+                                const std::vector<BufferRole>& inputRoles,
+                                const std::vector<BufferRole>& outputRoles,
+                                DeviceBuffer* buffer) override;
+    ndk::ScopedAStatus getCapabilities(Capabilities* capabilities) override;
+    ndk::ScopedAStatus getNumberOfCacheFilesNeeded(NumberOfCacheFiles* numberOfCacheFiles) override;
+    ndk::ScopedAStatus getSupportedExtensions(std::vector<Extension>* extensions) override;
+    ndk::ScopedAStatus getSupportedOperations(const Model& model,
+                                              std::vector<bool>* supported) override;
+    ndk::ScopedAStatus getType(DeviceType* deviceType) override;
+    ndk::ScopedAStatus getVersionString(std::string* version) override;
+    ndk::ScopedAStatus prepareModel(
+            const Model& model, ExecutionPreference preference, Priority priority,
+            int64_t deadlineNs, const std::vector<ndk::ScopedFileDescriptor>& modelCache,
+            const std::vector<ndk::ScopedFileDescriptor>& dataCache,
+            const std::vector<uint8_t>& token,
+            const std::shared_ptr<IPreparedModelCallback>& callback) override;
+    ndk::ScopedAStatus prepareModelFromCache(
+            int64_t deadlineNs, const std::vector<ndk::ScopedFileDescriptor>& modelCache,
+            const std::vector<ndk::ScopedFileDescriptor>& dataCache,
+            const std::vector<uint8_t>& token,
+            const std::shared_ptr<IPreparedModelCallback>& callback) override;
+
+  protected:
+    const ::android::nn::SharedDevice kDevice;
+    const Executor kExecutor;
+};
+
+}  // namespace aidl::android::hardware::neuralnetworks::adapter
+
+#endif  // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_DEVICE_H
diff --git a/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/PreparedModel.h b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/PreparedModel.h
new file mode 100644
index 0000000..93e0427
--- /dev/null
+++ b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/PreparedModel.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_PREPARED_MDOEL_H
+#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_PREPARED_MDOEL_H
+
+#include "nnapi/hal/aidl/Adapter.h"
+
+#include <aidl/android/hardware/neuralnetworks/BnPreparedModel.h>
+#include <aidl/android/hardware/neuralnetworks/ExecutionResult.h>
+#include <aidl/android/hardware/neuralnetworks/FencedExecutionResult.h>
+#include <aidl/android/hardware/neuralnetworks/IBurst.h>
+#include <aidl/android/hardware/neuralnetworks/Request.h>
+#include <android/binder_auto_utils.h>
+#include <nnapi/IPreparedModel.h>
+#include <nnapi/Types.h>
+
+#include <memory>
+#include <vector>
+
+// See hardware/interfaces/neuralnetworks/utils/README.md for more information on AIDL interface
+// lifetimes across processes and for protecting asynchronous calls across AIDL.
+
+namespace aidl::android::hardware::neuralnetworks::adapter {
+
+// Class that adapts nn::IPreparedModel to BnPreparedModel.
+class PreparedModel : public BnPreparedModel {
+  public:
+    explicit PreparedModel(::android::nn::SharedPreparedModel preparedModel);
+
+    ndk::ScopedAStatus executeSynchronously(const Request& request, bool measureTiming,
+                                            int64_t deadlineNs, int64_t loopTimeoutDurationNs,
+                                            ExecutionResult* executionResult) override;
+    ndk::ScopedAStatus executeFenced(const Request& request,
+                                     const std::vector<ndk::ScopedFileDescriptor>& waitFor,
+                                     bool measureTiming, int64_t deadlineNs,
+                                     int64_t loopTimeoutDurationNs, int64_t durationNs,
+                                     FencedExecutionResult* executionResult) override;
+    ndk::ScopedAStatus configureExecutionBurst(std::shared_ptr<IBurst>* burst) override;
+
+    ::android::nn::SharedPreparedModel getUnderlyingPreparedModel() const;
+
+  protected:
+    const ::android::nn::SharedPreparedModel kPreparedModel;
+};
+
+}  // namespace aidl::android::hardware::neuralnetworks::adapter
+
+#endif  // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_PREPARED_MDOEL_H
diff --git a/neuralnetworks/utils/adapter/aidl/src/Adapter.cpp b/neuralnetworks/utils/adapter/aidl/src/Adapter.cpp
new file mode 100644
index 0000000..d0b56e8
--- /dev/null
+++ b/neuralnetworks/utils/adapter/aidl/src/Adapter.cpp
@@ -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.
+ */
+
+#include "Adapter.h"
+
+#include "Device.h"
+
+#include <aidl/android/hardware/neuralnetworks/BnDevice.h>
+#include <android/binder_interface_utils.h>
+#include <nnapi/IDevice.h>
+#include <nnapi/Types.h>
+
+#include <functional>
+#include <memory>
+#include <thread>
+
+// See hardware/interfaces/neuralnetworks/utils/README.md for more information on AIDL interface
+// lifetimes across processes and for protecting asynchronous calls across AIDL.
+
+namespace aidl::android::hardware::neuralnetworks::adapter {
+
+std::shared_ptr<BnDevice> adapt(::android::nn::SharedDevice device, Executor executor) {
+    return ndk::SharedRefBase::make<Device>(std::move(device), std::move(executor));
+}
+
+std::shared_ptr<BnDevice> adapt(::android::nn::SharedDevice device) {
+    Executor defaultExecutor = [](Task task, ::android::nn::OptionalTimePoint /*deadline*/) {
+        std::thread(std::move(task)).detach();
+    };
+    return adapt(std::move(device), std::move(defaultExecutor));
+}
+
+}  // namespace aidl::android::hardware::neuralnetworks::adapter
diff --git a/neuralnetworks/utils/adapter/aidl/src/Buffer.cpp b/neuralnetworks/utils/adapter/aidl/src/Buffer.cpp
new file mode 100644
index 0000000..c15ab65
--- /dev/null
+++ b/neuralnetworks/utils/adapter/aidl/src/Buffer.cpp
@@ -0,0 +1,88 @@
+/*
+ * 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 "Buffer.h"
+
+#include <aidl/android/hardware/neuralnetworks/BnBuffer.h>
+#include <aidl/android/hardware/neuralnetworks/Memory.h>
+#include <android-base/logging.h>
+#include <android/binder_auto_utils.h>
+#include <nnapi/IBuffer.h>
+#include <nnapi/Result.h>
+#include <nnapi/Types.h>
+#include <nnapi/hal/aidl/Conversions.h>
+
+namespace aidl::android::hardware::neuralnetworks::adapter {
+namespace {
+
+template <typename Type>
+auto convertInput(const Type& object) -> decltype(nn::convert(std::declval<Type>())) {
+    auto result = nn::convert(object);
+    if (!result.has_value()) {
+        result.error().code = nn::ErrorStatus::INVALID_ARGUMENT;
+    }
+    return result;
+}
+
+nn::GeneralResult<std::vector<uint32_t>> inputToUnsigned(const std::vector<int32_t>& dims) {
+    auto result = nn::toUnsigned(dims);
+    if (!result.has_value()) {
+        result.error().code = nn::ErrorStatus::INVALID_ARGUMENT;
+    }
+    return result;
+}
+
+nn::GeneralResult<void> copyTo(const nn::IBuffer& buffer, const Memory& dst) {
+    const auto nnDst = NN_TRY(convertInput(dst));
+    return buffer.copyTo(nnDst);
+}
+
+nn::GeneralResult<void> copyFrom(const nn::IBuffer& buffer, const Memory& src,
+                                 const std::vector<int32_t>& dimensions) {
+    const auto nnSrc = NN_TRY(convertInput(src));
+    const auto nnDims = NN_TRY(inputToUnsigned(dimensions));
+    return buffer.copyFrom(nnSrc, nnDims);
+}
+
+}  // namespace
+
+Buffer::Buffer(nn::SharedBuffer buffer) : kBuffer(std::move(buffer)) {
+    CHECK(kBuffer != nullptr);
+}
+
+ndk::ScopedAStatus Buffer::copyTo(const Memory& dst) {
+    const auto result = adapter::copyTo(*kBuffer, dst);
+    if (!result.has_value()) {
+        const auto& [message, code] = result.error();
+        const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE);
+        return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                static_cast<int32_t>(aidlCode), message.c_str());
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Buffer::copyFrom(const Memory& src, const std::vector<int32_t>& dimensions) {
+    const auto result = adapter::copyFrom(*kBuffer, src, dimensions);
+    if (!result.has_value()) {
+        const auto& [message, code] = result.error();
+        const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE);
+        return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                static_cast<int32_t>(aidlCode), message.c_str());
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+}  // namespace aidl::android::hardware::neuralnetworks::adapter
diff --git a/neuralnetworks/utils/adapter/aidl/src/Burst.cpp b/neuralnetworks/utils/adapter/aidl/src/Burst.cpp
new file mode 100644
index 0000000..4fabb20
--- /dev/null
+++ b/neuralnetworks/utils/adapter/aidl/src/Burst.cpp
@@ -0,0 +1,179 @@
+/*
+ * 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 "Burst.h"
+
+#include <android-base/logging.h>
+#include <android-base/thread_annotations.h>
+#include <android/binder_auto_utils.h>
+#include <nnapi/IBurst.h>
+#include <nnapi/Result.h>
+#include <nnapi/Types.h>
+#include <nnapi/Validation.h>
+#include <nnapi/hal/aidl/Conversions.h>
+#include <nnapi/hal/aidl/Utils.h>
+
+#include <algorithm>
+#include <chrono>
+#include <memory>
+#include <mutex>
+#include <unordered_map>
+#include <utility>
+#include <variant>
+
+namespace aidl::android::hardware::neuralnetworks::adapter {
+namespace {
+
+using Value = Burst::ThreadSafeMemoryCache::Value;
+
+template <typename Type>
+auto convertInput(const Type& object) -> decltype(nn::convert(std::declval<Type>())) {
+    auto result = nn::convert(object);
+    if (!result.has_value()) {
+        result.error().code = nn::ErrorStatus::INVALID_ARGUMENT;
+    }
+    return result;
+}
+
+nn::Duration makeDuration(int64_t durationNs) {
+    return nn::Duration(std::chrono::nanoseconds(durationNs));
+}
+
+nn::GeneralResult<nn::OptionalDuration> makeOptionalDuration(int64_t durationNs) {
+    if (durationNs < -1) {
+        return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid duration " << durationNs;
+    }
+    return durationNs < 0 ? nn::OptionalDuration{} : makeDuration(durationNs);
+}
+
+nn::GeneralResult<nn::OptionalTimePoint> makeOptionalTimePoint(int64_t durationNs) {
+    if (durationNs < -1) {
+        return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid time point " << durationNs;
+    }
+    return durationNs < 0 ? nn::OptionalTimePoint{} : nn::TimePoint(makeDuration(durationNs));
+}
+
+std::vector<nn::IBurst::OptionalCacheHold> ensureAllMemoriesAreCached(
+        nn::Request* request, const std::vector<int64_t>& memoryIdentifierTokens,
+        const nn::IBurst& burst, const Burst::ThreadSafeMemoryCache& cache) {
+    std::vector<nn::IBurst::OptionalCacheHold> holds;
+    holds.reserve(memoryIdentifierTokens.size());
+
+    for (size_t i = 0; i < memoryIdentifierTokens.size(); ++i) {
+        const auto& pool = request->pools[i];
+        const auto token = memoryIdentifierTokens[i];
+        constexpr int64_t kNoToken = -1;
+        if (token == kNoToken || !std::holds_alternative<nn::SharedMemory>(pool)) {
+            continue;
+        }
+
+        const auto& memory = std::get<nn::SharedMemory>(pool);
+        auto [storedMemory, hold] = cache.add(token, memory, burst);
+
+        request->pools[i] = std::move(storedMemory);
+        holds.push_back(std::move(hold));
+    }
+
+    return holds;
+}
+
+nn::ExecutionResult<ExecutionResult> executeSynchronously(
+        const nn::IBurst& burst, const Burst::ThreadSafeMemoryCache& cache, const Request& request,
+        const std::vector<int64_t>& memoryIdentifierTokens, bool measureTiming, int64_t deadlineNs,
+        int64_t loopTimeoutDurationNs) {
+    if (request.pools.size() != memoryIdentifierTokens.size()) {
+        return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT)
+               << "request.pools.size() != memoryIdentifierTokens.size()";
+    }
+    if (!std::all_of(memoryIdentifierTokens.begin(), memoryIdentifierTokens.end(),
+                     [](int64_t token) { return token >= -1; })) {
+        return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid memoryIdentifierTokens";
+    }
+
+    auto nnRequest = NN_TRY(convertInput(request));
+    const auto nnMeasureTiming = measureTiming ? nn::MeasureTiming::YES : nn::MeasureTiming::NO;
+    const auto nnDeadline = NN_TRY(makeOptionalTimePoint(deadlineNs));
+    const auto nnLoopTimeoutDuration = NN_TRY(makeOptionalDuration(loopTimeoutDurationNs));
+
+    const auto hold = ensureAllMemoriesAreCached(&nnRequest, memoryIdentifierTokens, burst, cache);
+
+    const auto result =
+            burst.execute(nnRequest, nnMeasureTiming, nnDeadline, nnLoopTimeoutDuration);
+
+    if (!result.ok() && result.error().code == nn::ErrorStatus::OUTPUT_INSUFFICIENT_SIZE) {
+        const auto& [message, code, outputShapes] = result.error();
+        return ExecutionResult{.outputSufficientSize = false,
+                               .outputShapes = utils::convert(outputShapes).value(),
+                               .timing = {.timeInDriverNs = -1, .timeOnDeviceNs = -1}};
+    }
+
+    const auto& [outputShapes, timing] = NN_TRY(result);
+    return ExecutionResult{.outputSufficientSize = true,
+                           .outputShapes = utils::convert(outputShapes).value(),
+                           .timing = utils::convert(timing).value()};
+}
+
+}  // namespace
+
+Value Burst::ThreadSafeMemoryCache::add(int64_t token, const nn::SharedMemory& memory,
+                                        const nn::IBurst& burst) const {
+    std::lock_guard guard(mMutex);
+    if (const auto it = mCache.find(token); it != mCache.end()) {
+        return it->second;
+    }
+    auto hold = burst.cacheMemory(memory);
+    auto [it, _] = mCache.emplace(token, std::make_pair(memory, std::move(hold)));
+    return it->second;
+}
+
+void Burst::ThreadSafeMemoryCache::remove(int64_t token) const {
+    std::lock_guard guard(mMutex);
+    mCache.erase(token);
+}
+
+Burst::Burst(nn::SharedBurst burst) : kBurst(std::move(burst)) {
+    CHECK(kBurst != nullptr);
+}
+
+ndk::ScopedAStatus Burst::executeSynchronously(const Request& request,
+                                               const std::vector<int64_t>& memoryIdentifierTokens,
+                                               bool measureTiming, int64_t deadlineNs,
+                                               int64_t loopTimeoutDurationNs,
+                                               ExecutionResult* executionResult) {
+    auto result =
+            adapter::executeSynchronously(*kBurst, kMemoryCache, request, memoryIdentifierTokens,
+                                          measureTiming, deadlineNs, loopTimeoutDurationNs);
+    if (!result.has_value()) {
+        auto [message, code, _] = std::move(result).error();
+        const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE);
+        return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                static_cast<int32_t>(aidlCode), message.c_str());
+    }
+    *executionResult = std::move(result).value();
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Burst::releaseMemoryResource(int64_t memoryIdentifierToken) {
+    if (memoryIdentifierToken < -1) {
+        return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                static_cast<int32_t>(ErrorStatus::INVALID_ARGUMENT),
+                "Invalid memoryIdentifierToken");
+    }
+    kMemoryCache.remove(memoryIdentifierToken);
+    return ndk::ScopedAStatus::ok();
+}
+
+}  // namespace aidl::android::hardware::neuralnetworks::adapter
diff --git a/neuralnetworks/utils/adapter/aidl/src/Device.cpp b/neuralnetworks/utils/adapter/aidl/src/Device.cpp
new file mode 100644
index 0000000..763be7f
--- /dev/null
+++ b/neuralnetworks/utils/adapter/aidl/src/Device.cpp
@@ -0,0 +1,304 @@
+/*
+ * 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 "Device.h"
+
+#include "Adapter.h"
+#include "Buffer.h"
+#include "PreparedModel.h"
+
+#include <aidl/android/hardware/neuralnetworks/BnDevice.h>
+#include <aidl/android/hardware/neuralnetworks/BufferDesc.h>
+#include <aidl/android/hardware/neuralnetworks/BufferRole.h>
+#include <aidl/android/hardware/neuralnetworks/DeviceBuffer.h>
+#include <aidl/android/hardware/neuralnetworks/DeviceType.h>
+#include <aidl/android/hardware/neuralnetworks/ErrorStatus.h>
+#include <aidl/android/hardware/neuralnetworks/ExecutionPreference.h>
+#include <aidl/android/hardware/neuralnetworks/Extension.h>
+#include <aidl/android/hardware/neuralnetworks/IPreparedModelCallback.h>
+#include <aidl/android/hardware/neuralnetworks/IPreparedModelParcel.h>
+#include <aidl/android/hardware/neuralnetworks/Model.h>
+#include <aidl/android/hardware/neuralnetworks/NumberOfCacheFiles.h>
+#include <aidl/android/hardware/neuralnetworks/Priority.h>
+#include <android-base/logging.h>
+#include <android/binder_auto_utils.h>
+#include <android/binder_interface_utils.h>
+#include <nnapi/IDevice.h>
+#include <nnapi/Result.h>
+#include <nnapi/TypeUtils.h>
+#include <nnapi/Types.h>
+#include <nnapi/hal/aidl/Conversions.h>
+
+#include <chrono>
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace aidl::android::hardware::neuralnetworks::adapter {
+namespace {
+
+template <typename Type>
+auto convertInput(const Type& object) -> decltype(nn::convert(std::declval<Type>())) {
+    auto result = nn::convert(object);
+    if (!result.has_value()) {
+        result.error().code = nn::ErrorStatus::INVALID_ARGUMENT;
+    }
+    return result;
+}
+
+nn::Duration makeDuration(int64_t durationNs) {
+    return nn::Duration(std::chrono::nanoseconds(durationNs));
+}
+
+nn::GeneralResult<nn::OptionalTimePoint> makeOptionalTimePoint(int64_t durationNs) {
+    if (durationNs < -1) {
+        return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid time point " << durationNs;
+    }
+    return durationNs < 0 ? nn::OptionalTimePoint{} : nn::TimePoint(makeDuration(durationNs));
+}
+
+nn::GeneralResult<nn::CacheToken> convertCacheToken(const std::vector<uint8_t>& token) {
+    nn::CacheToken nnToken;
+    if (token.size() != nnToken.size()) {
+        return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid token";
+    }
+    std::copy(token.begin(), token.end(), nnToken.begin());
+    return nnToken;
+}
+
+nn::GeneralResult<nn::SharedPreparedModel> downcast(const IPreparedModelParcel& preparedModel) {
+    if (preparedModel.preparedModel == nullptr) {
+        return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "preparedModel is nullptr";
+    }
+    if (preparedModel.preparedModel->isRemote()) {
+        return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Cannot convert remote models";
+    }
+
+    // This static_cast is safe because adapter::PreparedModel is the only class that implements
+    // the IPreparedModel interface in the adapter service code.
+    const auto* casted = static_cast<const PreparedModel*>(preparedModel.preparedModel.get());
+    return casted->getUnderlyingPreparedModel();
+}
+
+nn::GeneralResult<std::vector<nn::SharedPreparedModel>> downcastAll(
+        const std::vector<IPreparedModelParcel>& preparedModels) {
+    std::vector<nn::SharedPreparedModel> canonical;
+    canonical.reserve(preparedModels.size());
+    for (const auto& preparedModel : preparedModels) {
+        canonical.push_back(NN_TRY(downcast(preparedModel)));
+    }
+    return canonical;
+}
+
+nn::GeneralResult<DeviceBuffer> allocate(const nn::IDevice& device, const BufferDesc& desc,
+                                         const std::vector<IPreparedModelParcel>& preparedModels,
+                                         const std::vector<BufferRole>& inputRoles,
+                                         const std::vector<BufferRole>& outputRoles) {
+    auto nnDesc = NN_TRY(convertInput(desc));
+    auto nnPreparedModels = NN_TRY(downcastAll(preparedModels));
+    auto nnInputRoles = NN_TRY(convertInput(inputRoles));
+    auto nnOutputRoles = NN_TRY(convertInput(outputRoles));
+
+    auto buffer = NN_TRY(device.allocate(nnDesc, nnPreparedModels, nnInputRoles, nnOutputRoles));
+    CHECK(buffer != nullptr);
+
+    const nn::Request::MemoryDomainToken token = buffer->getToken();
+    auto aidlBuffer = ndk::SharedRefBase::make<Buffer>(std::move(buffer));
+    return DeviceBuffer{.buffer = std::move(aidlBuffer), .token = static_cast<int32_t>(token)};
+}
+
+nn::GeneralResult<std::vector<bool>> getSupportedOperations(const nn::IDevice& device,
+                                                            const Model& model) {
+    const auto nnModel = NN_TRY(convertInput(model));
+    return device.getSupportedOperations(nnModel);
+}
+
+using PrepareModelResult = nn::GeneralResult<nn::SharedPreparedModel>;
+
+std::shared_ptr<PreparedModel> adaptPreparedModel(nn::SharedPreparedModel preparedModel) {
+    if (preparedModel == nullptr) {
+        return nullptr;
+    }
+    return ndk::SharedRefBase::make<PreparedModel>(std::move(preparedModel));
+}
+
+void notify(IPreparedModelCallback* callback, PrepareModelResult result) {
+    if (!result.has_value()) {
+        const auto& [message, status] = result.error();
+        LOG(ERROR) << message;
+        const auto aidlCode = utils::convert(status).value_or(ErrorStatus::GENERAL_FAILURE);
+        callback->notify(aidlCode, nullptr);
+    } else {
+        auto preparedModel = std::move(result).value();
+        auto aidlPreparedModel = adaptPreparedModel(std::move(preparedModel));
+        callback->notify(ErrorStatus::NONE, std::move(aidlPreparedModel));
+    }
+}
+
+nn::GeneralResult<void> prepareModel(const nn::SharedDevice& device, const Executor& executor,
+                                     const Model& model, ExecutionPreference preference,
+                                     Priority priority, int64_t deadlineNs,
+                                     const std::vector<ndk::ScopedFileDescriptor>& modelCache,
+                                     const std::vector<ndk::ScopedFileDescriptor>& dataCache,
+                                     const std::vector<uint8_t>& token,
+                                     const std::shared_ptr<IPreparedModelCallback>& callback) {
+    if (callback.get() == nullptr) {
+        return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid callback";
+    }
+
+    auto nnModel = NN_TRY(convertInput(model));
+    const auto nnPreference = NN_TRY(convertInput(preference));
+    const auto nnPriority = NN_TRY(convertInput(priority));
+    const auto nnDeadline = NN_TRY(makeOptionalTimePoint(deadlineNs));
+    auto nnModelCache = NN_TRY(convertInput(modelCache));
+    auto nnDataCache = NN_TRY(convertInput(dataCache));
+    const auto nnToken = NN_TRY(convertCacheToken(token));
+
+    Task task = [device, nnModel = std::move(nnModel), nnPreference, nnPriority, nnDeadline,
+                 nnModelCache = std::move(nnModelCache), nnDataCache = std::move(nnDataCache),
+                 nnToken, callback] {
+        auto result = device->prepareModel(nnModel, nnPreference, nnPriority, nnDeadline,
+                                           nnModelCache, nnDataCache, nnToken);
+        notify(callback.get(), std::move(result));
+    };
+    executor(std::move(task), nnDeadline);
+
+    return {};
+}
+
+nn::GeneralResult<void> prepareModelFromCache(
+        const nn::SharedDevice& device, const Executor& executor, int64_t deadlineNs,
+        const std::vector<ndk::ScopedFileDescriptor>& modelCache,
+        const std::vector<ndk::ScopedFileDescriptor>& dataCache, const std::vector<uint8_t>& token,
+        const std::shared_ptr<IPreparedModelCallback>& callback) {
+    if (callback.get() == nullptr) {
+        return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid callback";
+    }
+
+    const auto nnDeadline = NN_TRY(makeOptionalTimePoint(deadlineNs));
+    auto nnModelCache = NN_TRY(convertInput(modelCache));
+    auto nnDataCache = NN_TRY(convertInput(dataCache));
+    const auto nnToken = NN_TRY(convertCacheToken(token));
+
+    auto task = [device, nnDeadline, nnModelCache = std::move(nnModelCache),
+                 nnDataCache = std::move(nnDataCache), nnToken, callback] {
+        auto result = device->prepareModelFromCache(nnDeadline, nnModelCache, nnDataCache, nnToken);
+        notify(callback.get(), std::move(result));
+    };
+    executor(std::move(task), nnDeadline);
+
+    return {};
+}
+
+}  // namespace
+
+Device::Device(::android::nn::SharedDevice device, Executor executor)
+    : kDevice(std::move(device)), kExecutor(std::move(executor)) {
+    CHECK(kDevice != nullptr);
+    CHECK(kExecutor != nullptr);
+}
+
+ndk::ScopedAStatus Device::allocate(const BufferDesc& desc,
+                                    const std::vector<IPreparedModelParcel>& preparedModels,
+                                    const std::vector<BufferRole>& inputRoles,
+                                    const std::vector<BufferRole>& outputRoles,
+                                    DeviceBuffer* buffer) {
+    auto result = adapter::allocate(*kDevice, desc, preparedModels, inputRoles, outputRoles);
+    if (!result.has_value()) {
+        const auto& [message, code] = result.error();
+        const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE);
+        return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                static_cast<int32_t>(aidlCode), message.c_str());
+    }
+    *buffer = std::move(result).value();
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Device::getCapabilities(Capabilities* capabilities) {
+    *capabilities = utils::convert(kDevice->getCapabilities()).value();
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Device::getNumberOfCacheFilesNeeded(NumberOfCacheFiles* numberOfCacheFiles) {
+    const auto [numModelCache, numDataCache] = kDevice->getNumberOfCacheFilesNeeded();
+    *numberOfCacheFiles = NumberOfCacheFiles{.numModelCache = static_cast<int32_t>(numModelCache),
+                                             .numDataCache = static_cast<int32_t>(numDataCache)};
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Device::getSupportedExtensions(std::vector<Extension>* extensions) {
+    *extensions = utils::convert(kDevice->getSupportedExtensions()).value();
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Device::getSupportedOperations(const Model& model,
+                                                  std::vector<bool>* supported) {
+    auto result = adapter::getSupportedOperations(*kDevice, model);
+    if (!result.has_value()) {
+        const auto& [message, code] = result.error();
+        const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE);
+        return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                static_cast<int32_t>(aidlCode), message.c_str());
+    }
+    *supported = std::move(result).value();
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Device::getType(DeviceType* deviceType) {
+    *deviceType = utils::convert(kDevice->getType()).value();
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Device::getVersionString(std::string* version) {
+    *version = kDevice->getVersionString();
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Device::prepareModel(const Model& model, ExecutionPreference preference,
+                                        Priority priority, int64_t deadlineNs,
+                                        const std::vector<ndk::ScopedFileDescriptor>& modelCache,
+                                        const std::vector<ndk::ScopedFileDescriptor>& dataCache,
+                                        const std::vector<uint8_t>& token,
+                                        const std::shared_ptr<IPreparedModelCallback>& callback) {
+    const auto result = adapter::prepareModel(kDevice, kExecutor, model, preference, priority,
+                                              deadlineNs, modelCache, dataCache, token, callback);
+    if (!result.has_value()) {
+        const auto& [message, code] = result.error();
+        const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE);
+        callback->notify(aidlCode, nullptr);
+        return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                static_cast<int32_t>(aidlCode), message.c_str());
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Device::prepareModelFromCache(
+        int64_t deadlineNs, const std::vector<ndk::ScopedFileDescriptor>& modelCache,
+        const std::vector<ndk::ScopedFileDescriptor>& dataCache, const std::vector<uint8_t>& token,
+        const std::shared_ptr<IPreparedModelCallback>& callback) {
+    const auto result = adapter::prepareModelFromCache(kDevice, kExecutor, deadlineNs, modelCache,
+                                                       dataCache, token, callback);
+    if (!result.has_value()) {
+        const auto& [message, code] = result.error();
+        const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE);
+        callback->notify(aidlCode, nullptr);
+        return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                static_cast<int32_t>(aidlCode), message.c_str());
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+}  // namespace aidl::android::hardware::neuralnetworks::adapter
diff --git a/neuralnetworks/utils/adapter/aidl/src/PreparedModel.cpp b/neuralnetworks/utils/adapter/aidl/src/PreparedModel.cpp
new file mode 100644
index 0000000..71ed1a8
--- /dev/null
+++ b/neuralnetworks/utils/adapter/aidl/src/PreparedModel.cpp
@@ -0,0 +1,225 @@
+/*
+ * 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 "PreparedModel.h"
+
+#include "Burst.h"
+
+#include <aidl/android/hardware/neuralnetworks/BnFencedExecutionCallback.h>
+#include <aidl/android/hardware/neuralnetworks/BnPreparedModel.h>
+#include <aidl/android/hardware/neuralnetworks/ExecutionResult.h>
+#include <aidl/android/hardware/neuralnetworks/FencedExecutionResult.h>
+#include <aidl/android/hardware/neuralnetworks/IBurst.h>
+#include <aidl/android/hardware/neuralnetworks/Request.h>
+#include <android-base/logging.h>
+#include <android/binder_auto_utils.h>
+#include <nnapi/IPreparedModel.h>
+#include <nnapi/Result.h>
+#include <nnapi/SharedMemory.h>
+#include <nnapi/Types.h>
+#include <nnapi/Validation.h>
+#include <nnapi/hal/aidl/Conversions.h>
+#include <nnapi/hal/aidl/Utils.h>
+
+#include <memory>
+#include <utility>
+#include <vector>
+
+namespace aidl::android::hardware::neuralnetworks::adapter {
+namespace {
+
+class FencedExecutionCallback : public BnFencedExecutionCallback {
+  public:
+    FencedExecutionCallback(nn::ExecuteFencedInfoCallback callback)
+        : kCallback(std::move(callback)) {}
+
+    ndk::ScopedAStatus getExecutionInfo(Timing* timingLaunched, Timing* timingFenced,
+                                        ErrorStatus* errorStatus) override {
+        const auto result = kCallback();
+        if (result.ok()) {
+            const auto& [nnTimingLaunched, nnTimingFenced] = result.value();
+            *timingLaunched = utils::convert(nnTimingLaunched).value();
+            *timingFenced = utils::convert(nnTimingFenced).value();
+            *errorStatus = ErrorStatus::NONE;
+        } else {
+            constexpr auto kNoTiming = Timing{.timeOnDeviceNs = -1, .timeInDriverNs = -1};
+            const auto& [message, code] = result.error();
+            LOG(ERROR) << "getExecutionInfo failed with " << code << ": " << message;
+            const auto aidlStatus = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE);
+            *timingLaunched = kNoTiming;
+            *timingFenced = kNoTiming;
+            *errorStatus = aidlStatus;
+        }
+        return ndk::ScopedAStatus::ok();
+    }
+
+  private:
+    const nn::ExecuteFencedInfoCallback kCallback;
+};
+
+template <typename Type>
+auto convertInput(const Type& object) -> decltype(nn::convert(std::declval<Type>())) {
+    auto result = nn::convert(object);
+    if (!result.has_value()) {
+        result.error().code = nn::ErrorStatus::INVALID_ARGUMENT;
+    }
+    return result;
+}
+
+nn::GeneralResult<std::vector<nn::SyncFence>> convertSyncFences(
+        const std::vector<ndk::ScopedFileDescriptor>& waitFor) {
+    auto handles = NN_TRY(convertInput(waitFor));
+
+    constexpr auto valid = [](const nn::SharedHandle& handle) {
+        return handle != nullptr && handle->ok();
+    };
+    if (!std::all_of(handles.begin(), handles.end(), valid)) {
+        return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid sync fence";
+    }
+
+    std::vector<nn::SyncFence> syncFences;
+    syncFences.reserve(waitFor.size());
+    for (auto& handle : handles) {
+        syncFences.push_back(nn::SyncFence::create(std::move(handle)).value());
+    }
+    return syncFences;
+}
+
+nn::Duration makeDuration(int64_t durationNs) {
+    return nn::Duration(std::chrono::nanoseconds(durationNs));
+}
+
+nn::GeneralResult<nn::OptionalDuration> makeOptionalDuration(int64_t durationNs) {
+    if (durationNs < -1) {
+        return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid duration " << durationNs;
+    }
+    return durationNs < 0 ? nn::OptionalDuration{} : makeDuration(durationNs);
+}
+
+nn::GeneralResult<nn::OptionalTimePoint> makeOptionalTimePoint(int64_t durationNs) {
+    if (durationNs < -1) {
+        return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid time point " << durationNs;
+    }
+    return durationNs < 0 ? nn::OptionalTimePoint{} : nn::TimePoint(makeDuration(durationNs));
+}
+
+nn::ExecutionResult<ExecutionResult> executeSynchronously(const nn::IPreparedModel& preparedModel,
+                                                          const Request& request,
+                                                          bool measureTiming, int64_t deadlineNs,
+                                                          int64_t loopTimeoutDurationNs) {
+    const auto nnRequest = NN_TRY(convertInput(request));
+    const auto nnMeasureTiming = measureTiming ? nn::MeasureTiming::YES : nn::MeasureTiming::NO;
+    const auto nnDeadline = NN_TRY(makeOptionalTimePoint(deadlineNs));
+    const auto nnLoopTimeoutDuration = NN_TRY(makeOptionalDuration(loopTimeoutDurationNs));
+
+    const auto result =
+            preparedModel.execute(nnRequest, nnMeasureTiming, nnDeadline, nnLoopTimeoutDuration);
+
+    if (!result.ok() && result.error().code == nn::ErrorStatus::OUTPUT_INSUFFICIENT_SIZE) {
+        const auto& [message, code, outputShapes] = result.error();
+        LOG(ERROR) << "executeSynchronously failed with " << code << ": " << message;
+        return ExecutionResult{.outputSufficientSize = false,
+                               .outputShapes = utils::convert(outputShapes).value(),
+                               .timing = {.timeInDriverNs = -1, .timeOnDeviceNs = -1}};
+    }
+
+    const auto& [outputShapes, timing] = NN_TRY(result);
+    return ExecutionResult{.outputSufficientSize = true,
+                           .outputShapes = utils::convert(outputShapes).value(),
+                           .timing = utils::convert(timing).value()};
+}
+
+nn::GeneralResult<FencedExecutionResult> executeFenced(
+        const nn::IPreparedModel& preparedModel, const Request& request,
+        const std::vector<ndk::ScopedFileDescriptor>& waitFor, bool measureTiming,
+        int64_t deadlineNs, int64_t loopTimeoutDurationNs, int64_t durationNs) {
+    const auto nnRequest = NN_TRY(convertInput(request));
+    const auto nnWaitFor = NN_TRY(convertSyncFences(waitFor));
+    const auto nnMeasureTiming = measureTiming ? nn::MeasureTiming::YES : nn::MeasureTiming::NO;
+    const auto nnDeadline = NN_TRY(makeOptionalTimePoint(deadlineNs));
+    const auto nnLoopTimeoutDuration = NN_TRY(makeOptionalDuration(loopTimeoutDurationNs));
+    const auto nnDuration = NN_TRY(makeOptionalDuration(durationNs));
+
+    auto [syncFence, executeFencedInfoCallback] = NN_TRY(preparedModel.executeFenced(
+            nnRequest, nnWaitFor, nnMeasureTiming, nnDeadline, nnLoopTimeoutDuration, nnDuration));
+
+    ndk::ScopedFileDescriptor fileDescriptor;
+    if (syncFence.hasFd()) {
+        auto uniqueFd = NN_TRY(nn::dupFd(syncFence.getFd()));
+        fileDescriptor = ndk::ScopedFileDescriptor(uniqueFd.release());
+    }
+
+    return FencedExecutionResult{.callback = ndk::SharedRefBase::make<FencedExecutionCallback>(
+                                         std::move(executeFencedInfoCallback)),
+                                 .syncFence = std::move(fileDescriptor)};
+}
+
+}  // namespace
+
+PreparedModel::PreparedModel(nn::SharedPreparedModel preparedModel)
+    : kPreparedModel(std::move(preparedModel)) {
+    CHECK(kPreparedModel != nullptr);
+}
+
+ndk::ScopedAStatus PreparedModel::executeSynchronously(const Request& request, bool measureTiming,
+                                                       int64_t deadlineNs,
+                                                       int64_t loopTimeoutDurationNs,
+                                                       ExecutionResult* executionResult) {
+    auto result = adapter::executeSynchronously(*kPreparedModel, request, measureTiming, deadlineNs,
+                                                loopTimeoutDurationNs);
+    if (!result.has_value()) {
+        const auto& [message, code, _] = result.error();
+        const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE);
+        return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                static_cast<int32_t>(aidlCode), message.c_str());
+    }
+    *executionResult = std::move(result).value();
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus PreparedModel::executeFenced(
+        const Request& request, const std::vector<ndk::ScopedFileDescriptor>& waitFor,
+        bool measureTiming, int64_t deadlineNs, int64_t loopTimeoutDurationNs, int64_t durationNs,
+        FencedExecutionResult* executionResult) {
+    auto result = adapter::executeFenced(*kPreparedModel, request, waitFor, measureTiming,
+                                         deadlineNs, loopTimeoutDurationNs, durationNs);
+    if (!result.has_value()) {
+        const auto& [message, code] = result.error();
+        const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE);
+        return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                static_cast<int32_t>(aidlCode), message.c_str());
+    }
+    *executionResult = std::move(result).value();
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus PreparedModel::configureExecutionBurst(std::shared_ptr<IBurst>* burst) {
+    auto result = kPreparedModel->configureExecutionBurst();
+    if (!result.has_value()) {
+        const auto& [message, code] = result.error();
+        const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE);
+        return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                static_cast<int32_t>(aidlCode), message.c_str());
+    }
+    *burst = ndk::SharedRefBase::make<Burst>(std::move(result).value());
+    return ndk::ScopedAStatus::ok();
+}
+
+nn::SharedPreparedModel PreparedModel::getUnderlyingPreparedModel() const {
+    return kPreparedModel;
+}
+
+}  // namespace aidl::android::hardware::neuralnetworks::adapter
diff --git a/neuralnetworks/utils/adapter/Android.bp b/neuralnetworks/utils/adapter/hidl/Android.bp
similarity index 100%
rename from neuralnetworks/utils/adapter/Android.bp
rename to neuralnetworks/utils/adapter/hidl/Android.bp
diff --git a/neuralnetworks/utils/adapter/include/nnapi/hal/Adapter.h b/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/Adapter.h
similarity index 86%
rename from neuralnetworks/utils/adapter/include/nnapi/hal/Adapter.h
rename to neuralnetworks/utils/adapter/hidl/include/nnapi/hal/Adapter.h
index da00a09..6fba4ab 100644
--- a/neuralnetworks/utils/adapter/include/nnapi/hal/Adapter.h
+++ b/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/Adapter.h
@@ -20,7 +20,6 @@
 #include <android/hardware/neuralnetworks/1.3/IDevice.h>
 #include <nnapi/IDevice.h>
 #include <nnapi/Types.h>
-#include <sys/types.h>
 #include <functional>
 #include <memory>
 
@@ -37,10 +36,12 @@
 /**
  * A type-erased executor which executes a task asynchronously.
  *
- * This executor is also provided with an Application ID (Android User ID) and an optional deadline
- * for when the caller expects is the upper bound for the amount of time to complete the task.
+ * This executor is also provided an optional deadline for when the caller expects is the upper
+ * bound for the amount of time to complete the task. If needed, the Executor can retrieve the
+ * Application ID (Android User ID) by calling IPCThreadState::self()->getCallingUid() in
+ * hwbinder/IPCThreadState.h.
  */
-using Executor = std::function<void(Task, uid_t, nn::OptionalTimePoint)>;
+using Executor = std::function<void(Task, nn::OptionalTimePoint)>;
 
 /**
  * Adapt an NNAPI canonical interface object to a HIDL NN HAL interface object.
diff --git a/neuralnetworks/utils/adapter/include/nnapi/hal/Buffer.h b/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/Buffer.h
similarity index 100%
rename from neuralnetworks/utils/adapter/include/nnapi/hal/Buffer.h
rename to neuralnetworks/utils/adapter/hidl/include/nnapi/hal/Buffer.h
diff --git a/neuralnetworks/utils/adapter/include/nnapi/hal/Burst.h b/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/Burst.h
similarity index 100%
rename from neuralnetworks/utils/adapter/include/nnapi/hal/Burst.h
rename to neuralnetworks/utils/adapter/hidl/include/nnapi/hal/Burst.h
diff --git a/neuralnetworks/utils/adapter/include/nnapi/hal/Device.h b/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/Device.h
similarity index 100%
rename from neuralnetworks/utils/adapter/include/nnapi/hal/Device.h
rename to neuralnetworks/utils/adapter/hidl/include/nnapi/hal/Device.h
diff --git a/neuralnetworks/utils/adapter/include/nnapi/hal/PreparedModel.h b/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/PreparedModel.h
similarity index 98%
rename from neuralnetworks/utils/adapter/include/nnapi/hal/PreparedModel.h
rename to neuralnetworks/utils/adapter/hidl/include/nnapi/hal/PreparedModel.h
index 65763b8..9482b0d 100644
--- a/neuralnetworks/utils/adapter/include/nnapi/hal/PreparedModel.h
+++ b/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/PreparedModel.h
@@ -39,7 +39,7 @@
 // Class that adapts nn::IPreparedModel to V1_3::IPreparedModel.
 class PreparedModel final : public V1_3::IPreparedModel {
   public:
-    PreparedModel(nn::SharedPreparedModel preparedModel, Executor executor, uid_t userId);
+    PreparedModel(nn::SharedPreparedModel preparedModel, Executor executor);
 
     Return<V1_0::ErrorStatus> execute(const V1_0::Request& request,
                                       const sp<V1_0::IExecutionCallback>& callback) override;
@@ -71,7 +71,6 @@
   private:
     const nn::SharedPreparedModel kPreparedModel;
     const Executor kExecutor;
-    const uid_t kUserId;
 };
 
 }  // namespace android::hardware::neuralnetworks::adapter
diff --git a/neuralnetworks/utils/adapter/src/Adapter.cpp b/neuralnetworks/utils/adapter/hidl/src/Adapter.cpp
similarity index 92%
rename from neuralnetworks/utils/adapter/src/Adapter.cpp
rename to neuralnetworks/utils/adapter/hidl/src/Adapter.cpp
index d6f53f0..782e815 100644
--- a/neuralnetworks/utils/adapter/src/Adapter.cpp
+++ b/neuralnetworks/utils/adapter/hidl/src/Adapter.cpp
@@ -21,7 +21,6 @@
 #include <android/hardware/neuralnetworks/1.3/IDevice.h>
 #include <nnapi/IDevice.h>
 #include <nnapi/Types.h>
-#include <sys/types.h>
 
 #include <functional>
 #include <memory>
@@ -37,7 +36,7 @@
 }
 
 sp<V1_3::IDevice> adapt(nn::SharedDevice device) {
-    Executor defaultExecutor = [](Task task, uid_t /*uid*/, nn::OptionalTimePoint /*deadline*/) {
+    Executor defaultExecutor = [](Task task, nn::OptionalTimePoint /*deadline*/) {
         std::thread(std::move(task)).detach();
     };
     return adapt(std::move(device), std::move(defaultExecutor));
diff --git a/neuralnetworks/utils/adapter/src/Buffer.cpp b/neuralnetworks/utils/adapter/hidl/src/Buffer.cpp
similarity index 100%
rename from neuralnetworks/utils/adapter/src/Buffer.cpp
rename to neuralnetworks/utils/adapter/hidl/src/Buffer.cpp
diff --git a/neuralnetworks/utils/adapter/src/Burst.cpp b/neuralnetworks/utils/adapter/hidl/src/Burst.cpp
similarity index 100%
rename from neuralnetworks/utils/adapter/src/Burst.cpp
rename to neuralnetworks/utils/adapter/hidl/src/Burst.cpp
diff --git a/neuralnetworks/utils/adapter/src/Device.cpp b/neuralnetworks/utils/adapter/hidl/src/Device.cpp
similarity index 92%
rename from neuralnetworks/utils/adapter/src/Device.cpp
rename to neuralnetworks/utils/adapter/hidl/src/Device.cpp
index 96142c3..4993a80 100644
--- a/neuralnetworks/utils/adapter/src/Device.cpp
+++ b/neuralnetworks/utils/adapter/hidl/src/Device.cpp
@@ -28,7 +28,6 @@
 #include <android/hardware/neuralnetworks/1.3/IDevice.h>
 #include <android/hardware/neuralnetworks/1.3/IPreparedModelCallback.h>
 #include <android/hardware/neuralnetworks/1.3/types.h>
-#include <hwbinder/IPCThreadState.h>
 #include <nnapi/IBuffer.h>
 #include <nnapi/IDevice.h>
 #include <nnapi/IPreparedModel.h>
@@ -43,7 +42,6 @@
 #include <nnapi/hal/1.2/Utils.h>
 #include <nnapi/hal/1.3/Conversions.h>
 #include <nnapi/hal/1.3/Utils.h>
-#include <sys/types.h>
 
 #include <memory>
 
@@ -64,12 +62,11 @@
 
 using PrepareModelResult = nn::GeneralResult<nn::SharedPreparedModel>;
 
-sp<PreparedModel> adaptPreparedModel(nn::SharedPreparedModel preparedModel, Executor executor,
-                                     uid_t userId) {
+sp<PreparedModel> adaptPreparedModel(nn::SharedPreparedModel preparedModel, Executor executor) {
     if (preparedModel == nullptr) {
         return nullptr;
     }
-    return sp<PreparedModel>::make(std::move(preparedModel), std::move(executor), userId);
+    return sp<PreparedModel>::make(std::move(preparedModel), std::move(executor));
 }
 
 void notify(V1_0::IPreparedModelCallback* callback, nn::ErrorStatus status,
@@ -108,15 +105,14 @@
 }
 
 template <typename CallbackType>
-void notify(CallbackType* callback, PrepareModelResult result, Executor executor, uid_t userId) {
+void notify(CallbackType* callback, PrepareModelResult result, Executor executor) {
     if (!result.has_value()) {
         const auto [message, status] = std::move(result).error();
         LOG(ERROR) << message;
         notify(callback, status, nullptr);
     } else {
         auto preparedModel = std::move(result).value();
-        auto hidlPreparedModel =
-                adaptPreparedModel(std::move(preparedModel), std::move(executor), userId);
+        auto hidlPreparedModel = adaptPreparedModel(std::move(preparedModel), std::move(executor));
         notify(callback, nn::ErrorStatus::NONE, std::move(hidlPreparedModel));
     }
 }
@@ -137,13 +133,12 @@
 
     auto nnModel = NN_TRY(convertInput(model));
 
-    const uid_t userId = hardware::IPCThreadState::self()->getCallingUid();
-    Task task = [device, nnModel = std::move(nnModel), userId, executor, callback] {
+    Task task = [device, nnModel = std::move(nnModel), executor, callback] {
         auto result = device->prepareModel(nnModel, nn::ExecutionPreference::DEFAULT,
                                            nn::Priority::DEFAULT, {}, {}, {}, {});
-        notify(callback.get(), std::move(result), executor, userId);
+        notify(callback.get(), std::move(result), executor);
     };
-    executor(std::move(task), userId, {});
+    executor(std::move(task), {});
 
     return {};
 }
@@ -159,13 +154,12 @@
     auto nnModel = NN_TRY(convertInput(model));
     const auto nnPreference = NN_TRY(convertInput(preference));
 
-    const uid_t userId = hardware::IPCThreadState::self()->getCallingUid();
-    Task task = [device, nnModel = std::move(nnModel), nnPreference, userId, executor, callback] {
+    Task task = [device, nnModel = std::move(nnModel), nnPreference, executor, callback] {
         auto result =
                 device->prepareModel(nnModel, nnPreference, nn::Priority::DEFAULT, {}, {}, {}, {});
-        notify(callback.get(), std::move(result), executor, userId);
+        notify(callback.get(), std::move(result), executor);
     };
-    executor(std::move(task), userId, {});
+    executor(std::move(task), {});
 
     return {};
 }
@@ -187,15 +181,14 @@
     auto nnDataCache = NN_TRY(convertInput(dataCache));
     const auto nnToken = nn::CacheToken(token);
 
-    const uid_t userId = hardware::IPCThreadState::self()->getCallingUid();
     Task task = [device, nnModel = std::move(nnModel), nnPreference,
                  nnModelCache = std::move(nnModelCache), nnDataCache = std::move(nnDataCache),
-                 nnToken, userId, executor, callback] {
+                 nnToken, executor, callback] {
         auto result = device->prepareModel(nnModel, nnPreference, nn::Priority::DEFAULT, {},
                                            nnModelCache, nnDataCache, nnToken);
-        notify(callback.get(), std::move(result), executor, userId);
+        notify(callback.get(), std::move(result), executor);
     };
-    executor(std::move(task), userId, {});
+    executor(std::move(task), {});
 
     return {};
 }
@@ -218,15 +211,14 @@
     auto nnDataCache = NN_TRY(convertInput(dataCache));
     const auto nnToken = nn::CacheToken(token);
 
-    const uid_t userId = hardware::IPCThreadState::self()->getCallingUid();
     Task task = [device, nnModel = std::move(nnModel), nnPreference, nnPriority, nnDeadline,
                  nnModelCache = std::move(nnModelCache), nnDataCache = std::move(nnDataCache),
-                 nnToken, userId, executor, callback] {
+                 nnToken, executor, callback] {
         auto result = device->prepareModel(nnModel, nnPreference, nnPriority, nnDeadline,
                                            nnModelCache, nnDataCache, nnToken);
-        notify(callback.get(), std::move(result), executor, userId);
+        notify(callback.get(), std::move(result), executor);
     };
-    executor(std::move(task), userId, nnDeadline);
+    executor(std::move(task), nnDeadline);
 
     return {};
 }
@@ -245,13 +237,12 @@
     auto nnDataCache = NN_TRY(convertInput(dataCache));
     const auto nnToken = nn::CacheToken(token);
 
-    const uid_t userId = hardware::IPCThreadState::self()->getCallingUid();
     Task task = [device, nnModelCache = std::move(nnModelCache),
-                 nnDataCache = std::move(nnDataCache), nnToken, userId, executor, callback] {
+                 nnDataCache = std::move(nnDataCache), nnToken, executor, callback] {
         auto result = device->prepareModelFromCache({}, nnModelCache, nnDataCache, nnToken);
-        notify(callback.get(), std::move(result), executor, userId);
+        notify(callback.get(), std::move(result), executor);
     };
-    executor(std::move(task), userId, {});
+    executor(std::move(task), {});
 
     return {};
 }
@@ -270,13 +261,12 @@
     auto nnDataCache = NN_TRY(convertInput(dataCache));
     const auto nnToken = nn::CacheToken(token);
 
-    const uid_t userId = hardware::IPCThreadState::self()->getCallingUid();
     auto task = [device, nnDeadline, nnModelCache = std::move(nnModelCache),
-                 nnDataCache = std::move(nnDataCache), nnToken, userId, executor, callback] {
+                 nnDataCache = std::move(nnDataCache), nnToken, executor, callback] {
         auto result = device->prepareModelFromCache(nnDeadline, nnModelCache, nnDataCache, nnToken);
-        notify(callback.get(), std::move(result), executor, userId);
+        notify(callback.get(), std::move(result), executor);
     };
-    executor(std::move(task), userId, nnDeadline);
+    executor(std::move(task), nnDeadline);
 
     return {};
 }
diff --git a/neuralnetworks/utils/adapter/src/PreparedModel.cpp b/neuralnetworks/utils/adapter/hidl/src/PreparedModel.cpp
similarity index 96%
rename from neuralnetworks/utils/adapter/src/PreparedModel.cpp
rename to neuralnetworks/utils/adapter/hidl/src/PreparedModel.cpp
index a14e782..71060d5 100644
--- a/neuralnetworks/utils/adapter/src/PreparedModel.cpp
+++ b/neuralnetworks/utils/adapter/hidl/src/PreparedModel.cpp
@@ -28,7 +28,6 @@
 #include <android/hardware/neuralnetworks/1.3/IFencedExecutionCallback.h>
 #include <android/hardware/neuralnetworks/1.3/IPreparedModel.h>
 #include <android/hardware/neuralnetworks/1.3/types.h>
-#include <hwbinder/IPCThreadState.h>
 #include <nnapi/IPreparedModel.h>
 #include <nnapi/TypeUtils.h>
 #include <nnapi/Types.h>
@@ -37,7 +36,6 @@
 #include <nnapi/hal/1.2/Utils.h>
 #include <nnapi/hal/1.3/Conversions.h>
 #include <nnapi/hal/1.3/Utils.h>
-#include <sys/types.h>
 
 #include <memory>
 #include <thread>
@@ -145,7 +143,7 @@
     }
 }
 
-nn::GeneralResult<void> execute(const nn::SharedPreparedModel& preparedModel, uid_t userId,
+nn::GeneralResult<void> execute(const nn::SharedPreparedModel& preparedModel,
                                 const Executor& executor, const V1_0::Request& request,
                                 const sp<V1_0::IExecutionCallback>& callback) {
     if (callback.get() == nullptr) {
@@ -164,12 +162,12 @@
         auto result = preparedModel->execute(nnRequest, nn::MeasureTiming::NO, {}, {});
         notify(callback.get(), std::move(result));
     };
-    executor(std::move(task), userId, {});
+    executor(std::move(task), {});
 
     return {};
 }
 
-nn::GeneralResult<void> execute_1_2(const nn::SharedPreparedModel& preparedModel, uid_t userId,
+nn::GeneralResult<void> execute_1_2(const nn::SharedPreparedModel& preparedModel,
                                     const Executor& executor, const V1_0::Request& request,
                                     V1_2::MeasureTiming measure,
                                     const sp<V1_2::IExecutionCallback>& callback) {
@@ -190,12 +188,12 @@
         auto result = preparedModel->execute(nnRequest, nnMeasure, {}, {});
         notify(callback.get(), std::move(result));
     };
-    executor(std::move(task), userId, {});
+    executor(std::move(task), {});
 
     return {};
 }
 
-nn::GeneralResult<void> execute_1_3(const nn::SharedPreparedModel& preparedModel, uid_t userId,
+nn::GeneralResult<void> execute_1_3(const nn::SharedPreparedModel& preparedModel,
                                     const Executor& executor, const V1_3::Request& request,
                                     V1_2::MeasureTiming measure,
                                     const V1_3::OptionalTimePoint& deadline,
@@ -222,7 +220,7 @@
                 preparedModel->execute(nnRequest, nnMeasure, nnDeadline, nnLoopTimeoutDuration);
         notify(callback.get(), std::move(result));
     };
-    executor(std::move(task), userId, nnDeadline);
+    executor(std::move(task), nnDeadline);
 
     return {};
 }
@@ -305,8 +303,8 @@
 
 }  // namespace
 
-PreparedModel::PreparedModel(nn::SharedPreparedModel preparedModel, Executor executor, uid_t userId)
-    : kPreparedModel(std::move(preparedModel)), kExecutor(std::move(executor)), kUserId(userId) {
+PreparedModel::PreparedModel(nn::SharedPreparedModel preparedModel, Executor executor)
+    : kPreparedModel(std::move(preparedModel)), kExecutor(std::move(executor)) {
     CHECK(kPreparedModel != nullptr);
     CHECK(kExecutor != nullptr);
 }
@@ -317,7 +315,7 @@
 
 Return<V1_0::ErrorStatus> PreparedModel::execute(const V1_0::Request& request,
                                                  const sp<V1_0::IExecutionCallback>& callback) {
-    auto result = adapter::execute(kPreparedModel, kUserId, kExecutor, request, callback);
+    auto result = adapter::execute(kPreparedModel, kExecutor, request, callback);
     if (!result.has_value()) {
         auto [message, code] = std::move(result).error();
         LOG(ERROR) << "adapter::PreparedModel::execute failed with " << code << ": " << message;
@@ -330,8 +328,7 @@
 Return<V1_0::ErrorStatus> PreparedModel::execute_1_2(const V1_0::Request& request,
                                                      V1_2::MeasureTiming measure,
                                                      const sp<V1_2::IExecutionCallback>& callback) {
-    auto result =
-            adapter::execute_1_2(kPreparedModel, kUserId, kExecutor, request, measure, callback);
+    auto result = adapter::execute_1_2(kPreparedModel, kExecutor, request, measure, callback);
     if (!result.has_value()) {
         auto [message, code] = std::move(result).error();
         LOG(ERROR) << "adapter::PreparedModel::execute_1_2 failed with " << code << ": " << message;
@@ -346,8 +343,8 @@
         const V1_3::OptionalTimePoint& deadline,
         const V1_3::OptionalTimeoutDuration& loopTimeoutDuration,
         const sp<V1_3::IExecutionCallback>& callback) {
-    auto result = adapter::execute_1_3(kPreparedModel, kUserId, kExecutor, request, measure,
-                                       deadline, loopTimeoutDuration, callback);
+    auto result = adapter::execute_1_3(kPreparedModel, kExecutor, request, measure, deadline,
+                                       loopTimeoutDuration, callback);
     if (!result.has_value()) {
         auto [message, code] = std::move(result).error();
         LOG(ERROR) << "adapter::PreparedModel::execute_1_3 failed with " << code << ": " << message;
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/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataProfileInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataProfileInfo.aidl
index 9df687c..c8efea0 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataProfileInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataProfileInfo.aidl
@@ -46,13 +46,14 @@
   int maxConns;
   int waitTime;
   boolean enabled;
-  android.hardware.radio.data.ApnTypes supportedApnTypesBitmap;
-  android.hardware.radio.RadioAccessFamily bearerBitmap;
+  int supportedApnTypesBitmap;
+  int bearerBitmap;
   int mtuV4;
   int mtuV6;
   boolean preferred;
   boolean persistent;
   boolean alwaysOn;
+  @nullable android.hardware.radio.data.TrafficDescriptor trafficDescriptor;
   const int ID_DEFAULT = 0;
   const int ID_TETHERED = 1;
   const int ID_IMS = 2;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/IRadioData.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/IRadioData.aidl
index a648675..dc6092a 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/IRadioData.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/IRadioData.aidl
@@ -46,7 +46,7 @@
   oneway void setDataThrottling(in int serial, in android.hardware.radio.data.DataThrottlingAction dataThrottlingAction, in long completionDurationMillis);
   oneway void setInitialAttachApn(in int serial, in android.hardware.radio.data.DataProfileInfo dataProfileInfo);
   oneway void setResponseFunctions(in android.hardware.radio.data.IRadioDataResponse radioDataResponse, in android.hardware.radio.data.IRadioDataIndication radioDataIndication);
-  oneway void setupDataCall(in int serial, in android.hardware.radio.AccessNetwork accessNetwork, in android.hardware.radio.data.DataProfileInfo dataProfileInfo, in boolean roamingAllowed, in android.hardware.radio.data.DataRequestReason reason, in android.hardware.radio.data.LinkAddress[] addresses, in String[] dnses, in int pduSessionId, in @nullable android.hardware.radio.data.SliceInfo sliceInfo, in @nullable android.hardware.radio.data.TrafficDescriptor trafficDescriptor, in boolean matchAllRuleAllowed);
+  oneway void setupDataCall(in int serial, in android.hardware.radio.AccessNetwork accessNetwork, in android.hardware.radio.data.DataProfileInfo dataProfileInfo, in boolean roamingAllowed, in android.hardware.radio.data.DataRequestReason reason, in android.hardware.radio.data.LinkAddress[] addresses, in String[] dnses, in int pduSessionId, in @nullable android.hardware.radio.data.SliceInfo sliceInfo, in boolean matchAllRuleAllowed);
   oneway void startHandover(in int serial, in int callId);
   oneway void startKeepalive(in int serial, in android.hardware.radio.data.KeepaliveRequest keepalive);
   oneway void stopKeepalive(in int serial, in int sessionHandle);
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/IRadioDataIndication.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/IRadioDataIndication.aidl
index e496c7b..b0cc1eb 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/IRadioDataIndication.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/IRadioDataIndication.aidl
@@ -37,5 +37,5 @@
   oneway void dataCallListChanged(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.data.SetupDataCallResult[] dcList);
   oneway void keepaliveStatus(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.data.KeepaliveStatus status);
   oneway void pcoData(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.data.PcoDataInfo pco);
-  oneway void unthrottleApn(in android.hardware.radio.RadioIndicationType type, in String apn);
+  oneway void unthrottleApn(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.data.DataProfileInfo dataProfileInfo);
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/RadioCapability.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/RadioCapability.aidl
index d5716ac..5aaf5a7 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/RadioCapability.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/RadioCapability.aidl
@@ -36,7 +36,7 @@
 parcelable RadioCapability {
   int session;
   int phase;
-  android.hardware.radio.RadioAccessFamily raf;
+  int raf;
   String logicalModemUuid;
   int status;
   const int PHASE_CONFIGURED = 0;
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 c618791..2b70e45 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
@@ -50,12 +50,12 @@
   oneway void getVoiceRegistrationState(in int serial);
   oneway void isNrDualConnectivityEnabled(in int serial);
   oneway void responseAcknowledgement();
-  oneway void setAllowedNetworkTypesBitmap(in int serial, in android.hardware.radio.RadioAccessFamily networkTypeBitmap);
+  oneway void setAllowedNetworkTypesBitmap(in int serial, in int networkTypeBitmap);
   oneway void setBandMode(in int serial, in android.hardware.radio.network.RadioBandMode mode);
   oneway void setBarringPassword(in int serial, in String facility, in String oldPassword, in String newPassword);
   oneway void setCdmaRoamingPreference(in int serial, in android.hardware.radio.network.CdmaRoamingType type);
   oneway void setCellInfoListRate(in int serial, in int rate);
-  oneway void setIndicationFilter(in int serial, in android.hardware.radio.network.IndicationFilter indicationFilter);
+  oneway void setIndicationFilter(in int serial, in int indicationFilter);
   oneway void setLinkCapacityReportingCriteria(in int serial, in int hysteresisMs, in int hysteresisDlKbps, in int hysteresisUlKbps, in int[] thresholdsDownlinkKbps, in int[] thresholdsUplinkKbps, in android.hardware.radio.AccessNetwork accessNetwork);
   oneway void setLocationUpdates(in int serial, in boolean enable);
   oneway void setNetworkSelectionModeAutomatic(in int serial);
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkIndication.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkIndication.aidl
index d135a69..bd03c51 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkIndication.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkIndication.aidl
@@ -44,7 +44,7 @@
   oneway void networkScanResult(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.network.NetworkScanResult result);
   oneway void networkStateChanged(in android.hardware.radio.RadioIndicationType type);
   oneway void nitzTimeReceived(in android.hardware.radio.RadioIndicationType type, in String nitzTime, in long receivedTimeMs, in long ageMs);
-  oneway void registrationFailed(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.network.CellIdentity cellIdentity, in String chosenPlmn, in android.hardware.radio.network.Domain domain, in int causeCode, in int additionalCauseCode);
+  oneway void registrationFailed(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.network.CellIdentity cellIdentity, in String chosenPlmn, in int domain, in int causeCode, in int additionalCauseCode);
   oneway void restrictedStateChanged(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.network.PhoneRestrictedState state);
   oneway void suppSvcNotify(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.network.SuppSvcNotification suppSvc);
   oneway void voiceRadioTechChanged(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.RadioTechnology rat);
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 8cf4c31..5f6c736 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
@@ -35,7 +35,7 @@
 @VintfStability
 interface IRadioNetworkResponse {
   oneway void acknowledgeRequest(in int serial);
-  oneway void getAllowedNetworkTypesBitmapResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.RadioAccessFamily networkTypeBitmap);
+  oneway void getAllowedNetworkTypesBitmapResponse(in android.hardware.radio.RadioResponseInfo info, in int networkTypeBitmap);
   oneway void getAvailableBandModesResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.network.RadioBandMode[] bandModes);
   oneway void getAvailableNetworksResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.network.OperatorInfo[] networkInfos);
   oneway void getBarringInfoResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.network.CellIdentity cellIdentity, in android.hardware.radio.network.BarringInfo[] barringInfos);
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyNumber.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyNumber.aidl
index 4f415ee..39bcf1a 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyNumber.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyNumber.aidl
@@ -37,7 +37,7 @@
   String number;
   String mcc;
   String mnc;
-  android.hardware.radio.voice.EmergencyServiceCategory categories;
+  int categories;
   String[] urns;
   int sources;
   const int SOURCE_NETWORK_SIGNALING = 1;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoice.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoice.aidl
index 68c82fa..34d155a 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoice.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoice.aidl
@@ -37,7 +37,7 @@
   oneway void acceptCall(in int serial);
   oneway void conference(in int serial);
   oneway void dial(in int serial, in android.hardware.radio.voice.Dial dialInfo);
-  oneway void emergencyDial(in int serial, in android.hardware.radio.voice.Dial dialInfo, in android.hardware.radio.voice.EmergencyServiceCategory categories, in String[] urns, in android.hardware.radio.voice.EmergencyCallRouting routing, in boolean hasKnownUserIntentEmergency, in boolean isTesting);
+  oneway void emergencyDial(in int serial, in android.hardware.radio.voice.Dial dialInfo, in int categories, in String[] urns, in android.hardware.radio.voice.EmergencyCallRouting routing, in boolean hasKnownUserIntentEmergency, in boolean isTesting);
   oneway void exitEmergencyCallbackMode(in int serial);
   oneway void explicitCallTransfer(in int serial);
   oneway void getCallForwardStatus(in int serial, in android.hardware.radio.voice.CallForwardInfo callInfo);
diff --git a/radio/aidl/android/hardware/radio/config/SimSlotStatus.aidl b/radio/aidl/android/hardware/radio/config/SimSlotStatus.aidl
index a1c3c27..b5cf633 100644
--- a/radio/aidl/android/hardware/radio/config/SimSlotStatus.aidl
+++ b/radio/aidl/android/hardware/radio/config/SimSlotStatus.aidl
@@ -42,7 +42,13 @@
      */
     String eid;
     /**
-     * PortInfo contains the ICCID, logical slot ID, and port state
+     * PortInfo contains the ICCID, logical slot ID, and port state.
+     * Cardstate has no relationship with whether the slot is active or inactive. Should always
+     * report up at least 1 port otherwise the logicalSlotIndex and portActive info will be lost.
+     * For example, the pSIM can be removed, but the slot can still be active. In that case, the
+     * SIM_STATUS reported for the corresponding logical stack will show CARDSTATE_ABSENT.
+     * Similarly, even if there is no profile enabled on the eSIM, that port can still be the
+     * active port in the slot mapping.
      */
     SimPortInfo[] portInfo;
 }
diff --git a/radio/aidl/android/hardware/radio/data/DataProfileInfo.aidl b/radio/aidl/android/hardware/radio/data/DataProfileInfo.aidl
index a14963f..7360202 100644
--- a/radio/aidl/android/hardware/radio/data/DataProfileInfo.aidl
+++ b/radio/aidl/android/hardware/radio/data/DataProfileInfo.aidl
@@ -20,6 +20,7 @@
 import android.hardware.radio.data.ApnAuthType;
 import android.hardware.radio.data.ApnTypes;
 import android.hardware.radio.data.PdpProtocolType;
+import android.hardware.radio.data.TrafficDescriptor;
 
 @VintfStability
 parcelable DataProfileInfo {
@@ -92,11 +93,11 @@
     /**
      * Supported APN types bitmap. See ApnTypes for the value of each bit.
      */
-    ApnTypes supportedApnTypesBitmap;
+    int supportedApnTypesBitmap;
     /**
      * The bearer bitmap. See RadioAccessFamily for the value of each bit.
      */
-    RadioAccessFamily bearerBitmap;
+    int bearerBitmap;
     /**
      * Maximum transmission unit (MTU) size in bytes for IPv4.
      */
@@ -122,4 +123,12 @@
      * See 3GPP TS 23.501 section 5.6.13 for the details.
      */
     boolean alwaysOn;
+    /**
+     * TrafficDescriptor for which data connection needs to be established.
+     * It is used for URSP traffic matching as described in TS 24.526 Section 4.2.2.
+     * It includes an optional DNN which, if present, must be used for traffic matching --
+     * it does not specify the end point to be used for the data call. The end point is specified by
+     * apn; apn must be used as the end point if one is not specified through URSP rules.
+     */
+    @nullable TrafficDescriptor trafficDescriptor;
 }
diff --git a/radio/aidl/android/hardware/radio/data/IRadioData.aidl b/radio/aidl/android/hardware/radio/data/IRadioData.aidl
index 9f5ba4c..54a045c 100644
--- a/radio/aidl/android/hardware/radio/data/IRadioData.aidl
+++ b/radio/aidl/android/hardware/radio/data/IRadioData.aidl
@@ -219,12 +219,6 @@
      *        EPDG to 5G. It is valid only when accessNetwork is AccessNetwork:NGRAN. If the slice
      *        passed from EPDG is rejected, then the data failure cause must be
      *        DataCallFailCause:SLICE_REJECTED.
-     * @param trafficDescriptor TrafficDescriptor for which data connection needs to be established.
-     *        It is used for URSP traffic matching as described in TS 24.526 Section 4.2.2.
-     *        It includes an optional DNN which, if present, must be used for traffic matching --
-     *        it does not specify the end point to be used for the data call. The end point is
-     *        specified by DataProfileInfo.apn; DataProfileInfo.apn must be used as the end point if
-     *        one is not specified through URSP rules.
      * @param matchAllRuleAllowed bool to indicate if using default match-all URSP rule for this
      *        request is allowed. If false, this request must not use the match-all URSP rule and if
      *        a non-match-all rule is not found (or if URSP rules are not available) it should
@@ -238,7 +232,6 @@
             in DataProfileInfo dataProfileInfo, in boolean roamingAllowed,
             in DataRequestReason reason, in LinkAddress[] addresses, in String[] dnses,
             in int pduSessionId, in @nullable SliceInfo sliceInfo,
-            in @nullable TrafficDescriptor trafficDescriptor,
             in boolean matchAllRuleAllowed);
 
     /**
diff --git a/radio/aidl/android/hardware/radio/data/IRadioDataIndication.aidl b/radio/aidl/android/hardware/radio/data/IRadioDataIndication.aidl
index 8e73ee3..1772c88 100644
--- a/radio/aidl/android/hardware/radio/data/IRadioDataIndication.aidl
+++ b/radio/aidl/android/hardware/radio/data/IRadioDataIndication.aidl
@@ -17,6 +17,7 @@
 package android.hardware.radio.data;
 
 import android.hardware.radio.RadioIndicationType;
+import android.hardware.radio.data.DataProfileInfo;
 import android.hardware.radio.data.KeepaliveStatus;
 import android.hardware.radio.data.PcoDataInfo;
 import android.hardware.radio.data.SetupDataCallResult;
@@ -68,7 +69,7 @@
      * is sent, AOSP will no longer throttle calls to IRadioData.SetupDataCall for the given APN.
      *
      * @param type Type of radio indication
-     * @param apn Apn to unthrottle
+     * @param dataProfileInfo Data profile info.
      */
-    void unthrottleApn(in RadioIndicationType type, in String apn);
+    void unthrottleApn(in RadioIndicationType type, in DataProfileInfo dataProfileInfo);
 }
diff --git a/radio/aidl/android/hardware/radio/modem/RadioCapability.aidl b/radio/aidl/android/hardware/radio/modem/RadioCapability.aidl
index b7b8ef3..9bd5f21 100644
--- a/radio/aidl/android/hardware/radio/modem/RadioCapability.aidl
+++ b/radio/aidl/android/hardware/radio/modem/RadioCapability.aidl
@@ -71,7 +71,7 @@
     /**
      * 32-bit bitmap of RadioAccessFamily.
      */
-    RadioAccessFamily raf;
+    int raf;
     /**
      * A UUID typically "com.xxxx.lmX" where X is the logical modem.
      * RadioConst:MAX_UUID_LENGTH is the max length.
diff --git a/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl b/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl
index aaf432a..7a22a9a 100644
--- a/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl
+++ b/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl
@@ -195,7 +195,7 @@
      *
      * Response function is IRadioNetworkResponse.setAllowedNetworkTypesBitmapResponse()
      */
-    void setAllowedNetworkTypesBitmap(in int serial, in RadioAccessFamily networkTypeBitmap);
+    void setAllowedNetworkTypesBitmap(in int serial, in int networkTypeBitmap);
 
     /**
      * Assign a specified band for RF configuration.
@@ -253,7 +253,7 @@
      *
      * Response function is IRadioNetworkResponse.setIndicationFilterResponse()
      */
-    void setIndicationFilter(in int serial, in IndicationFilter indicationFilter);
+    void setIndicationFilter(in int serial, in int indicationFilter);
 
     /**
      * Sets the link capacity reporting criteria. The resulting reporting criteria are the AND of
diff --git a/radio/aidl/android/hardware/radio/network/IRadioNetworkIndication.aidl b/radio/aidl/android/hardware/radio/network/IRadioNetworkIndication.aidl
index ba7610d..6863ac3 100644
--- a/radio/aidl/android/hardware/radio/network/IRadioNetworkIndication.aidl
+++ b/radio/aidl/android/hardware/radio/network/IRadioNetworkIndication.aidl
@@ -136,8 +136,8 @@
      *        include the time spend in sleep / low power states. If it can not be guaranteed,
      *        there must not be any caching done at the modem and should fill in 0 for ageMs
      */
-    void nitzTimeReceived(in RadioIndicationType type, in String nitzTime,
-            in long receivedTimeMs, in long ageMs);
+    void nitzTimeReceived(
+            in RadioIndicationType type, in String nitzTime, in long receivedTimeMs, in long ageMs);
 
     /**
      * Report that Registration or a Location/Routing/Tracking Area update has failed.
@@ -165,7 +165,7 @@
      *        MAX_INT if this value is unused.
      */
     void registrationFailed(in RadioIndicationType type, in CellIdentity cellIdentity,
-            in String chosenPlmn, in Domain domain, in int causeCode, in int additionalCauseCode);
+            in String chosenPlmn, in int domain, in int causeCode, in int additionalCauseCode);
 
     /**
      * Indicates a restricted state change (eg, for Domain Specific Access Control).
diff --git a/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl b/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl
index 30f4221..e650321 100644
--- a/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl
+++ b/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl
@@ -62,8 +62,7 @@
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:NO_RESOURCES
      */
-    void getAllowedNetworkTypesBitmapResponse(
-            in RadioResponseInfo info, in RadioAccessFamily networkTypeBitmap);
+    void getAllowedNetworkTypesBitmapResponse(in RadioResponseInfo info, in int networkTypeBitmap);
 
     /**
      * @param info Response info struct containing response type, serial no. and error
diff --git a/radio/aidl/android/hardware/radio/sim/IRadioSim.aidl b/radio/aidl/android/hardware/radio/sim/IRadioSim.aidl
index c731caf..7923b14 100644
--- a/radio/aidl/android/hardware/radio/sim/IRadioSim.aidl
+++ b/radio/aidl/android/hardware/radio/sim/IRadioSim.aidl
@@ -205,6 +205,12 @@
      * Open a new logical channel and select the given application. This command
      * reflects TS 27.007 "open logical channel" operation (+CCHO).
      *
+     * For MEP-A(Multiple enabled profile), only dedicated port 0 is ISDR selectable.
+     * e.g., Port0 - for ISDR access and Port1/Port2 - the currently active ports/subscriptions.
+     * Port 0 should be transparent to AP and iccLogicalChannel API should remain the same.
+     * Even if the ISDR request comes over port1 or port2, Modem would just internally convert the
+     * portID to port0 and add the real port index as the payload of MANAGE_CHANNEL command.
+     *
      * @param serial Serial number of request.
      * @param aid AID value, See ETSI 102.221 and 101.220.
      * @param p2 P2 value, described in ISO 7816-4. Ignore if equal to RadioConst:P2_CONSTANT_NO_P2
diff --git a/radio/aidl/android/hardware/radio/voice/EmergencyNumber.aidl b/radio/aidl/android/hardware/radio/voice/EmergencyNumber.aidl
index aa4dde2..ddc5d76 100644
--- a/radio/aidl/android/hardware/radio/voice/EmergencyNumber.aidl
+++ b/radio/aidl/android/hardware/radio/voice/EmergencyNumber.aidl
@@ -78,7 +78,7 @@
      * The bitfield of EmergencyServiceCategory(s). See EmergencyServiceCategory for the value of
      * each bit.
      */
-    EmergencyServiceCategory categories;
+    int categories;
     /**
      * The list of emergency Uniform Resource Names (URN).
      */
diff --git a/radio/aidl/android/hardware/radio/voice/IRadioVoice.aidl b/radio/aidl/android/hardware/radio/voice/IRadioVoice.aidl
index a012be4..b25e63d 100644
--- a/radio/aidl/android/hardware/radio/voice/IRadioVoice.aidl
+++ b/radio/aidl/android/hardware/radio/voice/IRadioVoice.aidl
@@ -117,9 +117,9 @@
      *
      * Response function is IRadioVoiceResponse.emergencyDialResponse()
      */
-    void emergencyDial(in int serial, in Dial dialInfo, in EmergencyServiceCategory categories,
-            in String[] urns, in EmergencyCallRouting routing,
-            in boolean hasKnownUserIntentEmergency, in boolean isTesting);
+    void emergencyDial(in int serial, in Dial dialInfo, in int categories, in String[] urns,
+            in EmergencyCallRouting routing, in boolean hasKnownUserIntentEmergency,
+            in boolean isTesting);
 
     /**
      * Request the radio's system selection module to exit emergency callback mode. Radio must not
diff --git a/radio/aidl/compat/OWNERS b/radio/aidl/compat/OWNERS
new file mode 100644
index 0000000..471d806
--- /dev/null
+++ b/radio/aidl/compat/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 20868
+include ../../1.0/vts/OWNERS
+twasilczyk@google.com
diff --git a/radio/aidl/compat/libradiocompat/Android.bp b/radio/aidl/compat/libradiocompat/Android.bp
index 43d9378..487d91b 100644
--- a/radio/aidl/compat/libradiocompat/Android.bp
+++ b/radio/aidl/compat/libradiocompat/Android.bp
@@ -28,7 +28,6 @@
     cflags: [
         "-Wall",
         "-Wextra",
-        //"-Wold-style-cast",  // TODO(b/203699028) enable after aosp/1900880 gets merged
         "-DANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION",
     ],
     shared_libs: [
@@ -56,7 +55,10 @@
         "libutils",
     ],
     srcs: [
+        "CallbackManager.cpp",
+        "DriverContext.cpp",
         "RadioCompatBase.cpp",
+        "RadioIndication.cpp",
         "RadioResponse.cpp",
         "commonStructs.cpp",
         "config/RadioConfig.cpp",
diff --git a/radio/aidl/compat/libradiocompat/CallbackManager.cpp b/radio/aidl/compat/libradiocompat/CallbackManager.cpp
new file mode 100644
index 0000000..c2eaed1
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/CallbackManager.cpp
@@ -0,0 +1,84 @@
+/*
+ * 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 <libradiocompat/CallbackManager.h>
+
+#include <android-base/logging.h>
+
+using namespace std::literals::chrono_literals;
+
+namespace android::hardware::radio::compat {
+
+/**
+ * How much setter thread will wait with setting response functions after the last
+ * setResponseFunctions call from the framework. Subsequent calls from the framework reset the
+ * clock, so this number should be larger than the longest time between setResponseFunctions calls
+ * from the framework.
+ *
+ * Real world measurements with Cuttlefish give <10ms delay between Modem and Data and <2ms delays
+ * between all others.
+ */
+static constexpr auto kDelayedSetterDelay = 100ms;
+
+CallbackManager::CallbackManager(std::shared_ptr<DriverContext> context, sp<V1_5::IRadio> hidlHal)
+    : mHidlHal(hidlHal),
+      mRadioResponse(sp<compat::RadioResponse>::make(context)),
+      mRadioIndication(sp<compat::RadioIndication>::make(context)),
+      mDelayedSetterThread(&CallbackManager::delayedSetterThread, this) {}
+
+CallbackManager::~CallbackManager() {
+    {
+        std::unique_lock<std::mutex> lock(mDelayedSetterGuard);
+        mDelayedSetterDeadline = std::nullopt;
+        mDestroy = true;
+        mDelayedSetterCv.notify_all();
+    }
+    mDelayedSetterThread.join();
+}
+
+RadioResponse& CallbackManager::response() const {
+    return *mRadioResponse;
+}
+
+void CallbackManager::setResponseFunctionsDelayed() {
+    std::unique_lock<std::mutex> lock(mDelayedSetterGuard);
+    mDelayedSetterDeadline = std::chrono::steady_clock::now() + kDelayedSetterDelay;
+    mDelayedSetterCv.notify_all();
+}
+
+void CallbackManager::delayedSetterThread() {
+    while (!mDestroy) {
+        std::unique_lock<std::mutex> lock(mDelayedSetterGuard);
+        auto deadline = mDelayedSetterDeadline;
+
+        // not waiting to set response functions
+        if (!deadline) {
+            mDelayedSetterCv.wait(lock);
+            continue;
+        }
+
+        // waiting to set response functions, but not yet
+        if (*deadline > std::chrono::steady_clock::now()) {
+            mDelayedSetterCv.wait_until(lock, *deadline);
+            continue;
+        }
+
+        mHidlHal->setResponseFunctions(mRadioResponse, mRadioIndication).assertOk();
+        mDelayedSetterDeadline = std::nullopt;
+    }
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/DriverContext.cpp b/radio/aidl/compat/libradiocompat/DriverContext.cpp
new file mode 100644
index 0000000..a07173e
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/DriverContext.cpp
@@ -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.
+ */
+
+#include <libradiocompat/DriverContext.h>
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio;
+
+void DriverContext::addDataProfile(const aidl::data::DataProfileInfo& profile) {
+    mDataProfiles[profile.apn] = profile;
+}
+
+aidl::data::DataProfileInfo DriverContext::getDataProfile(const std::string& apn) {
+    const auto it = mDataProfiles.find(apn);
+    if (it != mDataProfiles.end()) return it->second;
+
+    // if not found in cache, return a made up default
+    return {
+            .apn = apn,
+    };
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/RadioCompatBase.cpp b/radio/aidl/compat/libradiocompat/RadioCompatBase.cpp
index a9eac68..2a2d7a3 100644
--- a/radio/aidl/compat/libradiocompat/RadioCompatBase.cpp
+++ b/radio/aidl/compat/libradiocompat/RadioCompatBase.cpp
@@ -20,16 +20,11 @@
 
 namespace android::hardware::radio::compat {
 
-RadioCompatBase::RadioCompatBase(sp<V1_5::IRadio> hidlHal, sp<RadioResponse> radioResponse,
-                                 sp<RadioIndication> radioIndication)
-    : mHal1_5(hidlHal),
+RadioCompatBase::RadioCompatBase(std::shared_ptr<DriverContext> context, sp<V1_5::IRadio> hidlHal,
+                                 std::shared_ptr<CallbackManager> cbMgr)
+    : mContext(context),
+      mHal1_5(hidlHal),
       mHal1_6(V1_6::IRadio::castFrom(hidlHal)),
-      mRadioResponse(radioResponse),
-      mRadioIndication(radioIndication) {}
-
-V1_6::IRadioResponse& RadioCompatBase::respond() {
-    CHECK(mRadioResponse) << "This shouldn't happen (response functions are passed in constructor)";
-    return *mRadioResponse;
-}
+      mCallbackManager(cbMgr) {}
 
 }  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/RadioIndication.cpp b/radio/aidl/compat/libradiocompat/RadioIndication.cpp
new file mode 100644
index 0000000..30ef6a0
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/RadioIndication.cpp
@@ -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.
+ */
+
+#include <libradiocompat/RadioIndication.h>
+
+namespace android::hardware::radio::compat {
+
+RadioIndication::RadioIndication(std::shared_ptr<DriverContext> context) : mContext(context) {}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/RadioResponse.cpp b/radio/aidl/compat/libradiocompat/RadioResponse.cpp
index 35b0ac1..dab70cc 100644
--- a/radio/aidl/compat/libradiocompat/RadioResponse.cpp
+++ b/radio/aidl/compat/libradiocompat/RadioResponse.cpp
@@ -22,15 +22,20 @@
 
 namespace android::hardware::radio::compat {
 
+RadioResponse::RadioResponse(std::shared_ptr<DriverContext> context) : mContext(context) {}
+
 Return<void> RadioResponse::acknowledgeRequest(int32_t serial) {
     LOG_CALL << serial;
-    // TODO(b/203699028): send to correct requestor or confirm if spam is not a problem
-    if (mDataCb) mDataCb->acknowledgeRequest(serial);
-    if (mMessagingCb) mMessagingCb->acknowledgeRequest(serial);
-    if (mModemCb) mModemCb->acknowledgeRequest(serial);
-    if (mNetworkCb) mNetworkCb->acknowledgeRequest(serial);
-    if (mSimCb) mSimCb->acknowledgeRequest(serial);
-    if (mVoiceCb) mVoiceCb->acknowledgeRequest(serial);
+    /* We send ACKs to all callbacks instead of the one requested it to make implementation simpler.
+     * If it turns out to be a problem, we would have to track where serials come from and make sure
+     * this tracking data (e.g. a map) doesn't grow indefinitely.
+     */
+    if (mDataCb) mDataCb.get()->acknowledgeRequest(serial);
+    if (mMessagingCb) mMessagingCb.get()->acknowledgeRequest(serial);
+    if (mModemCb) mModemCb.get()->acknowledgeRequest(serial);
+    if (mNetworkCb) mNetworkCb.get()->acknowledgeRequest(serial);
+    if (mSimCb) mSimCb.get()->acknowledgeRequest(serial);
+    if (mVoiceCb) mVoiceCb.get()->acknowledgeRequest(serial);
     return {};
 }
 
diff --git a/radio/aidl/compat/libradiocompat/commonStructs.cpp b/radio/aidl/compat/libradiocompat/commonStructs.cpp
index c25768d..6e4c873 100644
--- a/radio/aidl/compat/libradiocompat/commonStructs.cpp
+++ b/radio/aidl/compat/libradiocompat/commonStructs.cpp
@@ -20,11 +20,11 @@
 
 namespace aidl = ::aidl::android::hardware::radio;
 
-V1_6::RadioResponseInfo notSupported(int32_t serial) {
+aidl::RadioResponseInfo notSupported(int32_t serial) {
     return {
-            .type = V1_0::RadioResponseType::SOLICITED,
+            .type = aidl::RadioResponseType::SOLICITED,
             .serial = serial,
-            .error = V1_6::RadioError::REQUEST_NOT_SUPPORTED,
+            .error = aidl::RadioError::REQUEST_NOT_SUPPORTED,
     };
 }
 
diff --git a/radio/aidl/compat/libradiocompat/commonStructs.h b/radio/aidl/compat/libradiocompat/commonStructs.h
index b859916..a4a4869 100644
--- a/radio/aidl/compat/libradiocompat/commonStructs.h
+++ b/radio/aidl/compat/libradiocompat/commonStructs.h
@@ -21,7 +21,7 @@
 
 namespace android::hardware::radio::compat {
 
-V1_6::RadioResponseInfo notSupported(int32_t serial);
+aidl::android::hardware::radio::RadioResponseInfo notSupported(int32_t serial);
 
 std::string toAidl(const hidl_string& str);
 hidl_string toHidl(const std::string& str);
diff --git a/radio/aidl/compat/libradiocompat/config/RadioConfig.cpp b/radio/aidl/compat/libradiocompat/config/RadioConfig.cpp
index d0d6f7a..b450418 100644
--- a/radio/aidl/compat/libradiocompat/config/RadioConfig.cpp
+++ b/radio/aidl/compat/libradiocompat/config/RadioConfig.cpp
@@ -16,12 +16,12 @@
 
 #include <libradiocompat/RadioConfig.h>
 
-#include "RadioConfigIndication.h"
-#include "RadioConfigResponse.h"
 #include "commonStructs.h"
 #include "debug.h"
 #include "structs.h"
 
+#include "collections.h"
+
 #define RADIO_MODULE "Config"
 
 namespace android::hardware::radio::compat {
@@ -31,11 +31,13 @@
 constexpr auto ok = &ScopedAStatus::ok;
 
 RadioConfig::RadioConfig(sp<config::V1_1::IRadioConfig> hidlHal)
-    : mHal1_1(hidlHal), mHal1_3(config::V1_3::IRadioConfig::castFrom(hidlHal)) {}
+    : mHal1_1(hidlHal),
+      mHal1_3(config::V1_3::IRadioConfig::castFrom(hidlHal)),
+      mRadioConfigResponse(sp<RadioConfigResponse>::make()),
+      mRadioConfigIndication(sp<RadioConfigIndication>::make()) {}
 
-config::V1_3::IRadioConfigResponse& RadioConfig::respond() {
-    CHECK(mRadioConfigResponse) << "setResponseFunctions was not called yet";
-    return *mRadioConfigResponse;
+std::shared_ptr<aidl::IRadioConfigResponse> RadioConfig::respond() {
+    return mRadioConfigResponse->respond();
 }
 
 ScopedAStatus RadioConfig::getHalDeviceCapabilities(int32_t serial) {
@@ -43,7 +45,7 @@
     if (mHal1_3) {
         mHal1_3->getHalDeviceCapabilities(serial);
     } else {
-        respond().getHalDeviceCapabilitiesResponse(notSupported(serial), false);
+        respond()->getHalDeviceCapabilitiesResponse(notSupported(serial), false);
     }
     return ok();
 }
@@ -86,9 +88,9 @@
     CHECK(radioConfigResponse);
     CHECK(radioConfigIndication);
 
-    mRadioConfigResponse = sp<RadioConfigResponse>::make(radioConfigResponse);
-    mRadioConfigIndication = sp<RadioConfigIndication>::make(radioConfigIndication);
-    mHal1_1->setResponseFunctions(mRadioConfigResponse, mRadioConfigIndication);
+    mRadioConfigResponse->setResponseFunction(radioConfigResponse);
+    mRadioConfigIndication->setResponseFunction(radioConfigIndication);
+    mHal1_1->setResponseFunctions(mRadioConfigResponse, mRadioConfigIndication).assertOk();
 
     return ok();
 }
diff --git a/radio/aidl/compat/libradiocompat/config/RadioConfigIndication.cpp b/radio/aidl/compat/libradiocompat/config/RadioConfigIndication.cpp
index 0320ad7..c1e32c1 100644
--- a/radio/aidl/compat/libradiocompat/config/RadioConfigIndication.cpp
+++ b/radio/aidl/compat/libradiocompat/config/RadioConfigIndication.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "RadioConfigIndication.h"
+#include <libradiocompat/RadioConfigIndication.h>
 
 #include "commonStructs.h"
 #include "debug.h"
@@ -28,20 +28,26 @@
 
 namespace aidl = ::aidl::android::hardware::radio::config;
 
-RadioConfigIndication::RadioConfigIndication(std::shared_ptr<aidl::IRadioConfigIndication> callback)
-    : mCallback(callback) {}
+void RadioConfigIndication::setResponseFunction(
+        std::shared_ptr<aidl::IRadioConfigIndication> callback) {
+    mCallback = callback;
+}
+
+std::shared_ptr<aidl::IRadioConfigIndication> RadioConfigIndication::indicate() {
+    return mCallback.get();
+}
 
 Return<void> RadioConfigIndication::simSlotsStatusChanged(
         V1_0::RadioIndicationType type, const hidl_vec<config::V1_0::SimSlotStatus>& slotStatus) {
     LOG_CALL << type;
-    mCallback->simSlotsStatusChanged(toAidl(type), toAidl(slotStatus));
+    indicate()->simSlotsStatusChanged(toAidl(type), toAidl(slotStatus));
     return {};
 }
 
 Return<void> RadioConfigIndication::simSlotsStatusChanged_1_2(
         V1_0::RadioIndicationType type, const hidl_vec<config::V1_2::SimSlotStatus>& slotStatus) {
     LOG_CALL << type;
-    mCallback->simSlotsStatusChanged(toAidl(type), toAidl(slotStatus));
+    indicate()->simSlotsStatusChanged(toAidl(type), toAidl(slotStatus));
     return {};
 }
 
diff --git a/radio/aidl/compat/libradiocompat/config/RadioConfigResponse.cpp b/radio/aidl/compat/libradiocompat/config/RadioConfigResponse.cpp
index 7066ae4..523c504 100644
--- a/radio/aidl/compat/libradiocompat/config/RadioConfigResponse.cpp
+++ b/radio/aidl/compat/libradiocompat/config/RadioConfigResponse.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "RadioConfigResponse.h"
+#include <libradiocompat/RadioConfigResponse.h>
 
 #include "commonStructs.h"
 #include "debug.h"
@@ -28,14 +28,20 @@
 
 namespace aidl = ::aidl::android::hardware::radio::config;
 
-RadioConfigResponse::RadioConfigResponse(std::shared_ptr<aidl::IRadioConfigResponse> callback)
-    : mCallback(callback) {}
+void RadioConfigResponse::setResponseFunction(
+        std::shared_ptr<aidl::IRadioConfigResponse> callback) {
+    mCallback = callback;
+}
+
+std::shared_ptr<aidl::IRadioConfigResponse> RadioConfigResponse::respond() {
+    return mCallback.get();
+}
 
 Return<void> RadioConfigResponse::getSimSlotsStatusResponse(
         const V1_0::RadioResponseInfo& info,
         const hidl_vec<config::V1_0::SimSlotStatus>& slotStatus) {
     LOG_CALL << info.serial;
-    mCallback->getSimSlotsStatusResponse(toAidl(info), toAidl(slotStatus));
+    respond()->getSimSlotsStatusResponse(toAidl(info), toAidl(slotStatus));
     return {};
 };
 
@@ -43,47 +49,47 @@
         const V1_0::RadioResponseInfo& info,
         const hidl_vec<config::V1_2::SimSlotStatus>& slotStatus) {
     LOG_CALL << info.serial;
-    mCallback->getSimSlotsStatusResponse(toAidl(info), toAidl(slotStatus));
+    respond()->getSimSlotsStatusResponse(toAidl(info), toAidl(slotStatus));
     return {};
 };
 
 Return<void> RadioConfigResponse::setSimSlotsMappingResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    mCallback->setSimSlotsMappingResponse(toAidl(info));
+    respond()->setSimSlotsMappingResponse(toAidl(info));
     return {};
 };
 
 Return<void> RadioConfigResponse::getPhoneCapabilityResponse(
         const V1_0::RadioResponseInfo& info, const config::V1_1::PhoneCapability& phoneCapability) {
     LOG_CALL << info.serial;
-    mCallback->getPhoneCapabilityResponse(toAidl(info), toAidl(phoneCapability));
+    respond()->getPhoneCapabilityResponse(toAidl(info), toAidl(phoneCapability));
     return {};
 };
 
 Return<void> RadioConfigResponse::setPreferredDataModemResponse(
         const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    mCallback->setPreferredDataModemResponse(toAidl(info));
+    respond()->setPreferredDataModemResponse(toAidl(info));
     return {};
 };
 
 Return<void> RadioConfigResponse::setModemsConfigResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    mCallback->setNumOfLiveModemsResponse(toAidl(info));
+    respond()->setNumOfLiveModemsResponse(toAidl(info));
     return {};
 };
 
 Return<void> RadioConfigResponse::getModemsConfigResponse(
         const V1_0::RadioResponseInfo& info, const config::V1_1::ModemsConfig& modemsConfig) {
     LOG_CALL << info.serial;
-    mCallback->getNumOfLiveModemsResponse(toAidl(info), modemsConfig.numOfLiveModems);
+    respond()->getNumOfLiveModemsResponse(toAidl(info), modemsConfig.numOfLiveModems);
     return {};
 };
 
 Return<void> RadioConfigResponse::getHalDeviceCapabilitiesResponse(
         const V1_6::RadioResponseInfo& info, bool modemReducedFeatureSet1) {
     LOG_CALL << info.serial;
-    mCallback->getHalDeviceCapabilitiesResponse(toAidl(info), modemReducedFeatureSet1);
+    respond()->getHalDeviceCapabilitiesResponse(toAidl(info), modemReducedFeatureSet1);
     return {};
 };
 
diff --git a/radio/aidl/compat/libradiocompat/config/structs.cpp b/radio/aidl/compat/libradiocompat/config/structs.cpp
index 9ba5623..39ad944 100644
--- a/radio/aidl/compat/libradiocompat/config/structs.cpp
+++ b/radio/aidl/compat/libradiocompat/config/structs.cpp
@@ -24,14 +24,11 @@
 
 namespace aidl = ::aidl::android::hardware::radio::config;
 
-hidl_vec<uint32_t> toHidl(const std::vector<aidl::SlotPortMapping>& slotMap) {
-    hidl_vec<uint32_t> out(slotMap.size());
-    for (const auto& el : slotMap) {
-        CHECK_GE(el.portId, 0);
-        CHECK_LT(static_cast<size_t>(el.portId), out.size());
-        out[el.portId] = el.physicalSlotId;
+uint32_t toHidl(const aidl::SlotPortMapping& slotPortMapping) {
+    if (slotPortMapping.portId != 0) {
+        LOG(ERROR) << "Port ID " << slotPortMapping.portId << " != 0 not supported by HIDL HAL";
     }
-    return out;
+    return slotPortMapping.physicalSlotId;
 }
 
 aidl::SimSlotStatus toAidl(const config::V1_0::SimSlotStatus& sst) {
diff --git a/radio/aidl/compat/libradiocompat/config/structs.h b/radio/aidl/compat/libradiocompat/config/structs.h
index b8a0385..6ea4e4a 100644
--- a/radio/aidl/compat/libradiocompat/config/structs.h
+++ b/radio/aidl/compat/libradiocompat/config/structs.h
@@ -23,8 +23,7 @@
 
 namespace android::hardware::radio::compat {
 
-hidl_vec<uint32_t>  //
-toHidl(const std::vector<aidl::android::hardware::radio::config::SlotPortMapping>& slotMap);
+uint32_t toHidl(const aidl::android::hardware::radio::config::SlotPortMapping& slotPortMapping);
 
 aidl::android::hardware::radio::config::SimSlotStatus  //
 toAidl(const config::V1_0::SimSlotStatus& sst);
diff --git a/radio/aidl/compat/libradiocompat/data/RadioData.cpp b/radio/aidl/compat/libradiocompat/data/RadioData.cpp
index fdb1273..d2f3687 100644
--- a/radio/aidl/compat/libradiocompat/data/RadioData.cpp
+++ b/radio/aidl/compat/libradiocompat/data/RadioData.cpp
@@ -31,12 +31,16 @@
 namespace aidlCommon = ::aidl::android::hardware::radio;
 constexpr auto ok = &ScopedAStatus::ok;
 
+std::shared_ptr<aidl::IRadioDataResponse> RadioData::respond() {
+    return mCallbackManager->response().dataCb();
+}
+
 ScopedAStatus RadioData::allocatePduSessionId(int32_t serial) {
     LOG_CALL << serial;
     if (mHal1_6) {
         mHal1_6->allocatePduSessionId(serial);
     } else {
-        respond().allocatePduSessionIdResponse(notSupported(serial), 0);
+        respond()->allocatePduSessionIdResponse(notSupported(serial), 0);
     }
     return ok();
 }
@@ -46,7 +50,7 @@
     if (mHal1_6) {
         mHal1_6->cancelHandover(serial, callId);
     } else {
-        respond().cancelHandoverResponse(notSupported(serial));
+        respond()->cancelHandoverResponse(notSupported(serial));
     }
     return ok();
 }
@@ -60,7 +64,11 @@
 
 ScopedAStatus RadioData::getDataCallList(int32_t serial) {
     LOG_CALL << serial;
-    mHal1_5->getDataCallList(serial);
+    if (mHal1_6) {
+        mHal1_6->getDataCallList_1_6(serial);
+    } else {
+        mHal1_5->getDataCallList(serial);
+    }
     return ok();
 }
 
@@ -69,7 +77,7 @@
     if (mHal1_6) {
         mHal1_6->getSlicingConfig(serial);
     } else {
-        respond().getSlicingConfigResponse(notSupported(serial), {});
+        respond()->getSlicingConfigResponse(notSupported(serial), {});
     }
     return ok();
 }
@@ -79,7 +87,7 @@
     if (mHal1_6) {
         mHal1_6->releasePduSessionId(serial, id);
     } else {
-        respond().releasePduSessionIdResponse(notSupported(serial));
+        respond()->releasePduSessionIdResponse(notSupported(serial));
     }
     return ok();
 }
@@ -109,7 +117,7 @@
     if (mHal1_6) {
         mHal1_6->setDataThrottling(serial, V1_6::DataThrottlingAction(dta), completionDurationMs);
     } else {
-        respond().setDataThrottlingResponse(notSupported(serial));
+        respond()->setDataThrottlingResponse(notSupported(serial));
     }
     return ok();
 }
@@ -121,16 +129,10 @@
 }
 
 ScopedAStatus RadioData::setResponseFunctions(
-        const std::shared_ptr<aidl::IRadioDataResponse>& dataResponse,
-        const std::shared_ptr<aidl::IRadioDataIndication>& dataIndication) {
-    LOG_CALL << dataResponse << ' ' << dataIndication;
-
-    CHECK(dataResponse);
-    CHECK(dataIndication);
-
-    mRadioResponse->setResponseFunction(dataResponse);
-    mRadioIndication->setResponseFunction(dataIndication);
-
+        const std::shared_ptr<aidl::IRadioDataResponse>& response,
+        const std::shared_ptr<aidl::IRadioDataIndication>& indication) {
+    LOG_CALL << response << ' ' << indication;
+    mCallbackManager->setResponseFunctions(response, indication);
     return ok();
 }
 
@@ -139,14 +141,15 @@
         const aidl::DataProfileInfo& dataProfileInfo, bool roamingAllowed,
         aidl::DataRequestReason reason, const std::vector<aidl::LinkAddress>& addresses,
         const std::vector<std::string>& dnses, int32_t pduSessId,
-        const std::optional<aidl::SliceInfo>& sliceInfo,
-        const std::optional<aidl::TrafficDescriptor>& trDesc, bool matchAllRuleAllowed) {
+        const std::optional<aidl::SliceInfo>& sliceInfo, bool matchAllRuleAllowed) {
     if (mHal1_6) {
         mHal1_6->setupDataCall_1_6(  //
                 serial, V1_5::AccessNetwork(accessNetwork), toHidl(dataProfileInfo), roamingAllowed,
                 V1_2::DataRequestReason(reason), toHidl(addresses), toHidl(dnses), pduSessId,
                 toHidl<V1_6::OptionalSliceInfo>(sliceInfo),
-                toHidl<V1_6::OptionalTrafficDescriptor>(trDesc), matchAllRuleAllowed);
+                toHidl<V1_6::OptionalTrafficDescriptor>(dataProfileInfo.trafficDescriptor),
+                matchAllRuleAllowed);
+        mContext->addDataProfile(dataProfileInfo);
     } else {
         mHal1_5->setupDataCall_1_5(  //
                 serial, V1_5::AccessNetwork(accessNetwork), toHidl(dataProfileInfo), roamingAllowed,
@@ -160,7 +163,7 @@
     if (mHal1_6) {
         mHal1_6->startHandover(serial, callId);
     } else {
-        respond().startHandoverResponse(notSupported(serial));
+        respond()->startHandoverResponse(notSupported(serial));
     }
     return ok();
 }
diff --git a/radio/aidl/compat/libradiocompat/data/RadioIndication-data.cpp b/radio/aidl/compat/libradiocompat/data/RadioIndication-data.cpp
index f51d1a8..1d367d2 100644
--- a/radio/aidl/compat/libradiocompat/data/RadioIndication-data.cpp
+++ b/radio/aidl/compat/libradiocompat/data/RadioIndication-data.cpp
@@ -29,10 +29,13 @@
 namespace aidl = ::aidl::android::hardware::radio::data;
 
 void RadioIndication::setResponseFunction(std::shared_ptr<aidl::IRadioDataIndication> dataCb) {
-    CHECK(dataCb);
     mDataCb = dataCb;
 }
 
+std::shared_ptr<aidl::IRadioDataIndication> RadioIndication::dataCb() {
+    return mDataCb.get();
+}
+
 Return<void> RadioIndication::dataCallListChanged(V1_0::RadioIndicationType type,
                                                   const hidl_vec<V1_0::SetupDataCallResult>&) {
     LOG_CALL << type;
@@ -50,40 +53,35 @@
 Return<void> RadioIndication::dataCallListChanged_1_5(
         V1_0::RadioIndicationType type, const hidl_vec<V1_5::SetupDataCallResult>& dcList) {
     LOG_CALL << type;
-    CHECK_CB(mDataCb);
-    mDataCb->dataCallListChanged(toAidl(type), toAidl(dcList));
+    dataCb()->dataCallListChanged(toAidl(type), toAidl(dcList));
     return {};
 }
 
 Return<void> RadioIndication::dataCallListChanged_1_6(
         V1_0::RadioIndicationType type, const hidl_vec<V1_6::SetupDataCallResult>& dcList) {
     LOG_CALL << type;
-    CHECK_CB(mDataCb);
-    mDataCb->dataCallListChanged(toAidl(type), toAidl(dcList));
+    dataCb()->dataCallListChanged(toAidl(type), toAidl(dcList));
     return {};
 }
 
 Return<void> RadioIndication::keepaliveStatus(V1_0::RadioIndicationType type,
                                               const V1_1::KeepaliveStatus& status) {
     LOG_CALL << type;
-    CHECK_CB(mDataCb);
-    mDataCb->keepaliveStatus(toAidl(type), toAidl(status));
+    dataCb()->keepaliveStatus(toAidl(type), toAidl(status));
     return {};
 }
 
 Return<void> RadioIndication::pcoData(V1_0::RadioIndicationType type,
                                       const V1_0::PcoDataInfo& pco) {
     LOG_CALL << type;
-    CHECK_CB(mDataCb);
-    mDataCb->pcoData(toAidl(type), toAidl(pco));
+    dataCb()->pcoData(toAidl(type), toAidl(pco));
     return {};
 }
 
 Return<void> RadioIndication::unthrottleApn(V1_0::RadioIndicationType type,
                                             const hidl_string& apn) {
     LOG_CALL << type;
-    CHECK_CB(mDataCb);
-    mDataCb->unthrottleApn(toAidl(type), apn);
+    dataCb()->unthrottleApn(toAidl(type), mContext->getDataProfile(apn));
     return {};
 }
 
diff --git a/radio/aidl/compat/libradiocompat/data/RadioResponse-data.cpp b/radio/aidl/compat/libradiocompat/data/RadioResponse-data.cpp
index 171f692..0bfa2df 100644
--- a/radio/aidl/compat/libradiocompat/data/RadioResponse-data.cpp
+++ b/radio/aidl/compat/libradiocompat/data/RadioResponse-data.cpp
@@ -29,29 +29,29 @@
 namespace aidl = ::aidl::android::hardware::radio::data;
 
 void RadioResponse::setResponseFunction(std::shared_ptr<aidl::IRadioDataResponse> dataCb) {
-    CHECK(dataCb);
     mDataCb = dataCb;
 }
 
+std::shared_ptr<aidl::IRadioDataResponse> RadioResponse::dataCb() {
+    return mDataCb.get();
+}
+
 Return<void> RadioResponse::allocatePduSessionIdResponse(const V1_6::RadioResponseInfo& info,
                                                          int32_t id) {
     LOG_CALL << info.serial;
-    CHECK_CB(mDataCb);
-    mDataCb->allocatePduSessionIdResponse(toAidl(info), id);
+    dataCb()->allocatePduSessionIdResponse(toAidl(info), id);
     return {};
 }
 
 Return<void> RadioResponse::cancelHandoverResponse(const V1_6::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mDataCb);
-    mDataCb->cancelHandoverResponse(toAidl(info));
+    dataCb()->cancelHandoverResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::deactivateDataCallResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mDataCb);
-    mDataCb->deactivateDataCallResponse(toAidl(info));
+    dataCb()->deactivateDataCallResponse(toAidl(info));
     return {};
 }
 
@@ -73,8 +73,7 @@
         const V1_0::RadioResponseInfo& info,
         const hidl_vec<V1_5::SetupDataCallResult>& dcResponse) {
     LOG_CALL << info.serial;
-    CHECK_CB(mDataCb);
-    mDataCb->getDataCallListResponse(toAidl(info), toAidl(dcResponse));
+    dataCb()->getDataCallListResponse(toAidl(info), toAidl(dcResponse));
     return {};
 }
 
@@ -82,65 +81,56 @@
         const V1_6::RadioResponseInfo& info,
         const hidl_vec<V1_6::SetupDataCallResult>& dcResponse) {
     LOG_CALL << info.serial;
-    CHECK_CB(mDataCb);
-    mDataCb->getDataCallListResponse(toAidl(info), toAidl(dcResponse));
+    dataCb()->getDataCallListResponse(toAidl(info), toAidl(dcResponse));
     return {};
 }
 
 Return<void> RadioResponse::getSlicingConfigResponse(const V1_6::RadioResponseInfo& info,
                                                      const V1_6::SlicingConfig& slicingConfig) {
     LOG_CALL << info.serial;
-    CHECK_CB(mDataCb);
-    mDataCb->getSlicingConfigResponse(toAidl(info), toAidl(slicingConfig));
+    dataCb()->getSlicingConfigResponse(toAidl(info), toAidl(slicingConfig));
     return {};
 }
 
 Return<void> RadioResponse::releasePduSessionIdResponse(const V1_6::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mDataCb);
-    mDataCb->releasePduSessionIdResponse(toAidl(info));
+    dataCb()->releasePduSessionIdResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setDataAllowedResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mDataCb);
-    mDataCb->setDataAllowedResponse(toAidl(info));
+    dataCb()->setDataAllowedResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setDataProfileResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mDataCb);
-    mDataCb->setDataProfileResponse(toAidl(info));
+    dataCb()->setDataProfileResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setDataProfileResponse_1_5(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mDataCb);
-    mDataCb->setDataProfileResponse(toAidl(info));
+    dataCb()->setDataProfileResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setDataThrottlingResponse(const V1_6::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mDataCb);
-    mDataCb->setDataThrottlingResponse(toAidl(info));
+    dataCb()->setDataThrottlingResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setInitialAttachApnResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mDataCb);
-    mDataCb->setInitialAttachApnResponse(toAidl(info));
+    dataCb()->setInitialAttachApnResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setInitialAttachApnResponse_1_5(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mDataCb);
-    mDataCb->setInitialAttachApnResponse(toAidl(info));
+    dataCb()->setInitialAttachApnResponse(toAidl(info));
     return {};
 }
 
@@ -161,38 +151,33 @@
 Return<void> RadioResponse::setupDataCallResponse_1_5(const V1_0::RadioResponseInfo& info,
                                                       const V1_5::SetupDataCallResult& dcResponse) {
     LOG_CALL << info.serial;
-    CHECK_CB(mDataCb);
-    mDataCb->setupDataCallResponse(toAidl(info), toAidl(dcResponse));
+    dataCb()->setupDataCallResponse(toAidl(info), toAidl(dcResponse));
     return {};
 }
 
 Return<void> RadioResponse::setupDataCallResponse_1_6(const V1_6::RadioResponseInfo& info,
                                                       const V1_6::SetupDataCallResult& dcResponse) {
     LOG_CALL << info.serial;
-    CHECK_CB(mDataCb);
-    mDataCb->setupDataCallResponse(toAidl(info), toAidl(dcResponse));
+    dataCb()->setupDataCallResponse(toAidl(info), toAidl(dcResponse));
     return {};
 }
 
 Return<void> RadioResponse::startHandoverResponse(const V1_6::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mDataCb);
-    mDataCb->startHandoverResponse(toAidl(info));
+    dataCb()->startHandoverResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::startKeepaliveResponse(const V1_0::RadioResponseInfo& info,
                                                    const V1_1::KeepaliveStatus& status) {
     LOG_CALL << info.serial;
-    CHECK_CB(mDataCb);
-    mDataCb->startKeepaliveResponse(toAidl(info), toAidl(status));
+    dataCb()->startKeepaliveResponse(toAidl(info), toAidl(status));
     return {};
 }
 
 Return<void> RadioResponse::stopKeepaliveResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mDataCb);
-    mDataCb->stopKeepaliveResponse(toAidl(info));
+    dataCb()->stopKeepaliveResponse(toAidl(info));
     return {};
 }
 
diff --git a/radio/aidl/compat/libradiocompat/debug.h b/radio/aidl/compat/libradiocompat/debug.h
index 4158059..cb773bf 100644
--- a/radio/aidl/compat/libradiocompat/debug.h
+++ b/radio/aidl/compat/libradiocompat/debug.h
@@ -26,12 +26,6 @@
 #define LOG_CALL \
     if constexpr (debug::kSuperVerbose) LOG(VERBOSE) << (RADIO_MODULE ".") << __func__ << ' '
 
-#define CHECK_CB(field)                     \
-    if (!field) {                           \
-        LOG(WARNING) << "Callback not set"; \
-        return {};                          \
-    }
-
 }  // namespace debug
 
 inline std::ostream& operator<<(std::ostream& os, const V1_0::RadioIndicationType& type) {
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/CallbackManager.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/CallbackManager.h
new file mode 100644
index 0000000..f1a7b49
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/CallbackManager.h
@@ -0,0 +1,62 @@
+/*
+ * 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 "DriverContext.h"
+#include "RadioIndication.h"
+#include "RadioResponse.h"
+
+#include <android-base/logging.h>
+#include <android/hardware/radio/1.6/IRadio.h>
+
+#include <thread>
+
+namespace android::hardware::radio::compat {
+
+class CallbackManager {
+    sp<V1_5::IRadio> mHidlHal;
+    sp<RadioResponse> mRadioResponse;
+    sp<RadioIndication> mRadioIndication;
+
+    std::thread mDelayedSetterThread;
+    std::mutex mDelayedSetterGuard;
+    std::optional<std::chrono::time_point<std::chrono::steady_clock>> mDelayedSetterDeadline
+            GUARDED_BY(mDelayedSetterGuard);
+    std::condition_variable mDelayedSetterCv GUARDED_BY(mDelayedSetterGuard);
+    bool mDestroy GUARDED_BY(mDelayedSetterGuard) = false;
+
+    void setResponseFunctionsDelayed();
+    void delayedSetterThread();
+
+  public:
+    CallbackManager(std::shared_ptr<DriverContext> context, sp<V1_5::IRadio> hidlHal);
+    ~CallbackManager();
+
+    RadioResponse& response() const;
+
+    template <typename ResponseType, typename IndicationType>
+    void setResponseFunctions(const std::shared_ptr<ResponseType>& response,
+                              const std::shared_ptr<IndicationType>& indication) {
+        CHECK(response);
+        CHECK(indication);
+
+        mRadioResponse->setResponseFunction(response);
+        mRadioIndication->setResponseFunction(indication);
+        setResponseFunctionsDelayed();
+    }
+};
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/DriverContext.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/DriverContext.h
new file mode 100644
index 0000000..6833aca
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/DriverContext.h
@@ -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.
+ */
+#pragma once
+
+#include <aidl/android/hardware/radio/data/DataProfileInfo.h>
+
+#include <map>
+
+namespace android::hardware::radio::compat {
+
+class DriverContext {
+    std::map<std::string, ::aidl::android::hardware::radio::data::DataProfileInfo> mDataProfiles;
+
+  public:
+    void addDataProfile(const ::aidl::android::hardware::radio::data::DataProfileInfo& profile);
+    ::aidl::android::hardware::radio::data::DataProfileInfo getDataProfile(const std::string& apn);
+};
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/GuaranteedCallback.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/GuaranteedCallback.h
new file mode 100644
index 0000000..0b6ee11
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/GuaranteedCallback.h
@@ -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.
+ */
+#pragma once
+
+#include <android-base/logging.h>
+#include <android/binder_interface_utils.h>
+#include <utils/Mutex.h>
+
+namespace android::hardware::radio::compat {
+
+template <typename Interface, typename DefaultImplementation, bool isIndication = false>
+class GuaranteedCallback {
+    mutable std::mutex mCallbackGuard;
+    std::shared_ptr<Interface> mCallback GUARDED_BY(mCallbackGuard);
+
+  public:
+    GuaranteedCallback<Interface, DefaultImplementation, isIndication>& operator=(
+            const std::shared_ptr<Interface>& callback) {
+        CHECK(callback);
+        const std::lock_guard<std::mutex> lock(mCallbackGuard);
+        mCallback = callback;
+        return *this;
+    }
+
+    std::shared_ptr<Interface> get() {
+        if (mCallback) return mCallback;
+        const std::lock_guard<std::mutex> lock(mCallbackGuard);
+        if (mCallback) return mCallback;
+
+        LOG(isIndication ? WARNING : ERROR) << "Callback is not set";
+        return mCallback = ndk::SharedRefBase::make<DefaultImplementation>();
+    }
+
+    operator bool() const { return mCallback != nullptr; }
+};
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioCompatBase.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioCompatBase.h
index a412c34..eb22fff 100644
--- a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioCompatBase.h
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioCompatBase.h
@@ -15,8 +15,8 @@
  */
 #pragma once
 
-#include "RadioIndication.h"
-#include "RadioResponse.h"
+#include "CallbackManager.h"
+#include "DriverContext.h"
 
 #include <android/hardware/radio/1.6/IRadio.h>
 
@@ -24,17 +24,16 @@
 
 class RadioCompatBase {
   protected:
+    std::shared_ptr<DriverContext> mContext;
+
     sp<V1_5::IRadio> mHal1_5;
     sp<V1_6::IRadio> mHal1_6;
 
-    sp<RadioResponse> mRadioResponse;
-    sp<RadioIndication> mRadioIndication;
-
-    V1_6::IRadioResponse& respond();
+    std::shared_ptr<CallbackManager> mCallbackManager;
 
   public:
-    RadioCompatBase(sp<V1_5::IRadio> hidlHal, sp<RadioResponse> radioResponse,
-                    sp<RadioIndication> radioIndication);
+    RadioCompatBase(std::shared_ptr<DriverContext> context, sp<V1_5::IRadio> hidlHal,
+                    std::shared_ptr<CallbackManager> cbMgr);
 };
 
 }  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioConfig.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioConfig.h
index 31ad207..bbfff61 100644
--- a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioConfig.h
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioConfig.h
@@ -15,6 +15,9 @@
  */
 #pragma once
 
+#include "RadioConfigIndication.h"
+#include "RadioConfigResponse.h"
+
 #include <aidl/android/hardware/radio/config/BnRadioConfig.h>
 #include <android/hardware/radio/config/1.2/IRadioConfigIndication.h>
 #include <android/hardware/radio/config/1.3/IRadioConfig.h>
@@ -30,11 +33,13 @@
  * fetch source implementation and publish resulting HAL instance.
  */
 class RadioConfig : public aidl::android::hardware::radio::config::BnRadioConfig {
-    sp<config::V1_1::IRadioConfig> mHal1_1;
-    sp<config::V1_3::IRadioConfig> mHal1_3;
+    const sp<config::V1_1::IRadioConfig> mHal1_1;
+    const sp<config::V1_3::IRadioConfig> mHal1_3;
 
-    sp<config::V1_3::IRadioConfigResponse> mRadioConfigResponse;
-    sp<config::V1_2::IRadioConfigIndication> mRadioConfigIndication;
+    const sp<RadioConfigResponse> mRadioConfigResponse;
+    const sp<RadioConfigIndication> mRadioConfigIndication;
+
+    std::shared_ptr<::aidl::android::hardware::radio::config::IRadioConfigResponse> respond();
 
     ::ndk::ScopedAStatus getHalDeviceCapabilities(int32_t serial) override;
     ::ndk::ScopedAStatus getNumOfLiveModems(int32_t serial) override;
@@ -52,8 +57,6 @@
             const std::vector<aidl::android::hardware::radio::config::SlotPortMapping>& slotMap)
             override;
 
-    config::V1_3::IRadioConfigResponse& respond();
-
   public:
     /**
      * Constructs AIDL IRadioConfig instance wrapping existing HIDL IRadioConfig instance.
diff --git a/radio/aidl/compat/libradiocompat/config/RadioConfigIndication.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioConfigIndication.h
similarity index 82%
rename from radio/aidl/compat/libradiocompat/config/RadioConfigIndication.h
rename to radio/aidl/compat/libradiocompat/include/libradiocompat/RadioConfigIndication.h
index 3d8d971..d256a87 100644
--- a/radio/aidl/compat/libradiocompat/config/RadioConfigIndication.h
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioConfigIndication.h
@@ -15,13 +15,17 @@
  */
 #pragma once
 
+#include "GuaranteedCallback.h"
+
 #include <aidl/android/hardware/radio/config/IRadioConfigIndication.h>
 #include <android/hardware/radio/config/1.2/IRadioConfigIndication.h>
 
 namespace android::hardware::radio::compat {
 
 class RadioConfigIndication : public config::V1_2::IRadioConfigIndication {
-    std::shared_ptr<aidl::android::hardware::radio::config::IRadioConfigIndication> mCallback;
+    GuaranteedCallback<aidl::android::hardware::radio::config::IRadioConfigIndication,
+                       aidl::android::hardware::radio::config::IRadioConfigIndicationDefault, true>
+            mCallback;
 
     Return<void> simSlotsStatusChanged(
             V1_0::RadioIndicationType type,
@@ -31,8 +35,10 @@
             const hidl_vec<config::V1_2::SimSlotStatus>& slotStatus) override;
 
   public:
-    RadioConfigIndication(
+    void setResponseFunction(
             std::shared_ptr<aidl::android::hardware::radio::config::IRadioConfigIndication> cb);
+
+    std::shared_ptr<aidl::android::hardware::radio::config::IRadioConfigIndication> indicate();
 };
 
 }  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/config/RadioConfigResponse.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioConfigResponse.h
similarity index 88%
rename from radio/aidl/compat/libradiocompat/config/RadioConfigResponse.h
rename to radio/aidl/compat/libradiocompat/include/libradiocompat/RadioConfigResponse.h
index 1461dd2..dc86da2 100644
--- a/radio/aidl/compat/libradiocompat/config/RadioConfigResponse.h
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioConfigResponse.h
@@ -15,13 +15,17 @@
  */
 #pragma once
 
+#include "GuaranteedCallback.h"
+
 #include <aidl/android/hardware/radio/config/IRadioConfigResponse.h>
 #include <android/hardware/radio/config/1.3/IRadioConfigResponse.h>
 
 namespace android::hardware::radio::compat {
 
 class RadioConfigResponse : public config::V1_3::IRadioConfigResponse {
-    std::shared_ptr<aidl::android::hardware::radio::config::IRadioConfigResponse> mCallback;
+    GuaranteedCallback<aidl::android::hardware::radio::config::IRadioConfigResponse,
+                       aidl::android::hardware::radio::config::IRadioConfigResponseDefault>
+            mCallback;
 
     Return<void> getSimSlotsStatusResponse(
             const V1_0::RadioResponseInfo& info,
@@ -41,8 +45,10 @@
                                                   bool modemReducedFeatureSet1) override;
 
   public:
-    RadioConfigResponse(
+    void setResponseFunction(
             std::shared_ptr<aidl::android::hardware::radio::config::IRadioConfigResponse> callback);
+
+    std::shared_ptr<aidl::android::hardware::radio::config::IRadioConfigResponse> respond();
 };
 
 }  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioData.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioData.h
index 900a669..c617ec2 100644
--- a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioData.h
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioData.h
@@ -22,6 +22,8 @@
 namespace android::hardware::radio::compat {
 
 class RadioData : public RadioCompatBase, public aidl::android::hardware::radio::data::BnRadioData {
+    std::shared_ptr<::aidl::android::hardware::radio::data::IRadioDataResponse> respond();
+
     ::ndk::ScopedAStatus allocatePduSessionId(int32_t serial) override;
     ::ndk::ScopedAStatus cancelHandover(int32_t serial, int32_t callId) override;
     ::ndk::ScopedAStatus deactivateDataCall(
@@ -55,7 +57,6 @@
             const std::vector<::aidl::android::hardware::radio::data::LinkAddress>& addresses,
             const std::vector<std::string>& dnses, int32_t pduSessionId,
             const std::optional<::aidl::android::hardware::radio::data::SliceInfo>& sliceInfo,
-            const std::optional<::aidl::android::hardware::radio::data::TrafficDescriptor>& trDescr,
             bool matchAllRuleAllowed) override;
     ::ndk::ScopedAStatus startHandover(int32_t serial, int32_t callId) override;
     ::ndk::ScopedAStatus startKeepalive(
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioIndication.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioIndication.h
index 20e0973..c668af5 100644
--- a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioIndication.h
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioIndication.h
@@ -15,6 +15,9 @@
  */
 #pragma once
 
+#include "DriverContext.h"
+#include "GuaranteedCallback.h"
+
 #include <aidl/android/hardware/radio/data/IRadioDataIndication.h>
 #include <aidl/android/hardware/radio/messaging/IRadioMessagingIndication.h>
 #include <aidl/android/hardware/radio/modem/IRadioModemIndication.h>
@@ -26,13 +29,32 @@
 namespace android::hardware::radio::compat {
 
 class RadioIndication : public V1_6::IRadioIndication {
-    std::shared_ptr<::aidl::android::hardware::radio::data::IRadioDataIndication> mDataCb;
-    std::shared_ptr<::aidl::android::hardware::radio::messaging::IRadioMessagingIndication>
+    std::shared_ptr<DriverContext> mContext;
+
+    GuaranteedCallback<  //
+            ::aidl::android::hardware::radio::data::IRadioDataIndication,
+            ::aidl::android::hardware::radio::data::IRadioDataIndicationDefault, true>
+            mDataCb;
+    GuaranteedCallback<  //
+            ::aidl::android::hardware::radio::messaging::IRadioMessagingIndication,
+            ::aidl::android::hardware::radio::messaging::IRadioMessagingIndicationDefault, true>
             mMessagingCb;
-    std::shared_ptr<::aidl::android::hardware::radio::modem::IRadioModemIndication> mModemCb;
-    std::shared_ptr<::aidl::android::hardware::radio::network::IRadioNetworkIndication> mNetworkCb;
-    std::shared_ptr<::aidl::android::hardware::radio::sim::IRadioSimIndication> mSimCb;
-    std::shared_ptr<::aidl::android::hardware::radio::voice::IRadioVoiceIndication> mVoiceCb;
+    GuaranteedCallback<  //
+            ::aidl::android::hardware::radio::modem::IRadioModemIndication,
+            ::aidl::android::hardware::radio::modem::IRadioModemIndicationDefault, true>
+            mModemCb;
+    GuaranteedCallback<  //
+            ::aidl::android::hardware::radio::network::IRadioNetworkIndication,
+            ::aidl::android::hardware::radio::network::IRadioNetworkIndicationDefault, true>
+            mNetworkCb;
+    GuaranteedCallback<  //
+            ::aidl::android::hardware::radio::sim::IRadioSimIndication,
+            ::aidl::android::hardware::radio::sim::IRadioSimIndicationDefault, true>
+            mSimCb;
+    GuaranteedCallback<  //
+            ::aidl::android::hardware::radio::voice::IRadioVoiceIndication,
+            ::aidl::android::hardware::radio::voice::IRadioVoiceIndicationDefault, true>
+            mVoiceCb;
 
     // IRadioIndication @ 1.0
     Return<void> radioStateChanged(V1_0::RadioIndicationType type,
@@ -181,6 +203,8 @@
             const hidl_vec<V1_6::PhonebookRecordInfo>& records) override;
 
   public:
+    RadioIndication(std::shared_ptr<DriverContext> context);
+
     void setResponseFunction(
             std::shared_ptr<::aidl::android::hardware::radio::data::IRadioDataIndication> dataCb);
     void setResponseFunction(
@@ -194,6 +218,14 @@
             std::shared_ptr<::aidl::android::hardware::radio::sim::IRadioSimIndication> simCb);
     void setResponseFunction(
             std::shared_ptr<::aidl::android::hardware::radio::voice::IRadioVoiceIndication> voicCb);
+
+    std::shared_ptr<::aidl::android::hardware::radio::data::IRadioDataIndication> dataCb();
+    std::shared_ptr<::aidl::android::hardware::radio::messaging::IRadioMessagingIndication>
+    messagingCb();
+    std::shared_ptr<::aidl::android::hardware::radio::modem::IRadioModemIndication> modemCb();
+    std::shared_ptr<::aidl::android::hardware::radio::network::IRadioNetworkIndication> networkCb();
+    std::shared_ptr<::aidl::android::hardware::radio::sim::IRadioSimIndication> simCb();
+    std::shared_ptr<::aidl::android::hardware::radio::voice::IRadioVoiceIndication> voiceCb();
 };
 
 }  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioMessaging.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioMessaging.h
index 0cd3381..419e9fb 100644
--- a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioMessaging.h
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioMessaging.h
@@ -23,6 +23,8 @@
 
 class RadioMessaging : public RadioCompatBase,
                        public aidl::android::hardware::radio::messaging::BnRadioMessaging {
+    std::shared_ptr<::aidl::android::hardware::radio::messaging::IRadioMessagingResponse> respond();
+
     ::ndk::ScopedAStatus acknowledgeIncomingGsmSmsWithPdu(int32_t serial, bool success,
                                                           const std::string& ackPdu) override;
     ::ndk::ScopedAStatus acknowledgeLastIncomingCdmaSms(
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioModem.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioModem.h
index 666ff47..fdca124 100644
--- a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioModem.h
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioModem.h
@@ -23,6 +23,8 @@
 
 class RadioModem : public RadioCompatBase,
                    public aidl::android::hardware::radio::modem::BnRadioModem {
+    std::shared_ptr<::aidl::android::hardware::radio::modem::IRadioModemResponse> respond();
+
     ::ndk::ScopedAStatus enableModem(int32_t serial, bool on) override;
     ::ndk::ScopedAStatus getBasebandVersion(int32_t serial) override;
     ::ndk::ScopedAStatus getDeviceIdentity(int32_t serial) override;
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioNetwork.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioNetwork.h
index 09ae240..1731b78 100644
--- a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioNetwork.h
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioNetwork.h
@@ -23,6 +23,8 @@
 
 class RadioNetwork : public RadioCompatBase,
                      public aidl::android::hardware::radio::network::BnRadioNetwork {
+    std::shared_ptr<::aidl::android::hardware::radio::network::IRadioNetworkResponse> respond();
+
     ::ndk::ScopedAStatus getAllowedNetworkTypesBitmap(int32_t serial) override;
     ::ndk::ScopedAStatus getAvailableBandModes(int32_t serial) override;
     ::ndk::ScopedAStatus getAvailableNetworks(int32_t serial) override;
@@ -39,9 +41,8 @@
     ::ndk::ScopedAStatus getVoiceRegistrationState(int32_t serial) override;
     ::ndk::ScopedAStatus isNrDualConnectivityEnabled(int32_t serial) override;
     ::ndk::ScopedAStatus responseAcknowledgement() override;
-    ::ndk::ScopedAStatus setAllowedNetworkTypesBitmap(
-            int32_t serial,
-            ::aidl::android::hardware::radio::RadioAccessFamily networkTypeBitmap) override;
+    ::ndk::ScopedAStatus setAllowedNetworkTypesBitmap(int32_t serial,
+                                                      int32_t networkTypeBitmap) override;
     ::ndk::ScopedAStatus setBandMode(
             int32_t serial, ::aidl::android::hardware::radio::network::RadioBandMode mode) override;
     ::ndk::ScopedAStatus setBarringPassword(int32_t serial, const std::string& facility,
@@ -51,9 +52,7 @@
             int32_t serial,
             ::aidl::android::hardware::radio::network::CdmaRoamingType type) override;
     ::ndk::ScopedAStatus setCellInfoListRate(int32_t serial, int32_t rate) override;
-    ::ndk::ScopedAStatus setIndicationFilter(
-            int32_t serial,
-            ::aidl::android::hardware::radio::network::IndicationFilter indicationFilter) override;
+    ::ndk::ScopedAStatus setIndicationFilter(int32_t serial, int32_t indicationFilter) override;
     ::ndk::ScopedAStatus setLinkCapacityReportingCriteria(
             int32_t serial, int32_t hysteresisMs, int32_t hysteresisDlKbps,
             int32_t hysteresisUlKbps, const std::vector<int32_t>& thresholdsDownlinkKbps,
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioResponse.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioResponse.h
index 5db963f..1f82dd1 100644
--- a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioResponse.h
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioResponse.h
@@ -15,6 +15,9 @@
  */
 #pragma once
 
+#include "DriverContext.h"
+#include "GuaranteedCallback.h"
+
 #include <aidl/android/hardware/radio/data/IRadioDataResponse.h>
 #include <aidl/android/hardware/radio/messaging/IRadioMessagingResponse.h>
 #include <aidl/android/hardware/radio/modem/IRadioModemResponse.h>
@@ -26,13 +29,26 @@
 namespace android::hardware::radio::compat {
 
 class RadioResponse : public V1_6::IRadioResponse {
-    std::shared_ptr<::aidl::android::hardware::radio::data::IRadioDataResponse> mDataCb;
-    std::shared_ptr<::aidl::android::hardware::radio::messaging::IRadioMessagingResponse>
+    std::shared_ptr<DriverContext> mContext;
+
+    GuaranteedCallback<::aidl::android::hardware::radio::data::IRadioDataResponse,
+                       ::aidl::android::hardware::radio::data::IRadioDataResponseDefault>
+            mDataCb;
+    GuaranteedCallback<::aidl::android::hardware::radio::messaging::IRadioMessagingResponse,
+                       ::aidl::android::hardware::radio::messaging::IRadioMessagingResponseDefault>
             mMessagingCb;
-    std::shared_ptr<::aidl::android::hardware::radio::modem::IRadioModemResponse> mModemCb;
-    std::shared_ptr<::aidl::android::hardware::radio::network::IRadioNetworkResponse> mNetworkCb;
-    std::shared_ptr<::aidl::android::hardware::radio::sim::IRadioSimResponse> mSimCb;
-    std::shared_ptr<::aidl::android::hardware::radio::voice::IRadioVoiceResponse> mVoiceCb;
+    GuaranteedCallback<::aidl::android::hardware::radio::modem::IRadioModemResponse,
+                       ::aidl::android::hardware::radio::modem::IRadioModemResponseDefault>
+            mModemCb;
+    GuaranteedCallback<::aidl::android::hardware::radio::network::IRadioNetworkResponse,
+                       ::aidl::android::hardware::radio::network::IRadioNetworkResponseDefault>
+            mNetworkCb;
+    GuaranteedCallback<::aidl::android::hardware::radio::sim::IRadioSimResponse,
+                       ::aidl::android::hardware::radio::sim::IRadioSimResponseDefault>
+            mSimCb;
+    GuaranteedCallback<::aidl::android::hardware::radio::voice::IRadioVoiceResponse,
+                       ::aidl::android::hardware::radio::voice::IRadioVoiceResponseDefault>
+            mVoiceCb;
 
     // IRadioResponse @ 1.0
     Return<void> getIccCardStatusResponse(const V1_0::RadioResponseInfo& info,
@@ -409,6 +425,8 @@
                                                    int32_t updatedRecordIndex) override;
 
   public:
+    RadioResponse(std::shared_ptr<DriverContext> context);
+
     void setResponseFunction(
             std::shared_ptr<::aidl::android::hardware::radio::data::IRadioDataResponse> dataCb);
     void setResponseFunction(
@@ -422,6 +440,14 @@
             std::shared_ptr<::aidl::android::hardware::radio::sim::IRadioSimResponse> simCb);
     void setResponseFunction(
             std::shared_ptr<::aidl::android::hardware::radio::voice::IRadioVoiceResponse> voiceCb);
+
+    std::shared_ptr<::aidl::android::hardware::radio::data::IRadioDataResponse> dataCb();
+    std::shared_ptr<::aidl::android::hardware::radio::messaging::IRadioMessagingResponse>
+    messagingCb();
+    std::shared_ptr<::aidl::android::hardware::radio::modem::IRadioModemResponse> modemCb();
+    std::shared_ptr<::aidl::android::hardware::radio::network::IRadioNetworkResponse> networkCb();
+    std::shared_ptr<::aidl::android::hardware::radio::sim::IRadioSimResponse> simCb();
+    std::shared_ptr<::aidl::android::hardware::radio::voice::IRadioVoiceResponse> voiceCb();
 };
 
 }  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioSim.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioSim.h
index a6b77fd..84bb68b 100644
--- a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioSim.h
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioSim.h
@@ -22,6 +22,8 @@
 namespace android::hardware::radio::compat {
 
 class RadioSim : public RadioCompatBase, public aidl::android::hardware::radio::sim::BnRadioSim {
+    std::shared_ptr<::aidl::android::hardware::radio::sim::IRadioSimResponse> respond();
+
     ::ndk::ScopedAStatus areUiccApplicationsEnabled(int32_t serial) override;
     ::ndk::ScopedAStatus changeIccPin2ForApp(int32_t serial, const std::string& oldPin2,
                                              const std::string& newPin2,
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioVoice.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioVoice.h
index 5bf93e0..a0e1e82 100644
--- a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioVoice.h
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioVoice.h
@@ -23,14 +23,15 @@
 
 class RadioVoice : public RadioCompatBase,
                    public aidl::android::hardware::radio::voice::BnRadioVoice {
+    std::shared_ptr<::aidl::android::hardware::radio::voice::IRadioVoiceResponse> respond();
+
     ::ndk::ScopedAStatus acceptCall(int32_t serial) override;
     ::ndk::ScopedAStatus conference(int32_t serial) override;
     ::ndk::ScopedAStatus dial(
             int32_t serial, const ::aidl::android::hardware::radio::voice::Dial& dialInfo) override;
     ::ndk::ScopedAStatus emergencyDial(
             int32_t serial, const ::aidl::android::hardware::radio::voice::Dial& dialInfo,
-            ::aidl::android::hardware::radio::voice::EmergencyServiceCategory categories,
-            const std::vector<std::string>& urns,
+            int32_t categories, const std::vector<std::string>& urns,
             ::aidl::android::hardware::radio::voice::EmergencyCallRouting routing,
             bool hasKnownUserIntentEmergency, bool isTesting) override;
     ::ndk::ScopedAStatus exitEmergencyCallbackMode(int32_t serial) override;
diff --git a/radio/aidl/compat/libradiocompat/messaging/RadioIndication-messaging.cpp b/radio/aidl/compat/libradiocompat/messaging/RadioIndication-messaging.cpp
index c7342b1..e5c33b3 100644
--- a/radio/aidl/compat/libradiocompat/messaging/RadioIndication-messaging.cpp
+++ b/radio/aidl/compat/libradiocompat/messaging/RadioIndication-messaging.cpp
@@ -27,67 +27,62 @@
 namespace aidl = ::aidl::android::hardware::radio::messaging;
 
 void RadioIndication::setResponseFunction(std::shared_ptr<aidl::IRadioMessagingIndication> rmiCb) {
-    CHECK(rmiCb);
     mMessagingCb = rmiCb;
 }
 
+std::shared_ptr<aidl::IRadioMessagingIndication> RadioIndication::messagingCb() {
+    return mMessagingCb.get();
+}
+
 Return<void> RadioIndication::cdmaNewSms(V1_0::RadioIndicationType type,
                                          const V1_0::CdmaSmsMessage& msg) {
     LOG_CALL << type;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->cdmaNewSms(toAidl(type), toAidl(msg));
+    messagingCb()->cdmaNewSms(toAidl(type), toAidl(msg));
     return {};
 }
 
 Return<void> RadioIndication::cdmaRuimSmsStorageFull(V1_0::RadioIndicationType type) {
     LOG_CALL << type;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->cdmaRuimSmsStorageFull(toAidl(type));
+    messagingCb()->cdmaRuimSmsStorageFull(toAidl(type));
     return {};
 }
 
 Return<void> RadioIndication::newBroadcastSms(V1_0::RadioIndicationType type,
                                               const hidl_vec<uint8_t>& data) {
     LOG_CALL << type;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->newBroadcastSms(toAidl(type), data);
+    messagingCb()->newBroadcastSms(toAidl(type), data);
     return {};
 }
 
 Return<void> RadioIndication::newSms(V1_0::RadioIndicationType type, const hidl_vec<uint8_t>& pdu) {
     LOG_CALL << type;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->newSms(toAidl(type), pdu);
+    messagingCb()->newSms(toAidl(type), pdu);
     return {};
 }
 
 Return<void> RadioIndication::newSmsOnSim(V1_0::RadioIndicationType type, int32_t recordNumber) {
     LOG_CALL << type;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->newSmsOnSim(toAidl(type), recordNumber);
+    messagingCb()->newSmsOnSim(toAidl(type), recordNumber);
     return {};
 }
 
 Return<void> RadioIndication::newSmsStatusReport(V1_0::RadioIndicationType type,
                                                  const hidl_vec<uint8_t>& pdu) {
     LOG_CALL << type;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->newSmsStatusReport(toAidl(type), pdu);
+    messagingCb()->newSmsStatusReport(toAidl(type), pdu);
     return {};
 }
 
 Return<void> RadioIndication::onUssd(V1_0::RadioIndicationType type, V1_0::UssdModeType modeType,
                                      const hidl_string& msg) {
     LOG_CALL << type;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->onUssd(toAidl(type), aidl::UssdModeType(modeType), msg);
+    messagingCb()->onUssd(toAidl(type), aidl::UssdModeType(modeType), msg);
     return {};
 }
 
 Return<void> RadioIndication::simSmsStorageFull(V1_0::RadioIndicationType type) {
     LOG_CALL << type;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->simSmsStorageFull(toAidl(type));
+    messagingCb()->simSmsStorageFull(toAidl(type));
     return {};
 }
 
diff --git a/radio/aidl/compat/libradiocompat/messaging/RadioMessaging.cpp b/radio/aidl/compat/libradiocompat/messaging/RadioMessaging.cpp
index c1a82b5..4d94e17 100644
--- a/radio/aidl/compat/libradiocompat/messaging/RadioMessaging.cpp
+++ b/radio/aidl/compat/libradiocompat/messaging/RadioMessaging.cpp
@@ -29,6 +29,10 @@
 namespace aidl = ::aidl::android::hardware::radio::messaging;
 constexpr auto ok = &ScopedAStatus::ok;
 
+std::shared_ptr<aidl::IRadioMessagingResponse> RadioMessaging::respond() {
+    return mCallbackManager->response().messagingCb();
+}
+
 ScopedAStatus RadioMessaging::acknowledgeIncomingGsmSmsWithPdu(  //
         int32_t serial, bool success, const std::string& ackPdu) {
     LOG_CALL << serial << ' ' << success << ' ' << ackPdu;
@@ -100,13 +104,21 @@
 
 ScopedAStatus RadioMessaging::sendCdmaSms(int32_t serial, const aidl::CdmaSmsMessage& sms) {
     LOG_CALL << serial;
-    mHal1_5->sendCdmaSms(serial, toHidl(sms));
+    if (mHal1_6) {
+        mHal1_6->sendCdmaSms_1_6(serial, toHidl(sms));
+    } else {
+        mHal1_5->sendCdmaSms(serial, toHidl(sms));
+    }
     return ok();
 }
 
 ScopedAStatus RadioMessaging::sendCdmaSmsExpectMore(int32_t serial, const aidl::CdmaSmsMessage& m) {
     LOG_CALL << serial;
-    mHal1_5->sendCdmaSmsExpectMore(serial, toHidl(m));
+    if (mHal1_6) {
+        mHal1_6->sendCdmaSmsExpectMore_1_6(serial, toHidl(m));
+    } else {
+        mHal1_5->sendCdmaSmsExpectMore(serial, toHidl(m));
+    }
     return ok();
 }
 
@@ -118,13 +130,21 @@
 
 ScopedAStatus RadioMessaging::sendSms(int32_t serial, const aidl::GsmSmsMessage& message) {
     LOG_CALL << serial;
-    mHal1_5->sendSms(serial, toHidl(message));
+    if (mHal1_6) {
+        mHal1_6->sendSms_1_6(serial, toHidl(message));
+    } else {
+        mHal1_5->sendSms(serial, toHidl(message));
+    }
     return ok();
 }
 
 ScopedAStatus RadioMessaging::sendSmsExpectMore(int32_t serial, const aidl::GsmSmsMessage& msg) {
     LOG_CALL << serial;
-    mHal1_5->sendSMSExpectMore(serial, toHidl(msg));
+    if (mHal1_6) {
+        mHal1_6->sendSmsExpectMore_1_6(serial, toHidl(msg));
+    } else {
+        mHal1_5->sendSMSExpectMore(serial, toHidl(msg));
+    }
     return ok();
 }
 
@@ -161,16 +181,10 @@
 }
 
 ScopedAStatus RadioMessaging::setResponseFunctions(
-        const std::shared_ptr<aidl::IRadioMessagingResponse>& messagingResponse,
-        const std::shared_ptr<aidl::IRadioMessagingIndication>& messagingIndication) {
-    LOG_CALL << messagingResponse << ' ' << messagingIndication;
-
-    CHECK(messagingResponse);
-    CHECK(messagingIndication);
-
-    mRadioResponse->setResponseFunction(messagingResponse);
-    mRadioIndication->setResponseFunction(messagingIndication);
-
+        const std::shared_ptr<aidl::IRadioMessagingResponse>& response,
+        const std::shared_ptr<aidl::IRadioMessagingIndication>& indication) {
+    LOG_CALL << response << ' ' << indication;
+    mCallbackManager->setResponseFunctions(response, indication);
     return ok();
 }
 
diff --git a/radio/aidl/compat/libradiocompat/messaging/RadioResponse-messaging.cpp b/radio/aidl/compat/libradiocompat/messaging/RadioResponse-messaging.cpp
index 379e463..24ad3d7 100644
--- a/radio/aidl/compat/libradiocompat/messaging/RadioResponse-messaging.cpp
+++ b/radio/aidl/compat/libradiocompat/messaging/RadioResponse-messaging.cpp
@@ -29,52 +29,49 @@
 namespace aidl = ::aidl::android::hardware::radio::messaging;
 
 void RadioResponse::setResponseFunction(std::shared_ptr<aidl::IRadioMessagingResponse> rmrCb) {
-    CHECK(rmrCb);
     mMessagingCb = rmrCb;
 }
 
+std::shared_ptr<aidl::IRadioMessagingResponse> RadioResponse::messagingCb() {
+    return mMessagingCb.get();
+}
+
 Return<void> RadioResponse::acknowledgeIncomingGsmSmsWithPduResponse(
         const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->acknowledgeIncomingGsmSmsWithPduResponse(toAidl(info));
+    messagingCb()->acknowledgeIncomingGsmSmsWithPduResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::acknowledgeLastIncomingCdmaSmsResponse(
         const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->acknowledgeLastIncomingCdmaSmsResponse(toAidl(info));
+    messagingCb()->acknowledgeLastIncomingCdmaSmsResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::acknowledgeLastIncomingGsmSmsResponse(
         const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->acknowledgeLastIncomingGsmSmsResponse(toAidl(info));
+    messagingCb()->acknowledgeLastIncomingGsmSmsResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::cancelPendingUssdResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->cancelPendingUssdResponse(toAidl(info));
+    messagingCb()->cancelPendingUssdResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::deleteSmsOnRuimResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->deleteSmsOnRuimResponse(toAidl(info));
+    messagingCb()->deleteSmsOnRuimResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::deleteSmsOnSimResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->deleteSmsOnSimResponse(toAidl(info));
+    messagingCb()->deleteSmsOnSimResponse(toAidl(info));
     return {};
 }
 
@@ -82,162 +79,141 @@
         const V1_0::RadioResponseInfo& info,
         const hidl_vec<V1_0::CdmaBroadcastSmsConfigInfo>& configs) {
     LOG_CALL << info.serial;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->getCdmaBroadcastConfigResponse(toAidl(info), toAidl(configs));
+    messagingCb()->getCdmaBroadcastConfigResponse(toAidl(info), toAidl(configs));
     return {};
 }
 
 Return<void> RadioResponse::getGsmBroadcastConfigResponse(
         const V1_0::RadioResponseInfo& info, const hidl_vec<V1_0::GsmBroadcastSmsConfigInfo>& cfg) {
     LOG_CALL << info.serial;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->getGsmBroadcastConfigResponse(toAidl(info), toAidl(cfg));
+    messagingCb()->getGsmBroadcastConfigResponse(toAidl(info), toAidl(cfg));
     return {};
 }
 
 Return<void> RadioResponse::getSmscAddressResponse(const V1_0::RadioResponseInfo& info,
                                                    const hidl_string& smsc) {
     LOG_CALL << info.serial;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->getSmscAddressResponse(toAidl(info), smsc);
+    messagingCb()->getSmscAddressResponse(toAidl(info), smsc);
     return {};
 }
 
 Return<void> RadioResponse::reportSmsMemoryStatusResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->reportSmsMemoryStatusResponse(toAidl(info));
+    messagingCb()->reportSmsMemoryStatusResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::sendCdmaSmsExpectMoreResponse(const V1_0::RadioResponseInfo& info,
                                                           const V1_0::SendSmsResult& sms) {
     LOG_CALL << info.serial;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->sendCdmaSmsExpectMoreResponse(toAidl(info), toAidl(sms));
+    messagingCb()->sendCdmaSmsExpectMoreResponse(toAidl(info), toAidl(sms));
     return {};
 }
 
 Return<void> RadioResponse::sendCdmaSmsExpectMoreResponse_1_6(const V1_6::RadioResponseInfo& info,
                                                               const V1_0::SendSmsResult& sms) {
     LOG_CALL << info.serial;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->sendCdmaSmsExpectMoreResponse(toAidl(info), toAidl(sms));
+    messagingCb()->sendCdmaSmsExpectMoreResponse(toAidl(info), toAidl(sms));
     return {};
 }
 
 Return<void> RadioResponse::sendCdmaSmsResponse(const V1_0::RadioResponseInfo& info,
                                                 const V1_0::SendSmsResult& sms) {
     LOG_CALL << info.serial;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->sendCdmaSmsResponse(toAidl(info), toAidl(sms));
+    messagingCb()->sendCdmaSmsResponse(toAidl(info), toAidl(sms));
     return {};
 }
 
 Return<void> RadioResponse::sendCdmaSmsResponse_1_6(const V1_6::RadioResponseInfo& info,
                                                     const V1_0::SendSmsResult& sms) {
     LOG_CALL << info.serial;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->sendCdmaSmsResponse(toAidl(info), toAidl(sms));
+    messagingCb()->sendCdmaSmsResponse(toAidl(info), toAidl(sms));
     return {};
 }
 
 Return<void> RadioResponse::sendImsSmsResponse(const V1_0::RadioResponseInfo& info,
                                                const V1_0::SendSmsResult& sms) {
     LOG_CALL << info.serial;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->sendImsSmsResponse(toAidl(info), toAidl(sms));
+    messagingCb()->sendImsSmsResponse(toAidl(info), toAidl(sms));
     return {};
 }
 
 Return<void> RadioResponse::sendSMSExpectMoreResponse(const V1_0::RadioResponseInfo& info,
                                                       const V1_0::SendSmsResult& sms) {
     LOG_CALL << info.serial;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->sendSmsExpectMoreResponse(toAidl(info), toAidl(sms));
+    messagingCb()->sendSmsExpectMoreResponse(toAidl(info), toAidl(sms));
     return {};
 }
 
 Return<void> RadioResponse::sendSmsExpectMoreResponse_1_6(const V1_6::RadioResponseInfo& info,
                                                           const V1_0::SendSmsResult& sms) {
     LOG_CALL << info.serial;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->sendSmsExpectMoreResponse(toAidl(info), toAidl(sms));
+    messagingCb()->sendSmsExpectMoreResponse(toAidl(info), toAidl(sms));
     return {};
 }
 
 Return<void> RadioResponse::sendSmsResponse(const V1_0::RadioResponseInfo& info,
                                             const V1_0::SendSmsResult& sms) {
     LOG_CALL << info.serial;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->sendSmsResponse(toAidl(info), toAidl(sms));
+    messagingCb()->sendSmsResponse(toAidl(info), toAidl(sms));
     return {};
 }
 
 Return<void> RadioResponse::sendSmsResponse_1_6(const V1_6::RadioResponseInfo& info,
                                                 const V1_0::SendSmsResult& sms) {
     LOG_CALL << info.serial;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->sendSmsResponse(toAidl(info), toAidl(sms));
+    messagingCb()->sendSmsResponse(toAidl(info), toAidl(sms));
     return {};
 }
 
 Return<void> RadioResponse::sendUssdResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->sendUssdResponse(toAidl(info));
+    messagingCb()->sendUssdResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setCdmaBroadcastActivationResponse(
         const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->setCdmaBroadcastActivationResponse(toAidl(info));
+    messagingCb()->setCdmaBroadcastActivationResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setCdmaBroadcastConfigResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->setCdmaBroadcastConfigResponse(toAidl(info));
+    messagingCb()->setCdmaBroadcastConfigResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setGsmBroadcastActivationResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->setGsmBroadcastActivationResponse(toAidl(info));
+    messagingCb()->setGsmBroadcastActivationResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setGsmBroadcastConfigResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->setGsmBroadcastConfigResponse(toAidl(info));
+    messagingCb()->setGsmBroadcastConfigResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setSmscAddressResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->setSmscAddressResponse(toAidl(info));
+    messagingCb()->setSmscAddressResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::writeSmsToRuimResponse(const V1_0::RadioResponseInfo& info,
                                                    uint32_t index) {
     LOG_CALL << info.serial << ' ' << index;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->writeSmsToRuimResponse(toAidl(info), index);
+    messagingCb()->writeSmsToRuimResponse(toAidl(info), index);
     return {};
 }
 
 Return<void> RadioResponse::writeSmsToSimResponse(const V1_0::RadioResponseInfo& info,
                                                   int32_t index) {
     LOG_CALL << info.serial << ' ' << index;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->writeSmsToSimResponse(toAidl(info), index);
+    messagingCb()->writeSmsToSimResponse(toAidl(info), index);
     return {};
 }
 
diff --git a/radio/aidl/compat/libradiocompat/modem/RadioIndication-modem.cpp b/radio/aidl/compat/libradiocompat/modem/RadioIndication-modem.cpp
index 8fc4da6..851c93b 100644
--- a/radio/aidl/compat/libradiocompat/modem/RadioIndication-modem.cpp
+++ b/radio/aidl/compat/libradiocompat/modem/RadioIndication-modem.cpp
@@ -29,44 +29,42 @@
 namespace aidl = ::aidl::android::hardware::radio::modem;
 
 void RadioIndication::setResponseFunction(std::shared_ptr<aidl::IRadioModemIndication> modemCb) {
-    CHECK(modemCb);
     mModemCb = modemCb;
 }
 
+std::shared_ptr<aidl::IRadioModemIndication> RadioIndication::modemCb() {
+    return mModemCb.get();
+}
+
 Return<void> RadioIndication::hardwareConfigChanged(V1_0::RadioIndicationType type,
                                                     const hidl_vec<V1_0::HardwareConfig>& configs) {
     LOG_CALL << type;
-    CHECK_CB(mModemCb);
-    mModemCb->hardwareConfigChanged(toAidl(type), toAidl(configs));
+    modemCb()->hardwareConfigChanged(toAidl(type), toAidl(configs));
     return {};
 }
 
 Return<void> RadioIndication::modemReset(V1_0::RadioIndicationType type, const hidl_string& reasn) {
     LOG_CALL << type;
-    CHECK_CB(mModemCb);
-    mModemCb->modemReset(toAidl(type), reasn);
+    modemCb()->modemReset(toAidl(type), reasn);
     return {};
 }
 
 Return<void> RadioIndication::radioCapabilityIndication(V1_0::RadioIndicationType type,
                                                         const V1_0::RadioCapability& rc) {
     LOG_CALL << type;
-    CHECK_CB(mModemCb);
-    mModemCb->radioCapabilityIndication(toAidl(type), toAidl(rc));
+    modemCb()->radioCapabilityIndication(toAidl(type), toAidl(rc));
     return {};
 }
 
 Return<void> RadioIndication::radioStateChanged(V1_0::RadioIndicationType t, V1_0::RadioState st) {
     LOG_CALL << t;
-    CHECK_CB(mModemCb);
-    mModemCb->radioStateChanged(toAidl(t), aidl::RadioState(st));
+    modemCb()->radioStateChanged(toAidl(t), aidl::RadioState(st));
     return {};
 }
 
 Return<void> RadioIndication::rilConnected(V1_0::RadioIndicationType type) {
     LOG_CALL << type;
-    CHECK_CB(mModemCb);
-    mModemCb->rilConnected(toAidl(type));
+    modemCb()->rilConnected(toAidl(type));
     return {};
 }
 
diff --git a/radio/aidl/compat/libradiocompat/modem/RadioModem.cpp b/radio/aidl/compat/libradiocompat/modem/RadioModem.cpp
index 660ae9f..d28b940 100644
--- a/radio/aidl/compat/libradiocompat/modem/RadioModem.cpp
+++ b/radio/aidl/compat/libradiocompat/modem/RadioModem.cpp
@@ -27,6 +27,10 @@
 namespace aidl = ::aidl::android::hardware::radio::modem;
 constexpr auto ok = &ScopedAStatus::ok;
 
+std::shared_ptr<aidl::IRadioModemResponse> RadioModem::respond() {
+    return mCallbackManager->response().modemCb();
+}
+
 ScopedAStatus RadioModem::enableModem(int32_t serial, bool on) {
     LOG_CALL << serial;
     mHal1_5->enableModem(serial, on);
@@ -129,16 +133,10 @@
 }
 
 ScopedAStatus RadioModem::setResponseFunctions(
-        const std::shared_ptr<aidl::IRadioModemResponse>& modemResponse,
-        const std::shared_ptr<aidl::IRadioModemIndication>& modemIndication) {
-    LOG_CALL << modemResponse << ' ' << modemIndication;
-
-    CHECK(modemResponse);
-    CHECK(modemIndication);
-
-    mRadioResponse->setResponseFunction(modemResponse);
-    mRadioIndication->setResponseFunction(modemIndication);
-
+        const std::shared_ptr<aidl::IRadioModemResponse>& response,
+        const std::shared_ptr<aidl::IRadioModemIndication>& indication) {
+    LOG_CALL << response << ' ' << indication;
+    mCallbackManager->setResponseFunctions(response, indication);
     return ok();
 }
 
diff --git a/radio/aidl/compat/libradiocompat/modem/RadioResponse-modem.cpp b/radio/aidl/compat/libradiocompat/modem/RadioResponse-modem.cpp
index 300627c..6e1a962 100644
--- a/radio/aidl/compat/libradiocompat/modem/RadioResponse-modem.cpp
+++ b/radio/aidl/compat/libradiocompat/modem/RadioResponse-modem.cpp
@@ -29,22 +29,23 @@
 namespace aidl = ::aidl::android::hardware::radio::modem;
 
 void RadioResponse::setResponseFunction(std::shared_ptr<aidl::IRadioModemResponse> modemCb) {
-    CHECK(modemCb);
     mModemCb = modemCb;
 }
 
+std::shared_ptr<aidl::IRadioModemResponse> RadioResponse::modemCb() {
+    return mModemCb.get();
+}
+
 Return<void> RadioResponse::enableModemResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mModemCb);
-    mModemCb->enableModemResponse(toAidl(info));
+    modemCb()->enableModemResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::getBasebandVersionResponse(const V1_0::RadioResponseInfo& info,
                                                        const hidl_string& version) {
     LOG_CALL << info.serial;
-    CHECK_CB(mModemCb);
-    mModemCb->getBasebandVersionResponse(toAidl(info), version);
+    modemCb()->getBasebandVersionResponse(toAidl(info), version);
     return {};
 }
 
@@ -52,112 +53,97 @@
         const V1_0::RadioResponseInfo& info, const hidl_string& imei, const hidl_string& imeisv,
         const hidl_string& esn, const hidl_string& meid) {
     LOG_CALL << info.serial;
-    CHECK_CB(mModemCb);
-    mModemCb->getDeviceIdentityResponse(toAidl(info), imei, imeisv, esn, meid);
+    modemCb()->getDeviceIdentityResponse(toAidl(info), imei, imeisv, esn, meid);
     return {};
 }
 
 Return<void> RadioResponse::getHardwareConfigResponse(
         const V1_0::RadioResponseInfo& info, const hidl_vec<V1_0::HardwareConfig>& config) {
     LOG_CALL << info.serial;
-    CHECK_CB(mModemCb);
-    mModemCb->getHardwareConfigResponse(toAidl(info), toAidl(config));
+    modemCb()->getHardwareConfigResponse(toAidl(info), toAidl(config));
     return {};
 }
 
 Return<void> RadioResponse::getModemActivityInfoResponse(
         const V1_0::RadioResponseInfo& info, const V1_0::ActivityStatsInfo& activityInfo) {
     LOG_CALL << info.serial;
-    CHECK_CB(mModemCb);
-    mModemCb->getModemActivityInfoResponse(toAidl(info), toAidl(activityInfo));
+    modemCb()->getModemActivityInfoResponse(toAidl(info), toAidl(activityInfo));
     return {};
 }
 
 Return<void> RadioResponse::getModemStackStatusResponse(const V1_0::RadioResponseInfo& info,
                                                         bool isEnabled) {
     LOG_CALL << info.serial;
-    CHECK_CB(mModemCb);
-    mModemCb->getModemStackStatusResponse(toAidl(info), isEnabled);
+    modemCb()->getModemStackStatusResponse(toAidl(info), isEnabled);
     return {};
 }
 
 Return<void> RadioResponse::getRadioCapabilityResponse(const V1_0::RadioResponseInfo& info,
                                                        const V1_0::RadioCapability& rc) {
     LOG_CALL << info.serial;
-    CHECK_CB(mModemCb);
-    mModemCb->getRadioCapabilityResponse(toAidl(info), toAidl(rc));
+    modemCb()->getRadioCapabilityResponse(toAidl(info), toAidl(rc));
     return {};
 }
 
 Return<void> RadioResponse::nvReadItemResponse(const V1_0::RadioResponseInfo& info,
                                                const hidl_string& result) {
     LOG_CALL << info.serial;
-    CHECK_CB(mModemCb);
-    mModemCb->nvReadItemResponse(toAidl(info), result);
+    modemCb()->nvReadItemResponse(toAidl(info), result);
     return {};
 }
 
 Return<void> RadioResponse::nvResetConfigResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mModemCb);
-    mModemCb->nvResetConfigResponse(toAidl(info));
+    modemCb()->nvResetConfigResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::nvWriteCdmaPrlResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mModemCb);
-    mModemCb->nvWriteCdmaPrlResponse(toAidl(info));
+    modemCb()->nvWriteCdmaPrlResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::nvWriteItemResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mModemCb);
-    mModemCb->nvWriteItemResponse(toAidl(info));
+    modemCb()->nvWriteItemResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::requestShutdownResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mModemCb);
-    mModemCb->requestShutdownResponse(toAidl(info));
+    modemCb()->requestShutdownResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::sendDeviceStateResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mModemCb);
-    mModemCb->sendDeviceStateResponse(toAidl(info));
+    modemCb()->sendDeviceStateResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setRadioCapabilityResponse(const V1_0::RadioResponseInfo& info,
                                                        const V1_0::RadioCapability& rc) {
     LOG_CALL << info.serial;
-    CHECK_CB(mModemCb);
-    mModemCb->setRadioCapabilityResponse(toAidl(info), toAidl(rc));
+    modemCb()->setRadioCapabilityResponse(toAidl(info), toAidl(rc));
     return {};
 }
 
 Return<void> RadioResponse::setRadioPowerResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mModemCb);
-    mModemCb->setRadioPowerResponse(toAidl(info));
+    modemCb()->setRadioPowerResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setRadioPowerResponse_1_5(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mModemCb);
-    mModemCb->setRadioPowerResponse(toAidl(info));
+    modemCb()->setRadioPowerResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setRadioPowerResponse_1_6(const V1_6::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mModemCb);
-    mModemCb->setRadioPowerResponse(toAidl(info));
+    modemCb()->setRadioPowerResponse(toAidl(info));
     return {};
 }
 
diff --git a/radio/aidl/compat/libradiocompat/modem/structs.cpp b/radio/aidl/compat/libradiocompat/modem/structs.cpp
index 53d5753..69e651b 100644
--- a/radio/aidl/compat/libradiocompat/modem/structs.cpp
+++ b/radio/aidl/compat/libradiocompat/modem/structs.cpp
@@ -25,7 +25,6 @@
 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;
 
@@ -40,7 +39,7 @@
     return {
             .session = capa.session,
             .phase = static_cast<int32_t>(capa.phase),
-            .raf = RadioAccessFamily(capa.raf),
+            .raf = static_cast<int32_t>(capa.raf),
             .logicalModemUuid = capa.logicalModemUuid,
             .status = static_cast<int32_t>(capa.status),
     };
diff --git a/radio/aidl/compat/libradiocompat/network/RadioIndication-network.cpp b/radio/aidl/compat/libradiocompat/network/RadioIndication-network.cpp
index 899b133..4eb99f7 100644
--- a/radio/aidl/compat/libradiocompat/network/RadioIndication-network.cpp
+++ b/radio/aidl/compat/libradiocompat/network/RadioIndication-network.cpp
@@ -30,23 +30,24 @@
 namespace aidl = ::aidl::android::hardware::radio::network;
 
 void RadioIndication::setResponseFunction(std::shared_ptr<aidl::IRadioNetworkIndication> netCb) {
-    CHECK(netCb);
     mNetworkCb = netCb;
 }
 
+std::shared_ptr<aidl::IRadioNetworkIndication> RadioIndication::networkCb() {
+    return mNetworkCb.get();
+}
+
 Return<void> RadioIndication::barringInfoChanged(V1_0::RadioIndicationType type,
                                                  const V1_5::CellIdentity& cellIdentity,
                                                  const hidl_vec<V1_5::BarringInfo>& barringInfos) {
     LOG_CALL << type;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->barringInfoChanged(toAidl(type), toAidl(cellIdentity), toAidl(barringInfos));
+    networkCb()->barringInfoChanged(toAidl(type), toAidl(cellIdentity), toAidl(barringInfos));
     return {};
 }
 
 Return<void> RadioIndication::cdmaPrlChanged(V1_0::RadioIndicationType type, int32_t version) {
     LOG_CALL << type;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->cdmaPrlChanged(toAidl(type), version);
+    networkCb()->cdmaPrlChanged(toAidl(type), version);
     return {};
 }
 
@@ -74,32 +75,28 @@
 Return<void> RadioIndication::cellInfoList_1_5(V1_0::RadioIndicationType type,
                                                const hidl_vec<V1_5::CellInfo>& records) {
     LOG_CALL << type;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->cellInfoList(toAidl(type), toAidl(records));
+    networkCb()->cellInfoList(toAidl(type), toAidl(records));
     return {};
 }
 
 Return<void> RadioIndication::cellInfoList_1_6(V1_0::RadioIndicationType type,
                                                const hidl_vec<V1_6::CellInfo>& records) {
     LOG_CALL << type;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->cellInfoList(toAidl(type), toAidl(records));
+    networkCb()->cellInfoList(toAidl(type), toAidl(records));
     return {};
 }
 
 Return<void> RadioIndication::currentLinkCapacityEstimate(V1_0::RadioIndicationType type,
                                                           const V1_2::LinkCapacityEstimate& lce) {
     LOG_CALL << type;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->currentLinkCapacityEstimate(toAidl(type), toAidl(lce));
+    networkCb()->currentLinkCapacityEstimate(toAidl(type), toAidl(lce));
     return {};
 }
 
 Return<void> RadioIndication::currentLinkCapacityEstimate_1_6(
         V1_0::RadioIndicationType type, const V1_6::LinkCapacityEstimate& lce) {
     LOG_CALL << type;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->currentLinkCapacityEstimate(toAidl(type), toAidl(lce));
+    networkCb()->currentLinkCapacityEstimate(toAidl(type), toAidl(lce));
     return {};
 }
 
@@ -113,16 +110,14 @@
 Return<void> RadioIndication::currentPhysicalChannelConfigs_1_4(
         V1_0::RadioIndicationType type, const hidl_vec<V1_4::PhysicalChannelConfig>& configs) {
     LOG_CALL << type;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->currentPhysicalChannelConfigs(toAidl(type), toAidl(configs));
+    networkCb()->currentPhysicalChannelConfigs(toAidl(type), toAidl(configs));
     return {};
 }
 
 Return<void> RadioIndication::currentPhysicalChannelConfigs_1_6(
         V1_0::RadioIndicationType type, const hidl_vec<V1_6::PhysicalChannelConfig>& configs) {
     LOG_CALL << type;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->currentPhysicalChannelConfigs(toAidl(type), toAidl(configs));
+    networkCb()->currentPhysicalChannelConfigs(toAidl(type), toAidl(configs));
     return {};
 }
 
@@ -143,23 +138,20 @@
 Return<void> RadioIndication::currentSignalStrength_1_4(
         V1_0::RadioIndicationType type, const V1_4::SignalStrength& signalStrength) {
     LOG_CALL << type;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->currentSignalStrength(toAidl(type), toAidl(signalStrength));
+    networkCb()->currentSignalStrength(toAidl(type), toAidl(signalStrength));
     return {};
 }
 
 Return<void> RadioIndication::currentSignalStrength_1_6(
         V1_0::RadioIndicationType type, const V1_6::SignalStrength& signalStrength) {
     LOG_CALL << type;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->currentSignalStrength(toAidl(type), toAidl(signalStrength));
+    networkCb()->currentSignalStrength(toAidl(type), toAidl(signalStrength));
     return {};
 }
 
 Return<void> RadioIndication::imsNetworkStateChanged(V1_0::RadioIndicationType type) {
     LOG_CALL << type;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->imsNetworkStateChanged(toAidl(type));
+    networkCb()->imsNetworkStateChanged(toAidl(type));
     return {};
 }
 
@@ -187,31 +179,27 @@
 Return<void> RadioIndication::networkScanResult_1_5(V1_0::RadioIndicationType type,
                                                     const V1_5::NetworkScanResult& result) {
     LOG_CALL << type;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->networkScanResult(toAidl(type), toAidl(result));
+    networkCb()->networkScanResult(toAidl(type), toAidl(result));
     return {};
 }
 
 Return<void> RadioIndication::networkScanResult_1_6(V1_0::RadioIndicationType type,
                                                     const V1_6::NetworkScanResult& result) {
     LOG_CALL << type;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->networkScanResult(toAidl(type), toAidl(result));
+    networkCb()->networkScanResult(toAidl(type), toAidl(result));
     return {};
 }
 
 Return<void> RadioIndication::networkStateChanged(V1_0::RadioIndicationType type) {
     LOG_CALL << type;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->networkStateChanged(toAidl(type));
+    networkCb()->networkStateChanged(toAidl(type));
     return {};
 }
 
 Return<void> RadioIndication::nitzTimeReceived(V1_0::RadioIndicationType type,
                                                const hidl_string& nitzTime, uint64_t receivedTime) {
     LOG_CALL << type;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->nitzTimeReceived(toAidl(type), nitzTime, receivedTime, 0);
+    networkCb()->nitzTimeReceived(toAidl(type), nitzTime, receivedTime, 0);
     return {};
 }
 
@@ -220,33 +208,29 @@
         const hidl_string& chosenPlmn, hidl_bitfield<V1_5::Domain> domain, int32_t causeCode,
         int32_t additionalCauseCode) {
     LOG_CALL << type;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->registrationFailed(toAidl(type), toAidl(cellIdentity), chosenPlmn,
-                                   aidl::Domain(domain), causeCode, additionalCauseCode);
+    networkCb()->registrationFailed(toAidl(type), toAidl(cellIdentity), chosenPlmn, domain,
+                                    causeCode, additionalCauseCode);
     return {};
 }
 
 Return<void> RadioIndication::restrictedStateChanged(V1_0::RadioIndicationType type,
                                                      V1_0::PhoneRestrictedState state) {
     LOG_CALL << type;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->restrictedStateChanged(toAidl(type), aidl::PhoneRestrictedState(state));
+    networkCb()->restrictedStateChanged(toAidl(type), aidl::PhoneRestrictedState(state));
     return {};
 }
 
 Return<void> RadioIndication::suppSvcNotify(V1_0::RadioIndicationType type,
                                             const V1_0::SuppSvcNotification& suppSvc) {
     LOG_CALL << type;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->suppSvcNotify(toAidl(type), toAidl(suppSvc));
+    networkCb()->suppSvcNotify(toAidl(type), toAidl(suppSvc));
     return {};
 }
 
 Return<void> RadioIndication::voiceRadioTechChanged(V1_0::RadioIndicationType type,
                                                     V1_0::RadioTechnology rat) {
     LOG_CALL << type;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->voiceRadioTechChanged(toAidl(type), RadioTechnology(rat));
+    networkCb()->voiceRadioTechChanged(toAidl(type), RadioTechnology(rat));
     return {};
 }
 
diff --git a/radio/aidl/compat/libradiocompat/network/RadioNetwork.cpp b/radio/aidl/compat/libradiocompat/network/RadioNetwork.cpp
index 5fa1cf5..22b9ede 100644
--- a/radio/aidl/compat/libradiocompat/network/RadioNetwork.cpp
+++ b/radio/aidl/compat/libradiocompat/network/RadioNetwork.cpp
@@ -28,11 +28,14 @@
 namespace android::hardware::radio::compat {
 
 using ::aidl::android::hardware::radio::AccessNetwork;
-using ::aidl::android::hardware::radio::RadioAccessFamily;
 using ::ndk::ScopedAStatus;
 namespace aidl = ::aidl::android::hardware::radio::network;
 constexpr auto ok = &ScopedAStatus::ok;
 
+std::shared_ptr<aidl::IRadioNetworkResponse> RadioNetwork::respond() {
+    return mCallbackManager->response().networkCb();
+}
+
 ScopedAStatus RadioNetwork::getAllowedNetworkTypesBitmap(int32_t serial) {
     LOG_CALL << serial;
     if (mHal1_6) {
@@ -69,13 +72,21 @@
 
 ScopedAStatus RadioNetwork::getCellInfoList(int32_t serial) {
     LOG_CALL << serial;
-    mHal1_5->getCellInfoList(serial);
+    if (mHal1_6) {
+        mHal1_6->getCellInfoList_1_6(serial);
+    } else {
+        mHal1_5->getCellInfoList(serial);
+    }
     return ok();
 }
 
 ScopedAStatus RadioNetwork::getDataRegistrationState(int32_t serial) {
     LOG_CALL << serial;
-    mHal1_5->getDataRegistrationState(serial);
+    if (mHal1_6) {
+        mHal1_6->getDataRegistrationState_1_6(serial);
+    } else {
+        mHal1_5->getDataRegistrationState_1_5(serial);
+    }
     return ok();
 }
 
@@ -99,7 +110,11 @@
 
 ScopedAStatus RadioNetwork::getSignalStrength(int32_t serial) {
     LOG_CALL << serial;
-    mHal1_5->getSignalStrength(serial);
+    if (mHal1_6) {
+        mHal1_6->getSignalStrength_1_6(serial);
+    } else {
+        mHal1_5->getSignalStrength_1_4(serial);
+    }
     return ok();
 }
 
@@ -108,7 +123,7 @@
     if (mHal1_6) {
         mHal1_6->getSystemSelectionChannels(serial);
     } else {
-        respond().getSystemSelectionChannelsResponse(notSupported(serial), {});
+        respond()->getSystemSelectionChannelsResponse(notSupported(serial), {});
     }
     return ok();
 }
@@ -121,7 +136,11 @@
 
 ScopedAStatus RadioNetwork::getVoiceRegistrationState(int32_t serial) {
     LOG_CALL << serial;
-    mHal1_5->getVoiceRegistrationState(serial);
+    if (mHal1_6) {
+        mHal1_6->getVoiceRegistrationState_1_6(serial);
+    } else {
+        mHal1_5->getVoiceRegistrationState_1_5(serial);
+    }
     return ok();
 }
 
@@ -130,7 +149,7 @@
     if (mHal1_6) {
         mHal1_6->isNrDualConnectivityEnabled(serial);
     } else {
-        respond().isNrDualConnectivityEnabledResponse(notSupported(serial), false);
+        respond()->isNrDualConnectivityEnabledResponse(notSupported(serial), false);
     }
     return ok();
 }
@@ -141,7 +160,7 @@
     return ok();
 }
 
-ScopedAStatus RadioNetwork::setAllowedNetworkTypesBitmap(int32_t serial, RadioAccessFamily ntype) {
+ScopedAStatus RadioNetwork::setAllowedNetworkTypesBitmap(int32_t serial, int32_t ntype) {
     LOG_CALL << serial;
     const auto raf = toHidlBitfield<V1_4::RadioAccessFamily>(ntype);
     if (mHal1_6) {
@@ -177,9 +196,9 @@
     return ok();
 }
 
-ScopedAStatus RadioNetwork::setIndicationFilter(int32_t serial, aidl::IndicationFilter indFilter) {
+ScopedAStatus RadioNetwork::setIndicationFilter(int32_t serial, int32_t indFilter) {
     LOG_CALL << serial;
-    mHal1_5->setIndicationFilter(serial, toHidlBitfield<V1_0::IndicationFilter>(indFilter));
+    mHal1_5->setIndicationFilter_1_5(serial, toHidlBitfield<V1_5::IndicationFilter>(indFilter));
     return ok();
 }
 
@@ -188,9 +207,9 @@
         const std::vector<int32_t>& thrDownlinkKbps, const std::vector<int32_t>& thrUplinkKbps,
         AccessNetwork accessNetwork) {
     LOG_CALL << serial;
-    mHal1_5->setLinkCapacityReportingCriteria(  //
+    mHal1_5->setLinkCapacityReportingCriteria_1_5(  //
             serial, hysteresisMs, hysteresisDlKbps, hysteresisUlKbps, thrDownlinkKbps,
-            thrUplinkKbps, V1_2::AccessNetwork(accessNetwork));
+            thrUplinkKbps, V1_5::AccessNetwork(accessNetwork));
     return ok();
 }
 
@@ -219,29 +238,29 @@
     if (mHal1_6) {
         mHal1_6->setNrDualConnectivityState(serial, V1_6::NrDualConnectivityState(st));
     } else {
-        respond().setNrDualConnectivityStateResponse(notSupported(serial));
+        respond()->setNrDualConnectivityStateResponse(notSupported(serial));
     }
     return ok();
 }
 
 ScopedAStatus RadioNetwork::setResponseFunctions(
-        const std::shared_ptr<aidl::IRadioNetworkResponse>& networkResponse,
-        const std::shared_ptr<aidl::IRadioNetworkIndication>& networkIndication) {
-    LOG_CALL << networkResponse << ' ' << networkIndication;
-
-    CHECK(networkResponse);
-    CHECK(networkIndication);
-
-    mRadioResponse->setResponseFunction(networkResponse);
-    mRadioIndication->setResponseFunction(networkIndication);
-
+        const std::shared_ptr<aidl::IRadioNetworkResponse>& response,
+        const std::shared_ptr<aidl::IRadioNetworkIndication>& indication) {
+    LOG_CALL << response << ' ' << indication;
+    mCallbackManager->setResponseFunctions(response, indication);
     return ok();
 }
 
 ScopedAStatus RadioNetwork::setSignalStrengthReportingCriteria(
         int32_t serial, const std::vector<aidl::SignalThresholdInfo>& infos) {
     LOG_CALL << serial;
-    // TODO(b/203699028): how about other infos?
+    if (infos.size() == 0) {
+        LOG(ERROR) << "Threshold info array is empty - dropping setSignalStrengthReportingCriteria";
+        return ok();
+    }
+    if (infos.size() > 1) {
+        LOG(WARNING) << "Multi-element reporting criteria are not supported with HIDL HAL";
+    }
     mHal1_5->setSignalStrengthReportingCriteria_1_5(serial, toHidl(infos[0]),
                                                     V1_5::AccessNetwork(infos[0].ran));
     return ok();
@@ -278,18 +297,17 @@
     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;
+ScopedAStatus RadioNetwork::setUsageSetting(int32_t serial, aidl::UsageSetting) {
+    LOG_CALL << serial;
     LOG(ERROR) << "setUsageSetting is unsupported by HIDL HALs";
+    respond()->setUsageSettingResponse(notSupported(serial));
     return ok();
 }
 
-ScopedAStatus RadioNetwork::getUsageSetting(int32_t ser) {
-    LOG_CALL << ser;
+ScopedAStatus RadioNetwork::getUsageSetting(int32_t serial) {
+    LOG_CALL << serial;
     LOG(ERROR) << "getUsageSetting is unsupported by HIDL HALs";
+    respond()->getUsageSettingResponse(notSupported(serial), {});  // {} = neither voice nor data
     return ok();
 }
 
diff --git a/radio/aidl/compat/libradiocompat/network/RadioResponse-network.cpp b/radio/aidl/compat/libradiocompat/network/RadioResponse-network.cpp
index 81f7775..5a98eb2 100644
--- a/radio/aidl/compat/libradiocompat/network/RadioResponse-network.cpp
+++ b/radio/aidl/compat/libradiocompat/network/RadioResponse-network.cpp
@@ -27,32 +27,30 @@
 
 namespace android::hardware::radio::compat {
 
-using ::aidl::android::hardware::radio::RadioAccessFamily;
 using ::aidl::android::hardware::radio::RadioTechnology;
 using ::aidl::android::hardware::radio::RadioTechnologyFamily;
 namespace aidl = ::aidl::android::hardware::radio::network;
 
 void RadioResponse::setResponseFunction(std::shared_ptr<aidl::IRadioNetworkResponse> netCb) {
-    CHECK(netCb);
     mNetworkCb = netCb;
 }
 
+std::shared_ptr<aidl::IRadioNetworkResponse> RadioResponse::networkCb() {
+    return mNetworkCb.get();
+}
+
 Return<void> RadioResponse::getAllowedNetworkTypesBitmapResponse(
         const V1_6::RadioResponseInfo& info,
         hidl_bitfield<V1_4::RadioAccessFamily> networkTypeBitmap) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->getAllowedNetworkTypesBitmapResponse(toAidl(info),
-                                                     RadioAccessFamily(networkTypeBitmap));
+    networkCb()->getAllowedNetworkTypesBitmapResponse(toAidl(info), networkTypeBitmap);
     return {};
 }
 
 Return<void> RadioResponse::getPreferredNetworkTypeResponse(const V1_0::RadioResponseInfo& info,
                                                             V1_0::PreferredNetworkType nwType) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->getAllowedNetworkTypesBitmapResponse(  //
-            toAidl(info), RadioAccessFamily(getRafFromNetworkType(nwType)));
+    networkCb()->getAllowedNetworkTypesBitmapResponse(toAidl(info), getRafFromNetworkType(nwType));
     return {};
 }
 
@@ -66,16 +64,14 @@
 Return<void> RadioResponse::getAvailableBandModesResponse(
         const V1_0::RadioResponseInfo& info, const hidl_vec<V1_0::RadioBandMode>& bandModes) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->getAvailableBandModesResponse(toAidl(info), toAidl(bandModes));
+    networkCb()->getAvailableBandModesResponse(toAidl(info), toAidl(bandModes));
     return {};
 }
 
 Return<void> RadioResponse::getAvailableNetworksResponse(
         const V1_0::RadioResponseInfo& info, const hidl_vec<V1_0::OperatorInfo>& networkInfos) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->getAvailableNetworksResponse(toAidl(info), toAidl(networkInfos));
+    networkCb()->getAvailableNetworksResponse(toAidl(info), toAidl(networkInfos));
     return {};
 }
 
@@ -83,16 +79,14 @@
         const V1_0::RadioResponseInfo& info, const V1_5::CellIdentity& cellIdentity,
         const hidl_vec<V1_5::BarringInfo>& barringInfos) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->getBarringInfoResponse(toAidl(info), toAidl(cellIdentity), toAidl(barringInfos));
+    networkCb()->getBarringInfoResponse(toAidl(info), toAidl(cellIdentity), toAidl(barringInfos));
     return {};
 }
 
 Return<void> RadioResponse::getCdmaRoamingPreferenceResponse(const V1_0::RadioResponseInfo& info,
                                                              V1_0::CdmaRoamingType type) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->getCdmaRoamingPreferenceResponse(toAidl(info), aidl::CdmaRoamingType(type));
+    networkCb()->getCdmaRoamingPreferenceResponse(toAidl(info), aidl::CdmaRoamingType(type));
     return {};
 }
 
@@ -120,16 +114,14 @@
 Return<void> RadioResponse::getCellInfoListResponse_1_5(const V1_0::RadioResponseInfo& info,
                                                         const hidl_vec<V1_5::CellInfo>& cellInfo) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->getCellInfoListResponse(toAidl(info), toAidl(cellInfo));
+    networkCb()->getCellInfoListResponse(toAidl(info), toAidl(cellInfo));
     return {};
 }
 
 Return<void> RadioResponse::getCellInfoListResponse_1_6(const V1_6::RadioResponseInfo& info,
                                                         const hidl_vec<V1_6::CellInfo>& cellInfo) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->getCellInfoListResponse(toAidl(info), toAidl(cellInfo));
+    networkCb()->getCellInfoListResponse(toAidl(info), toAidl(cellInfo));
     return {};
 }
 
@@ -157,25 +149,22 @@
 Return<void> RadioResponse::getDataRegistrationStateResponse_1_5(
         const V1_0::RadioResponseInfo& info, const V1_5::RegStateResult& dataRegResponse) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->getDataRegistrationStateResponse(toAidl(info), toAidl(dataRegResponse));
+    networkCb()->getDataRegistrationStateResponse(toAidl(info), toAidl(dataRegResponse));
     return {};
 }
 
 Return<void> RadioResponse::getDataRegistrationStateResponse_1_6(
         const V1_6::RadioResponseInfo& info, const V1_6::RegStateResult& dataRegResponse) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->getDataRegistrationStateResponse(toAidl(info), toAidl(dataRegResponse));
+    networkCb()->getDataRegistrationStateResponse(toAidl(info), toAidl(dataRegResponse));
     return {};
 }
 
 Return<void> RadioResponse::getImsRegistrationStateResponse(  //
         const V1_0::RadioResponseInfo& info, bool isRegd, V1_0::RadioTechnologyFamily ratFamily) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->getImsRegistrationStateResponse(toAidl(info), isRegd,
-                                                RadioTechnologyFamily(ratFamily));
+    networkCb()->getImsRegistrationStateResponse(toAidl(info), isRegd,
+                                                 RadioTechnologyFamily(ratFamily));
     return {};
 }
 
@@ -189,8 +178,7 @@
 Return<void> RadioResponse::getNetworkSelectionModeResponse(const V1_0::RadioResponseInfo& info,
                                                             bool manual) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->getNetworkSelectionModeResponse(toAidl(info), manual);
+    networkCb()->getNetworkSelectionModeResponse(toAidl(info), manual);
     return {};
 }
 
@@ -198,8 +186,7 @@
         const V1_0::RadioResponseInfo& info, const hidl_string& longName,
         const hidl_string& shortName, const hidl_string& numeric) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->getOperatorResponse(toAidl(info), longName, shortName, numeric);
+    networkCb()->getOperatorResponse(toAidl(info), longName, shortName, numeric);
     return {};
 }
 
@@ -220,16 +207,14 @@
 Return<void> RadioResponse::getSignalStrengthResponse_1_4(
         const V1_0::RadioResponseInfo& info, const V1_4::SignalStrength& signalStrength) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->getSignalStrengthResponse(toAidl(info), toAidl(signalStrength));
+    networkCb()->getSignalStrengthResponse(toAidl(info), toAidl(signalStrength));
     return {};
 }
 
 Return<void> RadioResponse::getSignalStrengthResponse_1_6(
         const V1_6::RadioResponseInfo& info, const V1_6::SignalStrength& signalStrength) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->getSignalStrengthResponse(toAidl(info), toAidl(signalStrength));
+    networkCb()->getSignalStrengthResponse(toAidl(info), toAidl(signalStrength));
     return {};
 }
 
@@ -237,16 +222,14 @@
         const V1_6::RadioResponseInfo& info,
         const hidl_vec<V1_5::RadioAccessSpecifier>& specifiers) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->getSystemSelectionChannelsResponse(toAidl(info), toAidl(specifiers));
+    networkCb()->getSystemSelectionChannelsResponse(toAidl(info), toAidl(specifiers));
     return {};
 }
 
 Return<void> RadioResponse::getVoiceRadioTechnologyResponse(const V1_0::RadioResponseInfo& info,
                                                             V1_0::RadioTechnology rat) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->getVoiceRadioTechnologyResponse(toAidl(info), RadioTechnology(rat));
+    networkCb()->getVoiceRadioTechnologyResponse(toAidl(info), RadioTechnology(rat));
     return {};
 }
 
@@ -267,24 +250,21 @@
 Return<void> RadioResponse::getVoiceRegistrationStateResponse_1_5(
         const V1_0::RadioResponseInfo& info, const V1_5::RegStateResult& voiceRegResponse) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->getVoiceRegistrationStateResponse(toAidl(info), toAidl(voiceRegResponse));
+    networkCb()->getVoiceRegistrationStateResponse(toAidl(info), toAidl(voiceRegResponse));
     return {};
 }
 
 Return<void> RadioResponse::getVoiceRegistrationStateResponse_1_6(
         const V1_6::RadioResponseInfo& info, const V1_6::RegStateResult& voiceRegResponse) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->getVoiceRegistrationStateResponse(toAidl(info), toAidl(voiceRegResponse));
+    networkCb()->getVoiceRegistrationStateResponse(toAidl(info), toAidl(voiceRegResponse));
     return {};
 }
 
 Return<void> RadioResponse::isNrDualConnectivityEnabledResponse(const V1_6::RadioResponseInfo& info,
                                                                 bool isEnabled) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->isNrDualConnectivityEnabledResponse(toAidl(info), isEnabled);
+    networkCb()->isNrDualConnectivityEnabledResponse(toAidl(info), isEnabled);
     return {};
 }
 
@@ -297,15 +277,13 @@
 
 Return<void> RadioResponse::setAllowedNetworkTypesBitmapResponse(const V1_6::RadioResponseInfo& i) {
     LOG_CALL << i.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->setAllowedNetworkTypesBitmapResponse(toAidl(i));
+    networkCb()->setAllowedNetworkTypesBitmapResponse(toAidl(i));
     return {};
 }
 
 Return<void> RadioResponse::setPreferredNetworkTypeResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->setAllowedNetworkTypesBitmapResponse(toAidl(info));
+    networkCb()->setAllowedNetworkTypesBitmapResponse(toAidl(info));
     return {};
 }
 
@@ -318,174 +296,151 @@
 
 Return<void> RadioResponse::setBandModeResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->setBandModeResponse(toAidl(info));
+    networkCb()->setBandModeResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setBarringPasswordResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->setBarringPasswordResponse(toAidl(info));
+    networkCb()->setBarringPasswordResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setCdmaRoamingPreferenceResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->setCdmaRoamingPreferenceResponse(toAidl(info));
+    networkCb()->setCdmaRoamingPreferenceResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setCellInfoListRateResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->setCellInfoListRateResponse(toAidl(info));
+    networkCb()->setCellInfoListRateResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setIndicationFilterResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->setIndicationFilterResponse(toAidl(info));
+    networkCb()->setIndicationFilterResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setIndicationFilterResponse_1_5(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->setIndicationFilterResponse(toAidl(info));
+    networkCb()->setIndicationFilterResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setLinkCapacityReportingCriteriaResponse(
         const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->setLinkCapacityReportingCriteriaResponse(toAidl(info));
+    networkCb()->setLinkCapacityReportingCriteriaResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setLinkCapacityReportingCriteriaResponse_1_5(
         const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->setLinkCapacityReportingCriteriaResponse(toAidl(info));
+    networkCb()->setLinkCapacityReportingCriteriaResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setLocationUpdatesResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->setLocationUpdatesResponse(toAidl(info));
+    networkCb()->setLocationUpdatesResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setNetworkSelectionModeAutomaticResponse(
         const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->setNetworkSelectionModeAutomaticResponse(toAidl(info));
+    networkCb()->setNetworkSelectionModeAutomaticResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setNetworkSelectionModeManualResponse(
         const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->setNetworkSelectionModeManualResponse(toAidl(info));
+    networkCb()->setNetworkSelectionModeManualResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setNetworkSelectionModeManualResponse_1_5(
         const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->setNetworkSelectionModeManualResponse(toAidl(info));
+    networkCb()->setNetworkSelectionModeManualResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setNrDualConnectivityStateResponse(
         const V1_6::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->setNrDualConnectivityStateResponse(toAidl(info));
+    networkCb()->setNrDualConnectivityStateResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setSignalStrengthReportingCriteriaResponse(
         const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->setSignalStrengthReportingCriteriaResponse(toAidl(info));
+    networkCb()->setSignalStrengthReportingCriteriaResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setSignalStrengthReportingCriteriaResponse_1_5(
         const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->setSignalStrengthReportingCriteriaResponse(toAidl(info));
+    networkCb()->setSignalStrengthReportingCriteriaResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setSuppServiceNotificationsResponse(
         const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->setSuppServiceNotificationsResponse(toAidl(info));
+    networkCb()->setSuppServiceNotificationsResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setSystemSelectionChannelsResponse(
         const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->setSystemSelectionChannelsResponse(toAidl(info));
+    networkCb()->setSystemSelectionChannelsResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setSystemSelectionChannelsResponse_1_5(
         const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->setSystemSelectionChannelsResponse(toAidl(info));
+    networkCb()->setSystemSelectionChannelsResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::startNetworkScanResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->startNetworkScanResponse(toAidl(info));
+    networkCb()->startNetworkScanResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::startNetworkScanResponse_1_4(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->startNetworkScanResponse(toAidl(info));
+    networkCb()->startNetworkScanResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::startNetworkScanResponse_1_5(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->startNetworkScanResponse(toAidl(info));
+    networkCb()->startNetworkScanResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::stopNetworkScanResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->stopNetworkScanResponse(toAidl(info));
+    networkCb()->stopNetworkScanResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::supplyNetworkDepersonalizationResponse(
         const V1_0::RadioResponseInfo& info, int32_t remainingRetries) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->supplyNetworkDepersonalizationResponse(toAidl(info), remainingRetries);
+    networkCb()->supplyNetworkDepersonalizationResponse(toAidl(info), remainingRetries);
     return {};
 }
 
diff --git a/radio/aidl/compat/libradiocompat/sim/RadioIndication-sim.cpp b/radio/aidl/compat/libradiocompat/sim/RadioIndication-sim.cpp
index 6b906c6..3938e00 100644
--- a/radio/aidl/compat/libradiocompat/sim/RadioIndication-sim.cpp
+++ b/radio/aidl/compat/libradiocompat/sim/RadioIndication-sim.cpp
@@ -29,29 +29,29 @@
 namespace aidl = ::aidl::android::hardware::radio::sim;
 
 void RadioIndication::setResponseFunction(std::shared_ptr<aidl::IRadioSimIndication> simCb) {
-    CHECK(simCb);
     mSimCb = simCb;
 }
 
+std::shared_ptr<aidl::IRadioSimIndication> RadioIndication::simCb() {
+    return mSimCb.get();
+}
+
 Return<void> RadioIndication::carrierInfoForImsiEncryption(V1_0::RadioIndicationType type) {
     LOG_CALL << type;
-    CHECK_CB(mSimCb);
-    mSimCb->carrierInfoForImsiEncryption(toAidl(type));
+    simCb()->carrierInfoForImsiEncryption(toAidl(type));
     return {};
 }
 
 Return<void> RadioIndication::cdmaSubscriptionSourceChanged(
         V1_0::RadioIndicationType type, V1_0::CdmaSubscriptionSource cdmaSource) {
     LOG_CALL << type;
-    CHECK_CB(mSimCb);
-    mSimCb->cdmaSubscriptionSourceChanged(toAidl(type), aidl::CdmaSubscriptionSource(cdmaSource));
+    simCb()->cdmaSubscriptionSourceChanged(toAidl(type), aidl::CdmaSubscriptionSource(cdmaSource));
     return {};
 }
 
 Return<void> RadioIndication::simPhonebookChanged(V1_0::RadioIndicationType type) {
     LOG_CALL << type;
-    CHECK_CB(mSimCb);
-    mSimCb->simPhonebookChanged(toAidl(type));
+    simCb()->simPhonebookChanged(toAidl(type));
     return {};
 }
 
@@ -59,62 +59,54 @@
         V1_0::RadioIndicationType type, V1_6::PbReceivedStatus status,
         const hidl_vec<V1_6::PhonebookRecordInfo>& rec) {
     LOG_CALL << type;
-    CHECK_CB(mSimCb);
-    mSimCb->simPhonebookRecordsReceived(toAidl(type), aidl::PbReceivedStatus(status), toAidl(rec));
+    simCb()->simPhonebookRecordsReceived(toAidl(type), aidl::PbReceivedStatus(status), toAidl(rec));
     return {};
 }
 
 Return<void> RadioIndication::simRefresh(V1_0::RadioIndicationType type,
                                          const V1_0::SimRefreshResult& refreshResult) {
     LOG_CALL << type;
-    CHECK_CB(mSimCb);
-    mSimCb->simRefresh(toAidl(type), toAidl(refreshResult));
+    simCb()->simRefresh(toAidl(type), toAidl(refreshResult));
     return {};
 }
 
 Return<void> RadioIndication::simStatusChanged(V1_0::RadioIndicationType type) {
     LOG_CALL << type;
-    CHECK_CB(mSimCb);
-    mSimCb->simStatusChanged(toAidl(type));
+    simCb()->simStatusChanged(toAidl(type));
     return {};
 }
 
 Return<void> RadioIndication::stkEventNotify(V1_0::RadioIndicationType type,
                                              const hidl_string& cmd) {
     LOG_CALL << type;
-    CHECK_CB(mSimCb);
-    mSimCb->stkEventNotify(toAidl(type), cmd);
+    simCb()->stkEventNotify(toAidl(type), cmd);
     return {};
 }
 
 Return<void> RadioIndication::stkProactiveCommand(V1_0::RadioIndicationType type,
                                                   const hidl_string& cmd) {
     LOG_CALL << type;
-    CHECK_CB(mSimCb);
-    mSimCb->stkProactiveCommand(toAidl(type), cmd);
+    simCb()->stkProactiveCommand(toAidl(type), cmd);
     return {};
 }
 
 Return<void> RadioIndication::stkSessionEnd(V1_0::RadioIndicationType type) {
     LOG_CALL << type;
-    CHECK_CB(mSimCb);
-    mSimCb->stkSessionEnd(toAidl(type));
+    simCb()->stkSessionEnd(toAidl(type));
     return {};
 }
 
 Return<void> RadioIndication::subscriptionStatusChanged(V1_0::RadioIndicationType type,
                                                         bool activate) {
     LOG_CALL << type;
-    CHECK_CB(mSimCb);
-    mSimCb->subscriptionStatusChanged(toAidl(type), activate);
+    simCb()->subscriptionStatusChanged(toAidl(type), activate);
     return {};
 }
 
 Return<void> RadioIndication::uiccApplicationsEnablementChanged(V1_0::RadioIndicationType type,
                                                                 bool enabled) {
     LOG_CALL << type;
-    CHECK_CB(mSimCb);
-    mSimCb->uiccApplicationsEnablementChanged(toAidl(type), enabled);
+    simCb()->uiccApplicationsEnablementChanged(toAidl(type), enabled);
     return {};
 }
 
diff --git a/radio/aidl/compat/libradiocompat/sim/RadioResponse-sim.cpp b/radio/aidl/compat/libradiocompat/sim/RadioResponse-sim.cpp
index 2dfbc50..3ad9130 100644
--- a/radio/aidl/compat/libradiocompat/sim/RadioResponse-sim.cpp
+++ b/radio/aidl/compat/libradiocompat/sim/RadioResponse-sim.cpp
@@ -29,48 +29,46 @@
 namespace aidl = ::aidl::android::hardware::radio::sim;
 
 void RadioResponse::setResponseFunction(std::shared_ptr<aidl::IRadioSimResponse> simCb) {
-    CHECK(simCb);
     mSimCb = simCb;
 }
 
+std::shared_ptr<aidl::IRadioSimResponse> RadioResponse::simCb() {
+    return mSimCb.get();
+}
+
 Return<void> RadioResponse::areUiccApplicationsEnabledResponse(const V1_0::RadioResponseInfo& info,
                                                                bool enabled) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->areUiccApplicationsEnabledResponse(toAidl(info), enabled);
+    simCb()->areUiccApplicationsEnabledResponse(toAidl(info), enabled);
     return {};
 }
 
 Return<void> RadioResponse::changeIccPin2ForAppResponse(const V1_0::RadioResponseInfo& info,
                                                         int32_t remainingRetries) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->changeIccPin2ForAppResponse(toAidl(info), remainingRetries);
+    simCb()->changeIccPin2ForAppResponse(toAidl(info), remainingRetries);
     return {};
 }
 
 Return<void> RadioResponse::changeIccPinForAppResponse(const V1_0::RadioResponseInfo& info,
                                                        int32_t remainingRetries) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->changeIccPinForAppResponse(toAidl(info), remainingRetries);
+    simCb()->changeIccPinForAppResponse(toAidl(info), remainingRetries);
     return {};
 }
 
 Return<void> RadioResponse::enableUiccApplicationsResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->enableUiccApplicationsResponse(toAidl(info));
+    simCb()->enableUiccApplicationsResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::getAllowedCarriersResponse(  //
         const V1_0::RadioResponseInfo& info, bool allAllowed, const V1_0::CarrierRestrictions& cr) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
     aidl::CarrierRestrictions aidlCr = toAidl(cr);
     if (allAllowed) aidlCr = {};
-    mSimCb->getAllowedCarriersResponse(toAidl(info), aidlCr, {});
+    simCb()->getAllowedCarriersResponse(toAidl(info), aidlCr, {});
     return {};
 }
 
@@ -78,9 +76,8 @@
         const V1_0::RadioResponseInfo& info, const V1_4::CarrierRestrictionsWithPriority& carriers,
         V1_4::SimLockMultiSimPolicy multiSimPolicy) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->getAllowedCarriersResponse(toAidl(info), toAidl(carriers),
-                                       aidl::SimLockMultiSimPolicy(multiSimPolicy));
+    simCb()->getAllowedCarriersResponse(toAidl(info), toAidl(carriers),
+                                        aidl::SimLockMultiSimPolicy(multiSimPolicy));
     return {};
 }
 
@@ -88,133 +85,116 @@
         const V1_0::RadioResponseInfo& info, const hidl_string& mdn, const hidl_string& hSid,
         const hidl_string& hNid, const hidl_string& min, const hidl_string& prl) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->getCdmaSubscriptionResponse(toAidl(info), mdn, hSid, hNid, min, prl);
+    simCb()->getCdmaSubscriptionResponse(toAidl(info), mdn, hSid, hNid, min, prl);
     return {};
 }
 
 Return<void> RadioResponse::getCdmaSubscriptionSourceResponse(const V1_0::RadioResponseInfo& info,
                                                               V1_0::CdmaSubscriptionSource s) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->getCdmaSubscriptionSourceResponse(toAidl(info), aidl::CdmaSubscriptionSource(s));
+    simCb()->getCdmaSubscriptionSourceResponse(toAidl(info), aidl::CdmaSubscriptionSource(s));
     return {};
 }
 
 Return<void> RadioResponse::getFacilityLockForAppResponse(const V1_0::RadioResponseInfo& info,
                                                           int32_t response) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->getFacilityLockForAppResponse(toAidl(info), response);
+    simCb()->getFacilityLockForAppResponse(toAidl(info), response);
     return {};
 }
 
 Return<void> RadioResponse::getIccCardStatusResponse(const V1_0::RadioResponseInfo& info,
                                                      const V1_0::CardStatus& cardStatus) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->getIccCardStatusResponse(toAidl(info), toAidl(cardStatus));
+    simCb()->getIccCardStatusResponse(toAidl(info), toAidl(cardStatus));
     return {};
 }
 
 Return<void> RadioResponse::getIccCardStatusResponse_1_2(const V1_0::RadioResponseInfo& info,
                                                          const V1_2::CardStatus& cardStatus) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->getIccCardStatusResponse(toAidl(info), toAidl(cardStatus));
+    simCb()->getIccCardStatusResponse(toAidl(info), toAidl(cardStatus));
     return {};
 }
 
 Return<void> RadioResponse::getIccCardStatusResponse_1_4(const V1_0::RadioResponseInfo& info,
                                                          const V1_4::CardStatus& cardStatus) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->getIccCardStatusResponse(toAidl(info), toAidl(cardStatus));
+    simCb()->getIccCardStatusResponse(toAidl(info), toAidl(cardStatus));
     return {};
 }
 
 Return<void> RadioResponse::getIccCardStatusResponse_1_5(const V1_0::RadioResponseInfo& info,
                                                          const V1_5::CardStatus& cardStatus) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->getIccCardStatusResponse(toAidl(info), toAidl(cardStatus));
+    simCb()->getIccCardStatusResponse(toAidl(info), toAidl(cardStatus));
     return {};
 }
 
 Return<void> RadioResponse::getIMSIForAppResponse(const V1_0::RadioResponseInfo& info,
                                                   const hidl_string& imsi) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->getImsiForAppResponse(toAidl(info), imsi);
+    simCb()->getImsiForAppResponse(toAidl(info), imsi);
     return {};
 }
 
 Return<void> RadioResponse::getSimPhonebookCapacityResponse(
         const V1_6::RadioResponseInfo& info, const V1_6::PhonebookCapacity& capacity) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->getSimPhonebookCapacityResponse(toAidl(info), toAidl(capacity));
+    simCb()->getSimPhonebookCapacityResponse(toAidl(info), toAidl(capacity));
     return {};
 }
 
 Return<void> RadioResponse::getSimPhonebookRecordsResponse(const V1_6::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->getSimPhonebookRecordsResponse(toAidl(info));
+    simCb()->getSimPhonebookRecordsResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::iccCloseLogicalChannelResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->iccCloseLogicalChannelResponse(toAidl(info));
+    simCb()->iccCloseLogicalChannelResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::iccIOForAppResponse(const V1_0::RadioResponseInfo& info,
                                                 const V1_0::IccIoResult& iccIo) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->iccIoForAppResponse(toAidl(info), toAidl(iccIo));
+    simCb()->iccIoForAppResponse(toAidl(info), toAidl(iccIo));
     return {};
 }
 
 Return<void> RadioResponse::iccOpenLogicalChannelResponse(  //
         const V1_0::RadioResponseInfo& info, int32_t chanId, const hidl_vec<int8_t>& selectResp) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->iccOpenLogicalChannelResponse(toAidl(info), chanId, toAidl(selectResp));
+    simCb()->iccOpenLogicalChannelResponse(toAidl(info), chanId, toAidl(selectResp));
     return {};
 }
 
 Return<void> RadioResponse::iccTransmitApduBasicChannelResponse(const V1_0::RadioResponseInfo& info,
                                                                 const V1_0::IccIoResult& result) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->iccTransmitApduBasicChannelResponse(toAidl(info), toAidl(result));
+    simCb()->iccTransmitApduBasicChannelResponse(toAidl(info), toAidl(result));
     return {};
 }
 
 Return<void> RadioResponse::iccTransmitApduLogicalChannelResponse(
         const V1_0::RadioResponseInfo& info, const V1_0::IccIoResult& result) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->iccTransmitApduLogicalChannelResponse(toAidl(info), toAidl(result));
+    simCb()->iccTransmitApduLogicalChannelResponse(toAidl(info), toAidl(result));
     return {};
 }
 
 Return<void> RadioResponse::reportStkServiceIsRunningResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->reportStkServiceIsRunningResponse(toAidl(info));
+    simCb()->reportStkServiceIsRunningResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::requestIccSimAuthenticationResponse(const V1_0::RadioResponseInfo& info,
                                                                 const V1_0::IccIoResult& result) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->requestIccSimAuthenticationResponse(toAidl(info), toAidl(result));
+    simCb()->requestIccSimAuthenticationResponse(toAidl(info), toAidl(result));
     return {};
 }
 
@@ -228,121 +208,105 @@
 Return<void> RadioResponse::sendEnvelopeResponse(const V1_0::RadioResponseInfo& info,
                                                  const hidl_string& commandResponse) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->sendEnvelopeResponse(toAidl(info), commandResponse);
+    simCb()->sendEnvelopeResponse(toAidl(info), commandResponse);
     return {};
 }
 
 Return<void> RadioResponse::sendEnvelopeWithStatusResponse(const V1_0::RadioResponseInfo& info,
                                                            const V1_0::IccIoResult& iccIo) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->sendEnvelopeWithStatusResponse(toAidl(info), toAidl(iccIo));
+    simCb()->sendEnvelopeWithStatusResponse(toAidl(info), toAidl(iccIo));
     return {};
 }
 
 Return<void> RadioResponse::sendTerminalResponseToSimResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->sendTerminalResponseToSimResponse(toAidl(info));
+    simCb()->sendTerminalResponseToSimResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setAllowedCarriersResponse(const V1_0::RadioResponseInfo& info,
                                                        int32_t numAllowed) {
     LOG_CALL << info.serial << ' ' << numAllowed;
-    CHECK_CB(mSimCb);
-    mSimCb->setAllowedCarriersResponse(toAidl(info));
+    simCb()->setAllowedCarriersResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setAllowedCarriersResponse_1_4(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->setAllowedCarriersResponse(toAidl(info));
+    simCb()->setAllowedCarriersResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setCarrierInfoForImsiEncryptionResponse(
         const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->setCarrierInfoForImsiEncryptionResponse(toAidl(info));
+    simCb()->setCarrierInfoForImsiEncryptionResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setCdmaSubscriptionSourceResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->setCdmaSubscriptionSourceResponse(toAidl(info));
+    simCb()->setCdmaSubscriptionSourceResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setFacilityLockForAppResponse(const V1_0::RadioResponseInfo& info,
                                                           int32_t retry) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->setFacilityLockForAppResponse(toAidl(info), retry);
+    simCb()->setFacilityLockForAppResponse(toAidl(info), retry);
     return {};
 }
 
 Return<void> RadioResponse::setSimCardPowerResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->setSimCardPowerResponse(toAidl(info));
+    simCb()->setSimCardPowerResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setSimCardPowerResponse_1_1(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->setSimCardPowerResponse(toAidl(info));
+    simCb()->setSimCardPowerResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setSimCardPowerResponse_1_6(const V1_6::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->setSimCardPowerResponse(toAidl(info));
+    simCb()->setSimCardPowerResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setUiccSubscriptionResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->setUiccSubscriptionResponse(toAidl(info));
+    simCb()->setUiccSubscriptionResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::supplyIccPin2ForAppResponse(const V1_0::RadioResponseInfo& info,
                                                         int32_t remainingRetries) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->supplyIccPin2ForAppResponse(toAidl(info), remainingRetries);
+    simCb()->supplyIccPin2ForAppResponse(toAidl(info), remainingRetries);
     return {};
 }
 
 Return<void> RadioResponse::supplyIccPinForAppResponse(const V1_0::RadioResponseInfo& info,
                                                        int32_t remainingRetries) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->supplyIccPinForAppResponse(toAidl(info), remainingRetries);
+    simCb()->supplyIccPinForAppResponse(toAidl(info), remainingRetries);
     return {};
 }
 
 Return<void> RadioResponse::supplyIccPuk2ForAppResponse(const V1_0::RadioResponseInfo& info,
                                                         int32_t remainingRetries) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->supplyIccPuk2ForAppResponse(toAidl(info), remainingRetries);
+    simCb()->supplyIccPuk2ForAppResponse(toAidl(info), remainingRetries);
     return {};
 }
 
 Return<void> RadioResponse::supplyIccPukForAppResponse(const V1_0::RadioResponseInfo& info,
                                                        int32_t remainingRetries) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->supplyIccPukForAppResponse(toAidl(info), remainingRetries);
+    simCb()->supplyIccPukForAppResponse(toAidl(info), remainingRetries);
     return {};
 }
 
@@ -350,16 +314,14 @@
                                                                V1_5::PersoSubstate persoType,
                                                                int32_t rRet) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->supplySimDepersonalizationResponse(toAidl(info), aidl::PersoSubstate(persoType), rRet);
+    simCb()->supplySimDepersonalizationResponse(toAidl(info), aidl::PersoSubstate(persoType), rRet);
     return {};
 }
 
 Return<void> RadioResponse::updateSimPhonebookRecordsResponse(const V1_6::RadioResponseInfo& info,
                                                               int32_t updatedRecordIndex) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->updateSimPhonebookRecordsResponse(toAidl(info), updatedRecordIndex);
+    simCb()->updateSimPhonebookRecordsResponse(toAidl(info), updatedRecordIndex);
     return {};
 }
 
diff --git a/radio/aidl/compat/libradiocompat/sim/RadioSim.cpp b/radio/aidl/compat/libradiocompat/sim/RadioSim.cpp
index ca27918..b43f64f 100644
--- a/radio/aidl/compat/libradiocompat/sim/RadioSim.cpp
+++ b/radio/aidl/compat/libradiocompat/sim/RadioSim.cpp
@@ -30,6 +30,10 @@
 namespace aidl = ::aidl::android::hardware::radio::sim;
 constexpr auto ok = &ScopedAStatus::ok;
 
+std::shared_ptr<aidl::IRadioSimResponse> RadioSim::respond() {
+    return mCallbackManager->response().simCb();
+}
+
 ScopedAStatus RadioSim::areUiccApplicationsEnabled(int32_t serial) {
     LOG_CALL << serial;
     mHal1_5->areUiccApplicationsEnabled(serial);
@@ -58,7 +62,7 @@
 
 ScopedAStatus RadioSim::getAllowedCarriers(int32_t serial) {
     LOG_CALL << serial;
-    mHal1_5->getAllowedCarriers(serial);
+    mHal1_5->getAllowedCarriers_1_4(serial);
     return ok();
 }
 
@@ -99,7 +103,7 @@
     if (mHal1_6) {
         mHal1_6->getSimPhonebookCapacity(serial);
     } else {
-        respond().getSimPhonebookCapacityResponse(notSupported(serial), {});
+        respond()->getSimPhonebookCapacityResponse(notSupported(serial), {});
     }
     return ok();
 }
@@ -109,7 +113,7 @@
     if (mHal1_6) {
         mHal1_6->getSimPhonebookRecords(serial);
     } else {
-        respond().getSimPhonebookRecordsResponse(notSupported(serial));
+        respond()->getSimPhonebookRecordsResponse(notSupported(serial));
     }
     return ok();
 }
@@ -217,16 +221,10 @@
 }
 
 ScopedAStatus RadioSim::setResponseFunctions(
-        const std::shared_ptr<aidl::IRadioSimResponse>& simResponse,
-        const std::shared_ptr<aidl::IRadioSimIndication>& simIndication) {
-    LOG_CALL << simResponse << ' ' << simIndication;
-
-    CHECK(simResponse);
-    CHECK(simIndication);
-
-    mRadioResponse->setResponseFunction(simResponse);
-    mRadioIndication->setResponseFunction(simIndication);
-
+        const std::shared_ptr<aidl::IRadioSimResponse>& response,
+        const std::shared_ptr<aidl::IRadioSimIndication>& indication) {
+    LOG_CALL << response << ' ' << indication;
+    mCallbackManager->setResponseFunctions(response, indication);
     return ok();
 }
 
@@ -287,7 +285,7 @@
     if (mHal1_6) {
         mHal1_6->updateSimPhonebookRecords(serial, toHidl(recordInfo));
     } else {
-        respond().updateSimPhonebookRecordsResponse(notSupported(serial), 0);
+        respond()->updateSimPhonebookRecordsResponse(notSupported(serial), 0);
     }
     return ok();
 }
diff --git a/radio/aidl/compat/libradiocompat/sim/structs.cpp b/radio/aidl/compat/libradiocompat/sim/structs.cpp
index 97a21a1..bfbff02 100644
--- a/radio/aidl/compat/libradiocompat/sim/structs.cpp
+++ b/radio/aidl/compat/libradiocompat/sim/structs.cpp
@@ -173,7 +173,6 @@
             .atr = status.base.base.atr,
             .iccid = status.base.base.iccid,
             .eid = status.base.eid,
-            // TODO(b/203699028): we don't know portId here (but we can get it from RadioConfig)
             .slotMap = {static_cast<int32_t>(status.base.base.physicalSlotId), 0},
     };
 }
diff --git a/radio/aidl/compat/libradiocompat/voice/RadioIndication-voice.cpp b/radio/aidl/compat/libradiocompat/voice/RadioIndication-voice.cpp
index 6d9bda8..359fce0 100644
--- a/radio/aidl/compat/libradiocompat/voice/RadioIndication-voice.cpp
+++ b/radio/aidl/compat/libradiocompat/voice/RadioIndication-voice.cpp
@@ -29,113 +29,102 @@
 namespace aidl = ::aidl::android::hardware::radio::voice;
 
 void RadioIndication::setResponseFunction(std::shared_ptr<aidl::IRadioVoiceIndication> voiceCb) {
-    CHECK(voiceCb);
     mVoiceCb = voiceCb;
 }
 
+std::shared_ptr<aidl::IRadioVoiceIndication> RadioIndication::voiceCb() {
+    return mVoiceCb.get();
+}
+
 Return<void> RadioIndication::callRing(V1_0::RadioIndicationType type, bool isGsm,
                                        const V1_0::CdmaSignalInfoRecord& record) {
     LOG_CALL << type;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->callRing(toAidl(type), isGsm, toAidl(record));
+    voiceCb()->callRing(toAidl(type), isGsm, toAidl(record));
     return {};
 }
 
 Return<void> RadioIndication::callStateChanged(V1_0::RadioIndicationType type) {
     LOG_CALL << type;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->callStateChanged(toAidl(type));
+    voiceCb()->callStateChanged(toAidl(type));
     return {};
 }
 
 Return<void> RadioIndication::cdmaCallWaiting(V1_0::RadioIndicationType type,
                                               const V1_0::CdmaCallWaiting& callWaitingRecord) {
     LOG_CALL << type;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->cdmaCallWaiting(toAidl(type), toAidl(callWaitingRecord));
+    voiceCb()->cdmaCallWaiting(toAidl(type), toAidl(callWaitingRecord));
     return {};
 }
 
 Return<void> RadioIndication::cdmaInfoRec(V1_0::RadioIndicationType type,
                                           const V1_0::CdmaInformationRecords& records) {
     LOG_CALL << type;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->cdmaInfoRec(toAidl(type), toAidl(records.infoRec));
+    voiceCb()->cdmaInfoRec(toAidl(type), toAidl(records.infoRec));
     return {};
 }
 
 Return<void> RadioIndication::cdmaOtaProvisionStatus(V1_0::RadioIndicationType type,
                                                      V1_0::CdmaOtaProvisionStatus status) {
     LOG_CALL << type;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->cdmaOtaProvisionStatus(toAidl(type), aidl::CdmaOtaProvisionStatus(status));
+    voiceCb()->cdmaOtaProvisionStatus(toAidl(type), aidl::CdmaOtaProvisionStatus(status));
     return {};
 }
 
 Return<void> RadioIndication::currentEmergencyNumberList(
         V1_0::RadioIndicationType type, const hidl_vec<V1_4::EmergencyNumber>& emergencyNumbers) {
     LOG_CALL << type;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->currentEmergencyNumberList(toAidl(type), toAidl(emergencyNumbers));
+    voiceCb()->currentEmergencyNumberList(toAidl(type), toAidl(emergencyNumbers));
     return {};
 }
 
 Return<void> RadioIndication::enterEmergencyCallbackMode(V1_0::RadioIndicationType type) {
     LOG_CALL << type;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->enterEmergencyCallbackMode(toAidl(type));
+    voiceCb()->enterEmergencyCallbackMode(toAidl(type));
     return {};
 }
 
 Return<void> RadioIndication::exitEmergencyCallbackMode(V1_0::RadioIndicationType type) {
     LOG_CALL << type;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->exitEmergencyCallbackMode(toAidl(type));
+    voiceCb()->exitEmergencyCallbackMode(toAidl(type));
     return {};
 }
 
 Return<void> RadioIndication::indicateRingbackTone(V1_0::RadioIndicationType type, bool start) {
     LOG_CALL << type;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->indicateRingbackTone(toAidl(type), start);
+    voiceCb()->indicateRingbackTone(toAidl(type), start);
     return {};
 }
 
 Return<void> RadioIndication::onSupplementaryServiceIndication(V1_0::RadioIndicationType type,
                                                                const V1_0::StkCcUnsolSsResult& ss) {
     LOG_CALL << type;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->onSupplementaryServiceIndication(toAidl(type), toAidl(ss));
+    voiceCb()->onSupplementaryServiceIndication(toAidl(type), toAidl(ss));
     return {};
 }
 
 Return<void> RadioIndication::resendIncallMute(V1_0::RadioIndicationType type) {
     LOG_CALL << type;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->resendIncallMute(toAidl(type));
+    voiceCb()->resendIncallMute(toAidl(type));
     return {};
 }
 
 Return<void> RadioIndication::srvccStateNotify(V1_0::RadioIndicationType type,
                                                V1_0::SrvccState state) {
     LOG_CALL << type;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->srvccStateNotify(toAidl(type), aidl::SrvccState(state));
+    voiceCb()->srvccStateNotify(toAidl(type), aidl::SrvccState(state));
     return {};
 }
 
 Return<void> RadioIndication::stkCallControlAlphaNotify(V1_0::RadioIndicationType type,
                                                         const hidl_string& alpha) {
     LOG_CALL << type;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->stkCallControlAlphaNotify(toAidl(type), alpha);
+    voiceCb()->stkCallControlAlphaNotify(toAidl(type), alpha);
     return {};
 }
 
 Return<void> RadioIndication::stkCallSetup(V1_0::RadioIndicationType type, int64_t timeout) {
     LOG_CALL << type;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->stkCallSetup(toAidl(type), timeout);
+    voiceCb()->stkCallSetup(toAidl(type), timeout);
     return {};
 }
 
diff --git a/radio/aidl/compat/libradiocompat/voice/RadioResponse-voice.cpp b/radio/aidl/compat/libradiocompat/voice/RadioResponse-voice.cpp
index 0a64c56..d233548 100644
--- a/radio/aidl/compat/libradiocompat/voice/RadioResponse-voice.cpp
+++ b/radio/aidl/compat/libradiocompat/voice/RadioResponse-voice.cpp
@@ -29,265 +29,233 @@
 namespace aidl = ::aidl::android::hardware::radio::voice;
 
 void RadioResponse::setResponseFunction(std::shared_ptr<aidl::IRadioVoiceResponse> voiceCb) {
-    CHECK(voiceCb);
     mVoiceCb = voiceCb;
 }
 
+std::shared_ptr<aidl::IRadioVoiceResponse> RadioResponse::voiceCb() {
+    return mVoiceCb.get();
+}
+
 Return<void> RadioResponse::acceptCallResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->acceptCallResponse(toAidl(info));
+    voiceCb()->acceptCallResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::conferenceResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->conferenceResponse(toAidl(info));
+    voiceCb()->conferenceResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::dialResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->dialResponse(toAidl(info));
+    voiceCb()->dialResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::emergencyDialResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->emergencyDialResponse(toAidl(info));
+    voiceCb()->emergencyDialResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::exitEmergencyCallbackModeResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->exitEmergencyCallbackModeResponse(toAidl(info));
+    voiceCb()->exitEmergencyCallbackModeResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::explicitCallTransferResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->explicitCallTransferResponse(toAidl(info));
+    voiceCb()->explicitCallTransferResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::getCallForwardStatusResponse(
         const V1_0::RadioResponseInfo& info, const hidl_vec<V1_0::CallForwardInfo>& callFwdInfos) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->getCallForwardStatusResponse(toAidl(info), toAidl(callFwdInfos));
+    voiceCb()->getCallForwardStatusResponse(toAidl(info), toAidl(callFwdInfos));
     return {};
 }
 
 Return<void> RadioResponse::getCallWaitingResponse(const V1_0::RadioResponseInfo& info, bool enable,
                                                    int32_t serviceClass) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->getCallWaitingResponse(toAidl(info), enable, serviceClass);
+    voiceCb()->getCallWaitingResponse(toAidl(info), enable, serviceClass);
     return {};
 }
 
 Return<void> RadioResponse::getClipResponse(const V1_0::RadioResponseInfo& info,
                                             V1_0::ClipStatus status) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->getClipResponse(toAidl(info), aidl::ClipStatus(status));
+    voiceCb()->getClipResponse(toAidl(info), aidl::ClipStatus(status));
     return {};
 }
 
 Return<void> RadioResponse::getClirResponse(const V1_0::RadioResponseInfo& info, int32_t n,
                                             int32_t m) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->getClirResponse(toAidl(info), n, m);
+    voiceCb()->getClirResponse(toAidl(info), n, m);
     return {};
 }
 
 Return<void> RadioResponse::getCurrentCallsResponse(const V1_0::RadioResponseInfo& info,
                                                     const hidl_vec<V1_0::Call>& calls) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->getCurrentCallsResponse(toAidl(info), toAidl(calls));
+    voiceCb()->getCurrentCallsResponse(toAidl(info), toAidl(calls));
     return {};
 }
 
 Return<void> RadioResponse::getCurrentCallsResponse_1_2(const V1_0::RadioResponseInfo& info,
                                                         const hidl_vec<V1_2::Call>& calls) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->getCurrentCallsResponse(toAidl(info), toAidl(calls));
+    voiceCb()->getCurrentCallsResponse(toAidl(info), toAidl(calls));
     return {};
 }
 
 Return<void> RadioResponse::getCurrentCallsResponse_1_6(const V1_6::RadioResponseInfo& info,
                                                         const hidl_vec<V1_6::Call>& calls) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->getCurrentCallsResponse(toAidl(info), toAidl(calls));
+    voiceCb()->getCurrentCallsResponse(toAidl(info), toAidl(calls));
     return {};
 }
 
 Return<void> RadioResponse::getLastCallFailCauseResponse(
         const V1_0::RadioResponseInfo& info, const V1_0::LastCallFailCauseInfo& failCauseinfo) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->getLastCallFailCauseResponse(toAidl(info), toAidl(failCauseinfo));
+    voiceCb()->getLastCallFailCauseResponse(toAidl(info), toAidl(failCauseinfo));
     return {};
 }
 
 Return<void> RadioResponse::getMuteResponse(const V1_0::RadioResponseInfo& info, bool enable) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->getMuteResponse(toAidl(info), enable);
+    voiceCb()->getMuteResponse(toAidl(info), enable);
     return {};
 }
 
 Return<void> RadioResponse::getPreferredVoicePrivacyResponse(const V1_0::RadioResponseInfo& info,
                                                              bool enable) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->getPreferredVoicePrivacyResponse(toAidl(info), enable);
+    voiceCb()->getPreferredVoicePrivacyResponse(toAidl(info), enable);
     return {};
 }
 
 Return<void> RadioResponse::getTTYModeResponse(const V1_0::RadioResponseInfo& info,
                                                V1_0::TtyMode mode) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->getTtyModeResponse(toAidl(info), aidl::TtyMode(mode));
+    voiceCb()->getTtyModeResponse(toAidl(info), aidl::TtyMode(mode));
     return {};
 }
 
 Return<void> RadioResponse::handleStkCallSetupRequestFromSimResponse(
         const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->handleStkCallSetupRequestFromSimResponse(toAidl(info));
+    voiceCb()->handleStkCallSetupRequestFromSimResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::hangupConnectionResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->hangupConnectionResponse(toAidl(info));
+    voiceCb()->hangupConnectionResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::hangupForegroundResumeBackgroundResponse(
         const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->hangupForegroundResumeBackgroundResponse(toAidl(info));
+    voiceCb()->hangupForegroundResumeBackgroundResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::hangupWaitingOrBackgroundResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->hangupWaitingOrBackgroundResponse(toAidl(info));
+    voiceCb()->hangupWaitingOrBackgroundResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::rejectCallResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->rejectCallResponse(toAidl(info));
+    voiceCb()->rejectCallResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::sendBurstDtmfResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->sendBurstDtmfResponse(toAidl(info));
+    voiceCb()->sendBurstDtmfResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::sendCDMAFeatureCodeResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->sendCdmaFeatureCodeResponse(toAidl(info));
+    voiceCb()->sendCdmaFeatureCodeResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::sendDtmfResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->sendDtmfResponse(toAidl(info));
+    voiceCb()->sendDtmfResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::separateConnectionResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->separateConnectionResponse(toAidl(info));
+    voiceCb()->separateConnectionResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setCallForwardResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->setCallForwardResponse(toAidl(info));
+    voiceCb()->setCallForwardResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setCallWaitingResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->setCallWaitingResponse(toAidl(info));
+    voiceCb()->setCallWaitingResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setClirResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->setClirResponse(toAidl(info));
+    voiceCb()->setClirResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setMuteResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->setMuteResponse(toAidl(info));
+    voiceCb()->setMuteResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setPreferredVoicePrivacyResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->setPreferredVoicePrivacyResponse(toAidl(info));
+    voiceCb()->setPreferredVoicePrivacyResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setTTYModeResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->setTtyModeResponse(toAidl(info));
+    voiceCb()->setTtyModeResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::startDtmfResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->startDtmfResponse(toAidl(info));
+    voiceCb()->startDtmfResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::stopDtmfResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->stopDtmfResponse(toAidl(info));
+    voiceCb()->stopDtmfResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::switchWaitingOrHoldingAndActiveResponse(
         const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->switchWaitingOrHoldingAndActiveResponse(toAidl(info));
+    voiceCb()->switchWaitingOrHoldingAndActiveResponse(toAidl(info));
     return {};
 }
 
diff --git a/radio/aidl/compat/libradiocompat/voice/RadioVoice.cpp b/radio/aidl/compat/libradiocompat/voice/RadioVoice.cpp
index 16c6b14..71d1a56 100644
--- a/radio/aidl/compat/libradiocompat/voice/RadioVoice.cpp
+++ b/radio/aidl/compat/libradiocompat/voice/RadioVoice.cpp
@@ -30,6 +30,10 @@
 namespace aidl = ::aidl::android::hardware::radio::voice;
 constexpr auto ok = &ScopedAStatus::ok;
 
+std::shared_ptr<aidl::IRadioVoiceResponse> RadioVoice::respond() {
+    return mCallbackManager->response().voiceCb();
+}
+
 ScopedAStatus RadioVoice::acceptCall(int32_t serial) {
     LOG_CALL << serial;
     mHal1_5->acceptCall(serial);
@@ -49,13 +53,19 @@
 }
 
 ScopedAStatus RadioVoice::emergencyDial(  //
-        int32_t serial, const aidl::Dial& dialInfo, aidl::EmergencyServiceCategory categories,
+        int32_t serial, const aidl::Dial& info, int32_t categories,
         const std::vector<std::string>& urns, aidl::EmergencyCallRouting routing,
-        bool hasKnownUserIntentEmerg, bool isTesting) {
+        bool knownUserIntentEmerg, bool isTesting) {
     LOG_CALL << serial;
-    mHal1_5->emergencyDial(serial, toHidl(dialInfo),
-                           toHidlBitfield<V1_4::EmergencyServiceCategory>(categories), toHidl(urns),
-                           V1_4::EmergencyCallRouting(routing), hasKnownUserIntentEmerg, isTesting);
+    if (mHal1_6) {
+        mHal1_6->emergencyDial_1_6(  //
+                serial, toHidl(info), toHidlBitfield<V1_4::EmergencyServiceCategory>(categories),
+                toHidl(urns), V1_4::EmergencyCallRouting(routing), knownUserIntentEmerg, isTesting);
+    } else {
+        mHal1_5->emergencyDial(  //
+                serial, toHidl(info), toHidlBitfield<V1_4::EmergencyServiceCategory>(categories),
+                toHidl(urns), V1_4::EmergencyCallRouting(routing), knownUserIntentEmerg, isTesting);
+    }
     return ok();
 }
 
@@ -98,7 +108,11 @@
 
 ScopedAStatus RadioVoice::getCurrentCalls(int32_t serial) {
     LOG_CALL << serial;
-    mHal1_5->getCurrentCalls(serial);
+    if (mHal1_6) {
+        mHal1_6->getCurrentCalls_1_6(serial);
+    } else {
+        mHal1_5->getCurrentCalls(serial);
+    }
     return ok();
 }
 
@@ -152,7 +166,7 @@
 
 ScopedAStatus RadioVoice::isVoNrEnabled(int32_t serial) {
     LOG_CALL << serial;
-    // TODO(b/203699028): can't call isVoNrEnabledResponse with 1.6 callback
+    respond()->isVoNrEnabledResponse(notSupported(serial), false);
     return ok();
 }
 
@@ -224,16 +238,10 @@
 }
 
 ScopedAStatus RadioVoice::setResponseFunctions(
-        const std::shared_ptr<aidl::IRadioVoiceResponse>& voiceResponse,
-        const std::shared_ptr<aidl::IRadioVoiceIndication>& voiceIndication) {
-    LOG_CALL << voiceResponse << ' ' << voiceIndication;
-
-    CHECK(voiceResponse);
-    CHECK(voiceIndication);
-
-    mRadioResponse->setResponseFunction(voiceResponse);
-    mRadioIndication->setResponseFunction(voiceIndication);
-
+        const std::shared_ptr<aidl::IRadioVoiceResponse>& response,
+        const std::shared_ptr<aidl::IRadioVoiceIndication>& indication) {
+    LOG_CALL << response << ' ' << indication;
+    mCallbackManager->setResponseFunctions(response, indication);
     return ok();
 }
 
@@ -245,7 +253,8 @@
 
 ndk::ScopedAStatus RadioVoice::setVoNrEnabled(int32_t serial, [[maybe_unused]] bool enable) {
     LOG_CALL << serial;
-    // TODO(b/203699028): should set `persist.radio.is_vonr_enabled_` property instead
+    // Note: a workaround for older HALs could also be setting persist.radio.is_vonr_enabled_
+    respond()->setVoNrEnabledResponse(notSupported(serial));
     return ok();
 }
 
diff --git a/radio/aidl/compat/libradiocompat/voice/structs.cpp b/radio/aidl/compat/libradiocompat/voice/structs.cpp
index ae6342e..254ea20 100644
--- a/radio/aidl/compat/libradiocompat/voice/structs.cpp
+++ b/radio/aidl/compat/libradiocompat/voice/structs.cpp
@@ -147,7 +147,7 @@
             .number = num.number,
             .mcc = num.mcc,
             .mnc = num.mnc,
-            .categories = aidl::EmergencyServiceCategory(num.categories),
+            .categories = num.categories,
             .urns = toAidl(num.urns),
             .sources = num.sources,
     };
diff --git a/radio/aidl/compat/service/service.cpp b/radio/aidl/compat/service/service.cpp
index 2a67569..8af05de 100644
--- a/radio/aidl/compat/service/service.cpp
+++ b/radio/aidl/compat/service/service.cpp
@@ -19,13 +19,12 @@
 #include <android-base/logging.h>
 #include <android/binder_manager.h>
 #include <android/binder_process.h>
+#include <libradiocompat/CallbackManager.h>
 #include <libradiocompat/RadioConfig.h>
 #include <libradiocompat/RadioData.h>
-#include <libradiocompat/RadioIndication.h>
 #include <libradiocompat/RadioMessaging.h>
 #include <libradiocompat/RadioModem.h>
 #include <libradiocompat/RadioNetwork.h>
-#include <libradiocompat/RadioResponse.h>
 #include <libradiocompat/RadioSim.h>
 #include <libradiocompat/RadioVoice.h>
 
@@ -36,8 +35,8 @@
 static std::vector<std::shared_ptr<ndk::ICInterface>> gPublishedHals;
 
 template <typename T>
-static void publishRadioHal(sp<V1_5::IRadio> hidlHal, sp<compat::RadioResponse> responseCb,
-                            sp<compat::RadioIndication> indicationCb, const std::string& slot) {
+static void publishRadioHal(std::shared_ptr<compat::DriverContext> ctx, sp<V1_5::IRadio> hidlHal,
+                            std::shared_ptr<compat::CallbackManager> cm, const std::string& slot) {
     const auto instance = T::descriptor + "/"s + slot;
     if (!AServiceManager_isDeclared(instance.c_str())) {
         LOG(INFO) << instance << " is not declared in VINTF (this may be intentional)";
@@ -45,7 +44,7 @@
     }
     LOG(DEBUG) << "Publishing " << instance;
 
-    auto aidlHal = ndk::SharedRefBase::make<T>(hidlHal, responseCb, indicationCb);
+    auto aidlHal = ndk::SharedRefBase::make<T>(ctx, hidlHal, cm);
     gPublishedHals.push_back(aidlHal);
     const auto status = AServiceManager_addService(aidlHal->asBinder().get(), instance.c_str());
     CHECK_EQ(status, STATUS_OK);
@@ -57,16 +56,15 @@
 
     hidl_utils::linkDeathToDeath(radioHidl);
 
-    auto responseCb = sp<compat::RadioResponse>::make();
-    auto indicationCb = sp<compat::RadioIndication>::make();
-    radioHidl->setResponseFunctions(responseCb, indicationCb).assertOk();
+    auto context = std::make_shared<compat::DriverContext>();
+    auto callbackMgr = std::make_shared<compat::CallbackManager>(context, radioHidl);
 
-    publishRadioHal<compat::RadioData>(radioHidl, responseCb, indicationCb, slot);
-    publishRadioHal<compat::RadioMessaging>(radioHidl, responseCb, indicationCb, slot);
-    publishRadioHal<compat::RadioModem>(radioHidl, responseCb, indicationCb, slot);
-    publishRadioHal<compat::RadioNetwork>(radioHidl, responseCb, indicationCb, slot);
-    publishRadioHal<compat::RadioSim>(radioHidl, responseCb, indicationCb, slot);
-    publishRadioHal<compat::RadioVoice>(radioHidl, responseCb, indicationCb, slot);
+    publishRadioHal<compat::RadioData>(context, radioHidl, callbackMgr, slot);
+    publishRadioHal<compat::RadioMessaging>(context, radioHidl, callbackMgr, slot);
+    publishRadioHal<compat::RadioModem>(context, radioHidl, callbackMgr, slot);
+    publishRadioHal<compat::RadioNetwork>(context, radioHidl, callbackMgr, slot);
+    publishRadioHal<compat::RadioSim>(context, radioHidl, callbackMgr, slot);
+    publishRadioHal<compat::RadioVoice>(context, radioHidl, callbackMgr, slot);
 }
 
 static void publishRadioConfig() {
@@ -83,6 +81,7 @@
 }
 
 static void main() {
+    base::InitLogging(nullptr, base::LogdLogger(base::RADIO));
     base::SetDefaultTag("radiocompat");
     base::SetMinimumLogSeverity(base::VERBOSE);
     LOG(DEBUG) << "Radio HAL compat service starting...";
diff --git a/radio/aidl/vts/Android.bp b/radio/aidl/vts/Android.bp
new file mode 100644
index 0000000..8060e4b
--- /dev/null
+++ b/radio/aidl/vts/Android.bp
@@ -0,0 +1,74 @@
+// 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 {
+    // 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: "VtsHalRadioTargetTest",
+    defaults: [
+        "VtsHalTargetTestDefaults",
+        "use_libaidlvintf_gtest_helper_static",
+    ],
+    srcs: [
+        "radio_aidl_hal_utils.cpp",
+        "radio_config_indication.cpp",
+        "radio_config_response.cpp",
+        "radio_config_test.cpp",
+        "radio_data_indication.cpp",
+        "radio_data_response.cpp",
+        "radio_data_test.cpp",
+        "radio_messaging_indication.cpp",
+        "radio_messaging_response.cpp",
+        "radio_messaging_test.cpp",
+        "radio_modem_indication.cpp",
+        "radio_modem_response.cpp",
+        "radio_modem_test.cpp",
+        "radio_network_indication.cpp",
+        "radio_network_response.cpp",
+        "radio_network_test.cpp",
+        "radio_sim_indication.cpp",
+        "radio_sim_response.cpp",
+        "radio_sim_test.cpp",
+        "radio_voice_indication.cpp",
+        "radio_voice_response.cpp",
+        "radio_voice_test.cpp",
+        "VtsHalRadioTargetTest.cpp",
+    ],
+    shared_libs: [
+        "libbinder_ndk",
+        "libvintf",
+    ],
+    static_libs: [
+        "android.hardware.radio-V1-ndk",
+        "android.hardware.radio.config-V1-ndk",
+        "android.hardware.radio.data-V1-ndk",
+        "android.hardware.radio.messaging-V1-ndk",
+        "android.hardware.radio.modem-V1-ndk",
+        "android.hardware.radio.network-V1-ndk",
+        "android.hardware.radio.sim-V1-ndk",
+        "android.hardware.radio.voice-V1-ndk",
+    ],
+    // TODO(b/210712359): enable after b/207695009 is resolved.
+    //test_suites: [
+    //    "general-tests",
+    //    "vts",
+    //],
+}
diff --git a/radio/aidl/vts/VtsHalRadioTargetTest.cpp b/radio/aidl/vts/VtsHalRadioTargetTest.cpp
new file mode 100644
index 0000000..1ebc6af
--- /dev/null
+++ b/radio/aidl/vts/VtsHalRadioTargetTest.cpp
@@ -0,0 +1,73 @@
+/*
+ * 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/binder_process.h>
+
+#include "radio_config_utils.h"
+#include "radio_data_utils.h"
+#include "radio_messaging_utils.h"
+#include "radio_modem_utils.h"
+#include "radio_network_utils.h"
+#include "radio_sim_utils.h"
+#include "radio_voice_utils.h"
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(RadioConfigTest);
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, RadioConfigTest,
+        testing::ValuesIn(android::getAidlHalInstanceNames(IRadioConfig::descriptor)),
+        android::PrintInstanceNameToString);
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(RadioDataTest);
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, RadioDataTest,
+        testing::ValuesIn(android::getAidlHalInstanceNames(IRadioData::descriptor)),
+        android::PrintInstanceNameToString);
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(RadioMessagingTest);
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, RadioMessagingTest,
+        testing::ValuesIn(android::getAidlHalInstanceNames(IRadioMessaging::descriptor)),
+        android::PrintInstanceNameToString);
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(RadioModemTest);
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, RadioModemTest,
+        testing::ValuesIn(android::getAidlHalInstanceNames(IRadioModem::descriptor)),
+        android::PrintInstanceNameToString);
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(RadioNetworkTest);
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, RadioNetworkTest,
+        testing::ValuesIn(android::getAidlHalInstanceNames(IRadioNetwork::descriptor)),
+        android::PrintInstanceNameToString);
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(RadioSimTest);
+INSTANTIATE_TEST_SUITE_P(PerInstance, RadioSimTest,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(IRadioSim::descriptor)),
+                         android::PrintInstanceNameToString);
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(RadioVoiceTest);
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, RadioVoiceTest,
+        testing::ValuesIn(android::getAidlHalInstanceNames(IRadioVoice::descriptor)),
+        android::PrintInstanceNameToString);
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    ABinderProcess_setThreadPoolMaxThreadCount(1);
+    ABinderProcess_startThreadPool();
+    return RUN_ALL_TESTS();
+}
diff --git a/radio/aidl/vts/radio_aidl_hal_utils.cpp b/radio/aidl/vts/radio_aidl_hal_utils.cpp
new file mode 100644
index 0000000..dc61a3c
--- /dev/null
+++ b/radio/aidl/vts/radio_aidl_hal_utils.cpp
@@ -0,0 +1,206 @@
+/*
+ * 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 "RadioTest"
+
+#include "radio_aidl_hal_utils.h"
+#include <iostream>
+#include "VtsCoreUtil.h"
+#include "radio_config_utils.h"
+#include "radio_sim_utils.h"
+
+#define WAIT_TIMEOUT_PERIOD 75
+
+sim::CardStatus cardStatus = {};
+int serial = 0;
+int count_ = 0;
+
+int GetRandomSerialNumber() {
+    return rand();
+}
+
+::testing::AssertionResult CheckAnyOfErrors(RadioError err, std::vector<RadioError> errors,
+                                            CheckFlag flag) {
+    const static std::vector<RadioError> generalErrors = {
+            RadioError::RADIO_NOT_AVAILABLE,   RadioError::NO_MEMORY,
+            RadioError::INTERNAL_ERR,          RadioError::SYSTEM_ERR,
+            RadioError::REQUEST_NOT_SUPPORTED, RadioError::CANCELLED};
+    if (flag == CHECK_GENERAL_ERROR || flag == CHECK_OEM_AND_GENERAL_ERROR) {
+        for (size_t i = 0; i < generalErrors.size(); i++) {
+            if (err == generalErrors[i]) {
+                return testing::AssertionSuccess();
+            }
+        }
+    }
+    if (flag == CHECK_OEM_ERROR || flag == CHECK_OEM_AND_GENERAL_ERROR) {
+        if (err >= RadioError::OEM_ERROR_1 && err <= RadioError::OEM_ERROR_25) {
+            return testing::AssertionSuccess();
+        }
+    }
+    for (size_t i = 0; i < errors.size(); i++) {
+        if (err == errors[i]) {
+            return testing::AssertionSuccess();
+        }
+    }
+    return testing::AssertionFailure() << "RadioError:" + toString(err) + " is returned";
+}
+
+// Runs "pm list features" and attempts to find the specified feature in its output.
+bool deviceSupportsFeature(const char* feature) {
+    bool hasFeature = false;
+    FILE* p = popen("/system/bin/pm list features", "re");
+    if (p) {
+        char* line = NULL;
+        size_t len = 0;
+        while (getline(&line, &len, p) > 0) {
+            if (strstr(line, feature)) {
+                hasFeature = true;
+                break;
+            }
+        }
+        pclose(p);
+    } else {
+        __android_log_print(ANDROID_LOG_FATAL, LOG_TAG, "popen failed: %d", errno);
+        _exit(EXIT_FAILURE);
+    }
+    __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "Feature %s: %ssupported", feature,
+                        hasFeature ? "" : "not ");
+    return hasFeature;
+}
+
+bool isSsSsEnabled() {
+    // Do not use checkSubstringInCommandOutput("getprop persist.radio.multisim.config", "")
+    // until b/148904287 is fixed. We need exact matching instead of partial matching. (i.e.
+    // by definition the empty string "" is a substring of any string).
+    return !isDsDsEnabled() && !isTsTsEnabled();
+}
+
+bool isDsDsEnabled() {
+    return testing::checkSubstringInCommandOutput("getprop persist.radio.multisim.config", "dsds");
+}
+
+bool isTsTsEnabled() {
+    return testing::checkSubstringInCommandOutput("getprop persist.radio.multisim.config", "tsts");
+}
+
+bool isVoiceInService(RegState state) {
+    return RegState::REG_HOME == state || RegState::REG_ROAMING == state;
+}
+
+bool isVoiceEmergencyOnly(RegState state) {
+    return RegState::NOT_REG_MT_NOT_SEARCHING_OP_EM == state ||
+           RegState::NOT_REG_MT_SEARCHING_OP_EM == state || RegState::REG_DENIED_EM == state ||
+           RegState::UNKNOWN_EM == state;
+}
+
+bool stringEndsWith(std::string const& string, std::string const& end) {
+    if (string.size() >= end.size()) {
+        return (0 == string.compare(string.size() - end.size() - 1, end.size(), end));
+    } else {
+        return false;
+    }
+}
+
+bool isServiceValidForDeviceConfiguration(std::string& serviceName) {
+    if (isSsSsEnabled()) {
+        // Device is configured as SSSS.
+        if (stringEndsWith(serviceName, RADIO_SERVICE_SLOT1_NAME)) {
+            ALOGI("%s instance is not valid for SSSS device.", serviceName.c_str());
+            return false;
+        }
+    } else if (isDsDsEnabled()) {
+        // Device is configured as DSDS.
+        if (!stringEndsWith(serviceName, RADIO_SERVICE_SLOT1_NAME) &&
+            !stringEndsWith(serviceName, RADIO_SERVICE_SLOT2_NAME)) {
+            ALOGI("%s instance is not valid for DSDS device.", serviceName.c_str());
+            return false;
+        }
+    } else if (isTsTsEnabled()) {
+        // Device is configured as TSTS.
+        if (!stringEndsWith(serviceName, RADIO_SERVICE_SLOT1_NAME) &&
+            !stringEndsWith(serviceName, RADIO_SERVICE_SLOT2_NAME) &&
+            !stringEndsWith(serviceName, RADIO_SERVICE_SLOT3_NAME)) {
+            ALOGI("%s instance is not valid for TSTS device.", serviceName.c_str());
+            return false;
+        }
+    }
+    return true;
+}
+
+/*
+ * Notify that the response message is received.
+ */
+void RadioServiceTest::notify(int receivedSerial) {
+    std::unique_lock<std::mutex> lock(mtx_);
+    if (serial == receivedSerial) {
+        count_++;
+        cv_.notify_one();
+    }
+}
+
+/*
+ * Wait till the response message is notified or till WAIT_TIMEOUT_PERIOD.
+ */
+std::cv_status RadioServiceTest::wait() {
+    std::unique_lock<std::mutex> lock(mtx_);
+    std::cv_status status = std::cv_status::no_timeout;
+    auto now = std::chrono::system_clock::now();
+    while (count_ == 0) {
+        status = cv_.wait_until(lock, now + std::chrono::seconds(WAIT_TIMEOUT_PERIOD));
+        if (status == std::cv_status::timeout) {
+            return status;
+        }
+    }
+    count_--;
+    return status;
+}
+
+/**
+ * Specific features on the Radio HAL rely on Radio HAL Capabilities.
+ * The VTS test related to those features must not run if the related capability is disabled.
+ * Typical usage within VTS:
+ * if (getRadioHalCapabilities()) return;
+ */
+bool RadioServiceTest::getRadioHalCapabilities() {
+    // Get HalDeviceCapabilities from RadioConfig
+    std::shared_ptr<RadioConfigResponse> radioConfigRsp =
+            ndk::SharedRefBase::make<RadioConfigResponse>(*this);
+    std::shared_ptr<RadioConfigIndication> radioConfigInd =
+            ndk::SharedRefBase::make<RadioConfigIndication>(*this);
+    radio_config->setResponseFunctions(radioConfigRsp, radioConfigInd);
+    serial = GetRandomSerialNumber();
+    radio_config->getHalDeviceCapabilities(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    return radioConfigRsp->modemReducedFeatureSet1;
+}
+
+/**
+ * Some VTS tests require the SIM card status to be present before running.
+ * Update the SIM card status, which can be accessed via the extern cardStatus.
+ */
+void RadioServiceTest::updateSimCardStatus() {
+    // Update CardStatus from RadioSim
+    std::shared_ptr<RadioSimResponse> radioSimRsp =
+            ndk::SharedRefBase::make<RadioSimResponse>(*this);
+    std::shared_ptr<RadioSimIndication> radioSimInd =
+            ndk::SharedRefBase::make<RadioSimIndication>(*this);
+    radio_sim->setResponseFunctions(radioSimRsp, radioSimInd);
+    serial = GetRandomSerialNumber();
+    radio_sim->getIccCardStatus(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioSimRsp->rspInfo.type);
+    EXPECT_EQ(serial, radioSimRsp->rspInfo.serial);
+    EXPECT_EQ(RadioError::NONE, radioSimRsp->rspInfo.error);
+}
diff --git a/radio/aidl/vts/radio_aidl_hal_utils.h b/radio/aidl/vts/radio_aidl_hal_utils.h
new file mode 100644
index 0000000..414ffbc
--- /dev/null
+++ b/radio/aidl/vts/radio_aidl_hal_utils.h
@@ -0,0 +1,144 @@
+/*
+ * 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/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/radio/RadioError.h>
+#include <aidl/android/hardware/radio/config/IRadioConfig.h>
+#include <aidl/android/hardware/radio/network/RegState.h>
+#include <aidl/android/hardware/radio/sim/CardStatus.h>
+#include <aidl/android/hardware/radio/sim/IRadioSim.h>
+#include <utils/Log.h>
+#include <vector>
+
+using namespace aidl::android::hardware::radio;
+using aidl::android::hardware::radio::network::RegState;
+using aidl::android::hardware::radio::sim::CardStatus;
+
+extern CardStatus cardStatus;
+extern int serial;
+extern int count_;
+
+/*
+ * MACRO used to skip test case when radio response return error REQUEST_NOT_SUPPORTED
+ * on HAL versions which has deprecated the request interfaces. The MACRO can only be used
+ * AFTER receiving radio response.
+ */
+#define SKIP_TEST_IF_REQUEST_NOT_SUPPORTED_WITH_HAL(__ver__, __radio__, __radioRsp__)      \
+    do {                                                                                   \
+        sp<::android::hardware::radio::V##__ver__::IRadio> __radio =                       \
+                ::android::hardware::radio::V##__ver__::IRadio::castFrom(__radio__);       \
+        if (__radio && __radioRsp__->rspInfo.error == RadioError::REQUEST_NOT_SUPPORTED) { \
+            GTEST_SKIP() << "REQUEST_NOT_SUPPORTED";                                       \
+        }                                                                                  \
+    } while (0)
+
+enum CheckFlag {
+    CHECK_DEFAULT = 0,
+    CHECK_GENERAL_ERROR = 1,
+    CHECK_OEM_ERROR = 2,
+    CHECK_OEM_AND_GENERAL_ERROR = 3,
+    CHECK_SAP_ERROR = 4,
+};
+
+static constexpr const char* FEATURE_VOICE_CALL = "android.software.connectionservice";
+
+static constexpr const char* FEATURE_TELEPHONY = "android.hardware.telephony";
+
+static constexpr const char* FEATURE_TELEPHONY_GSM = "android.hardware.telephony.gsm";
+
+static constexpr const char* FEATURE_TELEPHONY_CDMA = "android.hardware.telephony.cdma";
+
+#define MODEM_EMERGENCY_CALL_ESTABLISH_TIME 3
+#define MODEM_EMERGENCY_CALL_DISCONNECT_TIME 3
+#define MODEM_SET_SIM_POWER_DELAY_IN_SECONDS 2
+
+#define RADIO_SERVICE_SLOT1_NAME "slot1"  // HAL instance name for SIM slot 1 or single SIM device
+#define RADIO_SERVICE_SLOT2_NAME "slot2"  // HAL instance name for SIM slot 2 on dual SIM device
+#define RADIO_SERVICE_SLOT3_NAME "slot3"  // HAL instance name for SIM slot 3 on triple SIM device
+
+/*
+ * Generate random serial number for radio test
+ */
+int GetRandomSerialNumber();
+
+/*
+ * Check multiple radio error codes which are possibly returned because of the different
+ * vendor/devices implementations. It allows optional checks for general errors or/and oem errors.
+ */
+::testing::AssertionResult CheckAnyOfErrors(RadioError err, std::vector<RadioError> generalError,
+                                            CheckFlag flag = CHECK_DEFAULT);
+
+/*
+ * Check if device supports feature.
+ */
+bool deviceSupportsFeature(const char* feature);
+
+/*
+ * Check if device is in SsSs (Single SIM Single Standby).
+ */
+bool isSsSsEnabled();
+
+/*
+ * Check if device is in DSDS (Dual SIM Dual Standby).
+ */
+bool isDsDsEnabled();
+
+/*
+ * Check if device is in TSTS (Triple SIM Triple Standby).
+ */
+bool isTsTsEnabled();
+
+/*
+ * Check if voice status is in emergency only.
+ */
+bool isVoiceEmergencyOnly(RegState state);
+
+/*
+ * Check if voice status is in service.
+ */
+bool isVoiceInService(RegState state);
+
+/*
+ * Check if service is valid for device configuration
+ */
+bool isServiceValidForDeviceConfiguration(std::string& serviceName);
+
+/**
+ * RadioServiceTest base class
+ */
+class RadioServiceTest {
+  protected:
+    std::mutex mtx_;
+    std::condition_variable cv_;
+    std::shared_ptr<config::IRadioConfig> radio_config;
+    std::shared_ptr<sim::IRadioSim> radio_sim;
+
+  public:
+    /* Used as a mechanism to inform the test about data/event callback */
+    void notify(int receivedSerial);
+
+    /* Test code calls this function to wait for response */
+    std::cv_status wait();
+
+    /* Get the radio HAL capabilities */
+    bool getRadioHalCapabilities();
+
+    /* Update SIM card status */
+    void updateSimCardStatus();
+};
diff --git a/radio/aidl/vts/radio_config_indication.cpp b/radio/aidl/vts/radio_config_indication.cpp
new file mode 100644
index 0000000..a84c20b
--- /dev/null
+++ b/radio/aidl/vts/radio_config_indication.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 "radio_config_utils.h"
+
+RadioConfigIndication::RadioConfigIndication(RadioServiceTest& parent) : parent_config(parent) {}
+
+ndk::ScopedAStatus RadioConfigIndication::simSlotsStatusChanged(
+        RadioIndicationType /*type*/, const std::vector<SimSlotStatus>& /*slotStatus*/) {
+    return ndk::ScopedAStatus::ok();
+}
diff --git a/radio/aidl/vts/radio_config_response.cpp b/radio/aidl/vts/radio_config_response.cpp
new file mode 100644
index 0000000..1a152fb
--- /dev/null
+++ b/radio/aidl/vts/radio_config_response.cpp
@@ -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.
+ */
+
+#include "radio_config_utils.h"
+
+RadioConfigResponse::RadioConfigResponse(RadioServiceTest& parent) : parent_config(parent) {}
+
+ndk::ScopedAStatus RadioConfigResponse::getSimSlotsStatusResponse(
+        const RadioResponseInfo& /* info */, const std::vector<SimSlotStatus>& /* slotStatus */) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioConfigResponse::setSimSlotsMappingResponse(
+        const RadioResponseInfo& /* info */) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioConfigResponse::getPhoneCapabilityResponse(
+        const RadioResponseInfo& info, const PhoneCapability& phoneCapability) {
+    rspInfo = info;
+    phoneCap = phoneCapability;
+    parent_config.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioConfigResponse::setPreferredDataModemResponse(
+        const RadioResponseInfo& /* info */) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioConfigResponse::getNumOfLiveModemsResponse(
+        const RadioResponseInfo& /* info */, const int8_t /* numOfLiveModems */) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioConfigResponse::setNumOfLiveModemsResponse(
+        const RadioResponseInfo& /* info */) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioConfigResponse::getHalDeviceCapabilitiesResponse(
+        const RadioResponseInfo& info, bool modemReducedFeatures) {
+    modemReducedFeatureSet1 = modemReducedFeatures;
+    parent_config.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
diff --git a/radio/aidl/vts/radio_config_test.cpp b/radio/aidl/vts/radio_config_test.cpp
new file mode 100644
index 0000000..2d7fe01
--- /dev/null
+++ b/radio/aidl/vts/radio_config_test.cpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+
+#include "radio_config_utils.h"
+
+#define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk())
+
+void RadioConfigTest::SetUp() {
+    std::string serviceName = GetParam();
+
+    if (!isServiceValidForDeviceConfiguration(serviceName)) {
+        ALOGI("Skipped the test due to device configuration.");
+        GTEST_SKIP();
+    }
+
+    radio_config = IRadioConfig::fromBinder(
+            ndk::SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
+    ASSERT_NE(nullptr, radio_config.get());
+
+    radioRsp_config = ndk::SharedRefBase::make<RadioConfigResponse>(*this);
+    ASSERT_NE(nullptr, radioRsp_config.get());
+
+    count_ = 0;
+
+    radioInd_config = ndk::SharedRefBase::make<RadioConfigIndication>(*this);
+    ASSERT_NE(nullptr, radioInd_config.get());
+
+    radio_config->setResponseFunctions(radioRsp_config, radioInd_config);
+}
+
+/*
+ * Test IRadioConfig.getHalDeviceCapabilities() for the response returned.
+ */
+TEST_P(RadioConfigTest, getHalDeviceCapabilities) {
+    serial = GetRandomSerialNumber();
+    ndk::ScopedAStatus res = radio_config->getHalDeviceCapabilities(serial);
+    ASSERT_OK(res);
+    ALOGI("getHalDeviceCapabilities, rspInfo.error = %s\n",
+          toString(radioRsp_config->rspInfo.error).c_str());
+}
diff --git a/radio/aidl/vts/radio_config_utils.h b/radio/aidl/vts/radio_config_utils.h
new file mode 100644
index 0000000..465c106
--- /dev/null
+++ b/radio/aidl/vts/radio_config_utils.h
@@ -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.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/radio/config/BnRadioConfigIndication.h>
+#include <aidl/android/hardware/radio/config/BnRadioConfigResponse.h>
+#include <aidl/android/hardware/radio/config/IRadioConfig.h>
+
+#include "radio_aidl_hal_utils.h"
+
+using namespace aidl::android::hardware::radio::config;
+
+class RadioConfigTest;
+
+/* Callback class for radio config response */
+class RadioConfigResponse : public BnRadioConfigResponse {
+  protected:
+    RadioServiceTest& parent_config;
+
+  public:
+    RadioConfigResponse(RadioServiceTest& parent_config);
+    virtual ~RadioConfigResponse() = default;
+
+    RadioResponseInfo rspInfo;
+    PhoneCapability phoneCap;
+    bool modemReducedFeatureSet1;
+
+    virtual ndk::ScopedAStatus getSimSlotsStatusResponse(
+            const RadioResponseInfo& info, const std::vector<SimSlotStatus>& slotStatus) override;
+
+    virtual ndk::ScopedAStatus setSimSlotsMappingResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus getPhoneCapabilityResponse(
+            const RadioResponseInfo& info, const PhoneCapability& phoneCapability) override;
+
+    virtual ndk::ScopedAStatus setPreferredDataModemResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus getNumOfLiveModemsResponse(const RadioResponseInfo& info,
+                                                          const int8_t numOfLiveModems) override;
+
+    virtual ndk::ScopedAStatus setNumOfLiveModemsResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus getHalDeviceCapabilitiesResponse(
+            const RadioResponseInfo& info, bool modemReducedFeatureSet1) override;
+};
+
+/* Callback class for radio config indication */
+class RadioConfigIndication : public BnRadioConfigIndication {
+  protected:
+    RadioServiceTest& parent_config;
+
+  public:
+    RadioConfigIndication(RadioServiceTest& parent_config);
+    virtual ~RadioConfigIndication() = default;
+
+    virtual ndk::ScopedAStatus simSlotsStatusChanged(
+            RadioIndicationType type, const std::vector<SimSlotStatus>& slotStatus) override;
+};
+
+// The main test class for Radio AIDL Config.
+class RadioConfigTest : public ::testing::TestWithParam<std::string>, public RadioServiceTest {
+  public:
+    virtual void SetUp() override;
+    ndk::ScopedAStatus updateSimCardStatus();
+
+    /* radio config service handle in RadioServiceTest */
+    /* radio config response handle */
+    std::shared_ptr<RadioConfigResponse> radioRsp_config;
+    /* radio config indication handle */
+    std::shared_ptr<RadioConfigIndication> radioInd_config;
+};
diff --git a/radio/aidl/vts/radio_data_indication.cpp b/radio/aidl/vts/radio_data_indication.cpp
new file mode 100644
index 0000000..4d3c539
--- /dev/null
+++ b/radio/aidl/vts/radio_data_indication.cpp
@@ -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.
+ */
+
+#include "radio_data_utils.h"
+
+RadioDataIndication::RadioDataIndication(RadioServiceTest& parent) : parent_data(parent) {}
+
+ndk::ScopedAStatus RadioDataIndication::dataCallListChanged(
+        RadioIndicationType /*type*/, const std::vector<SetupDataCallResult>& /*dcList*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioDataIndication::keepaliveStatus(RadioIndicationType /*type*/,
+                                                        const KeepaliveStatus& /*status*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioDataIndication::pcoData(RadioIndicationType /*type*/,
+                                                const PcoDataInfo& /*pco*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioDataIndication::unthrottleApn(RadioIndicationType /*type*/,
+                                                      const DataProfileInfo& /*dataProfileInfo*/) {
+    return ndk::ScopedAStatus::ok();
+}
diff --git a/radio/aidl/vts/radio_data_response.cpp b/radio/aidl/vts/radio_data_response.cpp
new file mode 100644
index 0000000..9b17bfb
--- /dev/null
+++ b/radio/aidl/vts/radio_data_response.cpp
@@ -0,0 +1,104 @@
+/*
+ * 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 "radio_data_utils.h"
+
+RadioDataResponse::RadioDataResponse(RadioServiceTest& parent) : parent_data(parent) {}
+
+ndk::ScopedAStatus RadioDataResponse::acknowledgeRequest(int32_t /*serial*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioDataResponse::allocatePduSessionIdResponse(const RadioResponseInfo& info,
+                                                                   int32_t id) {
+    rspInfo = info;
+    allocatedPduSessionId = id;
+    parent_data.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioDataResponse::cancelHandoverResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_data.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioDataResponse::deactivateDataCallResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioDataResponse::getDataCallListResponse(
+        const RadioResponseInfo& info, const std::vector<SetupDataCallResult>& /*dcResponse*/) {
+    rspInfo = info;
+    parent_data.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioDataResponse::getSlicingConfigResponse(
+        const RadioResponseInfo& info, const SlicingConfig& /*slicingConfig*/) {
+    rspInfo = info;
+    parent_data.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioDataResponse::releasePduSessionIdResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_data.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioDataResponse::setDataAllowedResponse(const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioDataResponse::setDataProfileResponse(const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioDataResponse::setDataThrottlingResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_data.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioDataResponse::setInitialAttachApnResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioDataResponse::setupDataCallResponse(const RadioResponseInfo& info,
+                                                            const SetupDataCallResult& dcResponse) {
+    rspInfo = info;
+    setupDataCallResult = dcResponse;
+    parent_data.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioDataResponse::startHandoverResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_data.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioDataResponse::startKeepaliveResponse(const RadioResponseInfo& /*info*/,
+                                                             const KeepaliveStatus& /*status*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioDataResponse::stopKeepaliveResponse(const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
diff --git a/radio/aidl/vts/radio_data_test.cpp b/radio/aidl/vts/radio_data_test.cpp
new file mode 100644
index 0000000..8547e9d
--- /dev/null
+++ b/radio/aidl/vts/radio_data_test.cpp
@@ -0,0 +1,311 @@
+/*
+ * 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/radio/RadioAccessFamily.h>
+#include <aidl/android/hardware/radio/config/IRadioConfig.h>
+#include <aidl/android/hardware/radio/data/ApnTypes.h>
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+
+#include "radio_data_utils.h"
+
+#define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk())
+
+void RadioDataTest::SetUp() {
+    std::string serviceName = GetParam();
+
+    if (!isServiceValidForDeviceConfiguration(serviceName)) {
+        ALOGI("Skipped the test due to device configuration.");
+        GTEST_SKIP();
+    }
+
+    radio_data = IRadioData::fromBinder(
+            ndk::SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
+    ASSERT_NE(nullptr, radio_data.get());
+
+    radioRsp_data = ndk::SharedRefBase::make<RadioDataResponse>(*this);
+    ASSERT_NE(nullptr, radioRsp_data.get());
+
+    count_ = 0;
+
+    radioInd_data = ndk::SharedRefBase::make<RadioDataIndication>(*this);
+    ASSERT_NE(nullptr, radioInd_data.get());
+
+    radio_data->setResponseFunctions(radioRsp_data, radioInd_data);
+
+    // Assert IRadioSim exists and SIM is present before testing
+    radio_sim = sim::IRadioSim::fromBinder(ndk::SpAIBinder(
+            AServiceManager_waitForService("android.hardware.radio.sim.IRadioSim/slot1")));
+    ASSERT_NE(nullptr, radio_sim.get());
+    updateSimCardStatus();
+    EXPECT_EQ(CardStatus::STATE_PRESENT, cardStatus.cardState);
+
+    // Assert IRadioConfig exists before testing
+    radio_config = config::IRadioConfig::fromBinder(ndk::SpAIBinder(
+            AServiceManager_waitForService("android.hardware.radio.config.IRadioConfig/default")));
+    ASSERT_NE(nullptr, radio_config.get());
+}
+
+ndk::ScopedAStatus RadioDataTest::getDataCallList() {
+    serial = GetRandomSerialNumber();
+    radio_data->getDataCallList(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    return ndk::ScopedAStatus::ok();
+}
+
+/*
+ * Test IRadioData.setupDataCall() for the response returned.
+ */
+TEST_P(RadioDataTest, setupDataCall) {
+    serial = GetRandomSerialNumber();
+
+    AccessNetwork accessNetwork = AccessNetwork::EUTRAN;
+
+    DataProfileInfo dataProfileInfo;
+    memset(&dataProfileInfo, 0, sizeof(dataProfileInfo));
+    dataProfileInfo.profileId = DataProfileInfo::ID_DEFAULT;
+    dataProfileInfo.apn = std::string("internet");
+    dataProfileInfo.protocol = PdpProtocolType::IP;
+    dataProfileInfo.roamingProtocol = PdpProtocolType::IP;
+    dataProfileInfo.authType = ApnAuthType::NO_PAP_NO_CHAP;
+    dataProfileInfo.user = std::string("username");
+    dataProfileInfo.password = std::string("password");
+    dataProfileInfo.type = DataProfileInfo::TYPE_THREE_GPP;
+    dataProfileInfo.maxConnsTime = 300;
+    dataProfileInfo.maxConns = 20;
+    dataProfileInfo.waitTime = 0;
+    dataProfileInfo.enabled = true;
+    dataProfileInfo.supportedApnTypesBitmap =
+            static_cast<int32_t>(ApnTypes::IMS) | static_cast<int32_t>(ApnTypes::IA);
+    dataProfileInfo.bearerBitmap = static_cast<int32_t>(RadioAccessFamily::GPRS) |
+                                   static_cast<int32_t>(RadioAccessFamily::EDGE) |
+                                   static_cast<int32_t>(RadioAccessFamily::UMTS) |
+                                   static_cast<int32_t>(RadioAccessFamily::HSDPA) |
+                                   static_cast<int32_t>(RadioAccessFamily::HSUPA) |
+                                   static_cast<int32_t>(RadioAccessFamily::HSPA) |
+                                   static_cast<int32_t>(RadioAccessFamily::EHRPD) |
+                                   static_cast<int32_t>(RadioAccessFamily::LTE) |
+                                   static_cast<int32_t>(RadioAccessFamily::HSPAP) |
+                                   static_cast<int32_t>(RadioAccessFamily::IWLAN);
+    dataProfileInfo.mtuV4 = 0;
+    dataProfileInfo.mtuV6 = 0;
+    dataProfileInfo.preferred = true;
+    dataProfileInfo.persistent = false;
+
+    bool roamingAllowed = false;
+
+    std::vector<LinkAddress> addresses = {};
+    std::vector<std::string> dnses = {};
+
+    DataRequestReason reason = DataRequestReason::NORMAL;
+    SliceInfo sliceInfo;
+    bool matchAllRuleAllowed = true;
+
+    ndk::ScopedAStatus res =
+            radio_data->setupDataCall(serial, accessNetwork, dataProfileInfo, roamingAllowed,
+                                      reason, addresses, dnses, -1, sliceInfo, matchAllRuleAllowed);
+    ASSERT_OK(res);
+
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_data->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_data->rspInfo.serial);
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_data->rspInfo.error,
+                                     {RadioError::SIM_ABSENT, RadioError::RADIO_NOT_AVAILABLE,
+                                      RadioError::OP_NOT_ALLOWED_BEFORE_REG_TO_NW}));
+    } else if (cardStatus.cardState == CardStatus::STATE_PRESENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_data->rspInfo.error,
+                                     {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
+                                      RadioError::OP_NOT_ALLOWED_BEFORE_REG_TO_NW}));
+    }
+}
+
+/*
+ * Test IRadioData.setupDataCall() with osAppId for the response returned.
+ */
+TEST_P(RadioDataTest, setupDataCall_osAppId) {
+    serial = GetRandomSerialNumber();
+
+    AccessNetwork accessNetwork = AccessNetwork::EUTRAN;
+
+    TrafficDescriptor trafficDescriptor;
+    OsAppId osAppId;
+    std::string osAppIdString("osAppId");
+    std::vector<unsigned char> osAppIdVec(osAppIdString.begin(), osAppIdString.end());
+    osAppId.osAppId = osAppIdVec;
+    trafficDescriptor.osAppId = osAppId;
+
+    DataProfileInfo dataProfileInfo;
+    memset(&dataProfileInfo, 0, sizeof(dataProfileInfo));
+    dataProfileInfo.profileId = DataProfileInfo::ID_DEFAULT;
+    dataProfileInfo.apn = std::string("internet");
+    dataProfileInfo.protocol = PdpProtocolType::IP;
+    dataProfileInfo.roamingProtocol = PdpProtocolType::IP;
+    dataProfileInfo.authType = ApnAuthType::NO_PAP_NO_CHAP;
+    dataProfileInfo.user = std::string("username");
+    dataProfileInfo.password = std::string("password");
+    dataProfileInfo.type = DataProfileInfo::TYPE_THREE_GPP;
+    dataProfileInfo.maxConnsTime = 300;
+    dataProfileInfo.maxConns = 20;
+    dataProfileInfo.waitTime = 0;
+    dataProfileInfo.enabled = true;
+    dataProfileInfo.supportedApnTypesBitmap =
+            static_cast<int32_t>(ApnTypes::IMS) | static_cast<int32_t>(ApnTypes::IA);
+    dataProfileInfo.bearerBitmap = static_cast<int32_t>(RadioAccessFamily::GPRS) |
+                                   static_cast<int32_t>(RadioAccessFamily::EDGE) |
+                                   static_cast<int32_t>(RadioAccessFamily::UMTS) |
+                                   static_cast<int32_t>(RadioAccessFamily::HSDPA) |
+                                   static_cast<int32_t>(RadioAccessFamily::HSUPA) |
+                                   static_cast<int32_t>(RadioAccessFamily::HSPA) |
+                                   static_cast<int32_t>(RadioAccessFamily::EHRPD) |
+                                   static_cast<int32_t>(RadioAccessFamily::LTE) |
+                                   static_cast<int32_t>(RadioAccessFamily::HSPAP) |
+                                   static_cast<int32_t>(RadioAccessFamily::IWLAN);
+    dataProfileInfo.mtuV4 = 0;
+    dataProfileInfo.mtuV6 = 0;
+    dataProfileInfo.preferred = true;
+    dataProfileInfo.persistent = false;
+    dataProfileInfo.trafficDescriptor = trafficDescriptor;
+
+    bool roamingAllowed = false;
+
+    std::vector<LinkAddress> addresses = {};
+    std::vector<std::string> dnses = {};
+
+    DataRequestReason reason = DataRequestReason::NORMAL;
+    SliceInfo sliceInfo;
+    bool matchAllRuleAllowed = true;
+
+    ndk::ScopedAStatus res =
+            radio_data->setupDataCall(serial, accessNetwork, dataProfileInfo, roamingAllowed,
+                                      reason, addresses, dnses, -1, sliceInfo, matchAllRuleAllowed);
+    ASSERT_OK(res);
+
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_data->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_data->rspInfo.serial);
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_data->rspInfo.error,
+                                     {RadioError::SIM_ABSENT, RadioError::RADIO_NOT_AVAILABLE,
+                                      RadioError::OP_NOT_ALLOWED_BEFORE_REG_TO_NW}));
+    } else if (cardStatus.cardState == CardStatus::STATE_PRESENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_data->rspInfo.error,
+                                     {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
+                                      RadioError::OP_NOT_ALLOWED_BEFORE_REG_TO_NW}));
+        if (radioRsp_data->setupDataCallResult.trafficDescriptors.size() <= 0) {
+            return;
+        }
+        EXPECT_EQ(trafficDescriptor.osAppId.value().osAppId,
+                  radioRsp_data->setupDataCallResult.trafficDescriptors[0].osAppId.value().osAppId);
+    }
+}
+
+/*
+ * Test IRadioData.getSlicingConfig() for the response returned.
+ */
+TEST_P(RadioDataTest, getSlicingConfig) {
+    serial = GetRandomSerialNumber();
+    radio_data->getSlicingConfig(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_data->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_data->rspInfo.serial);
+    if (getRadioHalCapabilities()) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_data->rspInfo.error,
+                                     {RadioError::REQUEST_NOT_SUPPORTED}));
+    } else {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_data->rspInfo.error,
+                                     {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
+                                      RadioError::INTERNAL_ERR, RadioError::MODEM_ERR}));
+    }
+}
+
+/*
+ * Test IRadioData.setDataThrottling() for the response returned.
+ */
+TEST_P(RadioDataTest, setDataThrottling) {
+    serial = GetRandomSerialNumber();
+
+    ndk::ScopedAStatus res = radio_data->setDataThrottling(
+            serial, DataThrottlingAction::THROTTLE_SECONDARY_CARRIER, 60000);
+    ASSERT_OK(res);
+
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_data->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_data->rspInfo.serial);
+    if (getRadioHalCapabilities()) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_data->rspInfo.error,
+                                     {RadioError::REQUEST_NOT_SUPPORTED, RadioError::NONE}));
+    } else {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_data->rspInfo.error,
+                                     {RadioError::RADIO_NOT_AVAILABLE, RadioError::MODEM_ERR,
+                                      RadioError::NONE, RadioError::INVALID_ARGUMENTS}));
+    }
+
+    sleep(1);
+    serial = GetRandomSerialNumber();
+
+    res = radio_data->setDataThrottling(serial, DataThrottlingAction::THROTTLE_ANCHOR_CARRIER,
+                                        60000);
+    ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_data->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_data->rspInfo.serial);
+    if (getRadioHalCapabilities()) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_data->rspInfo.error,
+                                     {RadioError::REQUEST_NOT_SUPPORTED, RadioError::NONE}));
+    } else {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_data->rspInfo.error,
+                                     {RadioError::RADIO_NOT_AVAILABLE, RadioError::MODEM_ERR,
+                                      RadioError::NONE, RadioError::INVALID_ARGUMENTS}));
+    }
+
+    sleep(1);
+    serial = GetRandomSerialNumber();
+
+    res = radio_data->setDataThrottling(serial, DataThrottlingAction::HOLD, 60000);
+    ASSERT_OK(res);
+
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_data->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_data->rspInfo.serial);
+    if (getRadioHalCapabilities()) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_data->rspInfo.error,
+                                     {RadioError::REQUEST_NOT_SUPPORTED, RadioError::NONE}));
+    } else {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_data->rspInfo.error,
+                                     {RadioError::RADIO_NOT_AVAILABLE, RadioError::MODEM_ERR,
+                                      RadioError::NONE, RadioError::INVALID_ARGUMENTS}));
+    }
+
+    sleep(1);
+    serial = GetRandomSerialNumber();
+
+    res = radio_data->setDataThrottling(serial, DataThrottlingAction::NO_DATA_THROTTLING, 60000);
+    ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_data->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_data->rspInfo.serial);
+    if (getRadioHalCapabilities()) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_data->rspInfo.error,
+                                     {RadioError::REQUEST_NOT_SUPPORTED, RadioError::NONE}));
+    } else {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_data->rspInfo.error,
+                                     {RadioError::RADIO_NOT_AVAILABLE, RadioError::MODEM_ERR,
+                                      RadioError::NONE, RadioError::INVALID_ARGUMENTS}));
+    }
+
+    sleep(1);
+}
diff --git a/radio/aidl/vts/radio_data_utils.h b/radio/aidl/vts/radio_data_utils.h
new file mode 100644
index 0000000..50c7878
--- /dev/null
+++ b/radio/aidl/vts/radio_data_utils.h
@@ -0,0 +1,115 @@
+/*
+ * 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/radio/data/BnRadioDataIndication.h>
+#include <aidl/android/hardware/radio/data/BnRadioDataResponse.h>
+#include <aidl/android/hardware/radio/data/IRadioData.h>
+
+#include "radio_aidl_hal_utils.h"
+
+using namespace aidl::android::hardware::radio::data;
+
+class RadioDataTest;
+
+/* Callback class for radio data response */
+class RadioDataResponse : public BnRadioDataResponse {
+  protected:
+    RadioServiceTest& parent_data;
+
+  public:
+    RadioDataResponse(RadioServiceTest& parent_data);
+    virtual ~RadioDataResponse() = default;
+
+    RadioResponseInfo rspInfo;
+    int32_t allocatedPduSessionId;
+    SetupDataCallResult setupDataCallResult;
+
+    virtual ndk::ScopedAStatus acknowledgeRequest(int32_t serial) override;
+
+    virtual ndk::ScopedAStatus allocatePduSessionIdResponse(const RadioResponseInfo& info,
+                                                            int32_t id) override;
+
+    virtual ndk::ScopedAStatus cancelHandoverResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus deactivateDataCallResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus getDataCallListResponse(
+            const RadioResponseInfo& info,
+            const std::vector<SetupDataCallResult>& dcResponse) override;
+
+    virtual ndk::ScopedAStatus getSlicingConfigResponse(
+            const RadioResponseInfo& info, const SlicingConfig& slicingConfig) override;
+
+    virtual ndk::ScopedAStatus releasePduSessionIdResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setDataAllowedResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setDataProfileResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setDataThrottlingResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setInitialAttachApnResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setupDataCallResponse(
+            const RadioResponseInfo& info, const SetupDataCallResult& dcResponse) override;
+
+    virtual ndk::ScopedAStatus startHandoverResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus startKeepaliveResponse(const RadioResponseInfo& info,
+                                                      const KeepaliveStatus& status) override;
+
+    virtual ndk::ScopedAStatus stopKeepaliveResponse(const RadioResponseInfo& info) override;
+};
+
+/* Callback class for radio data indication */
+class RadioDataIndication : public BnRadioDataIndication {
+  protected:
+    RadioServiceTest& parent_data;
+
+  public:
+    RadioDataIndication(RadioServiceTest& parent_data);
+    virtual ~RadioDataIndication() = default;
+
+    virtual ndk::ScopedAStatus dataCallListChanged(
+            RadioIndicationType type, const std::vector<SetupDataCallResult>& dcList) override;
+
+    virtual ndk::ScopedAStatus keepaliveStatus(RadioIndicationType type,
+                                               const KeepaliveStatus& status) override;
+
+    virtual ndk::ScopedAStatus pcoData(RadioIndicationType type, const PcoDataInfo& pco) override;
+
+    virtual ndk::ScopedAStatus unthrottleApn(RadioIndicationType type,
+                                             const DataProfileInfo& dataProfile) override;
+};
+
+// The main test class for Radio AIDL Data.
+class RadioDataTest : public ::testing::TestWithParam<std::string>, public RadioServiceTest {
+  protected:
+    /* Get current data call list */
+    ndk::ScopedAStatus getDataCallList();
+
+  public:
+    virtual void SetUp() override;
+
+    /* radio data service handle */
+    std::shared_ptr<IRadioData> radio_data;
+    /* radio data response handle */
+    std::shared_ptr<RadioDataResponse> radioRsp_data;
+    /* radio data indication handle */
+    std::shared_ptr<RadioDataIndication> radioInd_data;
+};
diff --git a/radio/aidl/vts/radio_messaging_indication.cpp b/radio/aidl/vts/radio_messaging_indication.cpp
new file mode 100644
index 0000000..c69611f
--- /dev/null
+++ b/radio/aidl/vts/radio_messaging_indication.cpp
@@ -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.
+ */
+
+#include "radio_messaging_utils.h"
+
+RadioMessagingIndication::RadioMessagingIndication(RadioServiceTest& parent)
+    : parent_messaging(parent) {}
+
+ndk::ScopedAStatus RadioMessagingIndication::cdmaNewSms(RadioIndicationType /*type*/,
+                                                        const CdmaSmsMessage& /*msg*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingIndication::cdmaRuimSmsStorageFull(RadioIndicationType /*type*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingIndication::newBroadcastSms(RadioIndicationType /*type*/,
+                                                             const std::vector<uint8_t>& /*data*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingIndication::newSms(RadioIndicationType /*type*/,
+                                                    const std::vector<uint8_t>& /*pdu*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingIndication::newSmsOnSim(RadioIndicationType /*type*/,
+                                                         int32_t /*recordNumber*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingIndication::newSmsStatusReport(
+        RadioIndicationType /*type*/, const std::vector<uint8_t>& /*pdu*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingIndication::onUssd(RadioIndicationType /*type*/,
+                                                    UssdModeType /*modeType*/,
+                                                    const std::string& /*msg*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingIndication::simSmsStorageFull(RadioIndicationType /*type*/) {
+    return ndk::ScopedAStatus::ok();
+}
diff --git a/radio/aidl/vts/radio_messaging_response.cpp b/radio/aidl/vts/radio_messaging_response.cpp
new file mode 100644
index 0000000..718df7e
--- /dev/null
+++ b/radio/aidl/vts/radio_messaging_response.cpp
@@ -0,0 +1,152 @@
+/*
+ * 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 "radio_messaging_utils.h"
+
+RadioMessagingResponse::RadioMessagingResponse(RadioServiceTest& parent)
+    : parent_messaging(parent) {}
+
+ndk::ScopedAStatus RadioMessagingResponse::acknowledgeIncomingGsmSmsWithPduResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingResponse::acknowledgeLastIncomingCdmaSmsResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingResponse::acknowledgeLastIncomingGsmSmsResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingResponse::acknowledgeRequest(int32_t /*serial*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingResponse::cancelPendingUssdResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingResponse::deleteSmsOnRuimResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingResponse::deleteSmsOnSimResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingResponse::getCdmaBroadcastConfigResponse(
+        const RadioResponseInfo& /*info*/,
+        const std::vector<CdmaBroadcastSmsConfigInfo>& /*configs*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingResponse::getGsmBroadcastConfigResponse(
+        const RadioResponseInfo& /*info*/,
+        const std::vector<GsmBroadcastSmsConfigInfo>& /*configs*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingResponse::getSmscAddressResponse(const RadioResponseInfo& /*info*/,
+                                                                  const std::string& /*smsc*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingResponse::reportSmsMemoryStatusResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingResponse::sendCdmaSmsExpectMoreResponse(
+        const RadioResponseInfo& info, const SendSmsResult& sms) {
+    rspInfo = info;
+    sendSmsResult = sms;
+    parent_messaging.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingResponse::sendCdmaSmsResponse(const RadioResponseInfo& info,
+                                                               const SendSmsResult& sms) {
+    rspInfo = info;
+    sendSmsResult = sms;
+    parent_messaging.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingResponse::sendImsSmsResponse(const RadioResponseInfo& /*info*/,
+                                                              const SendSmsResult& /*sms*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingResponse::sendSmsExpectMoreResponse(const RadioResponseInfo& info,
+                                                                     const SendSmsResult& sms) {
+    rspInfo = info;
+    sendSmsResult = sms;
+    parent_messaging.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingResponse::sendSmsResponse(const RadioResponseInfo& info,
+                                                           const SendSmsResult& sms) {
+    rspInfo = info;
+    sendSmsResult = sms;
+    parent_messaging.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingResponse::sendUssdResponse(const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingResponse::setCdmaBroadcastActivationResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingResponse::setCdmaBroadcastConfigResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingResponse::setGsmBroadcastActivationResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingResponse::setGsmBroadcastConfigResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingResponse::setSmscAddressResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingResponse::writeSmsToRuimResponse(const RadioResponseInfo& /*info*/,
+                                                                  int32_t /*index*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingResponse::writeSmsToSimResponse(const RadioResponseInfo& /*info*/,
+                                                                 int32_t /*index*/) {
+    return ndk::ScopedAStatus::ok();
+}
diff --git a/radio/aidl/vts/radio_messaging_test.cpp b/radio/aidl/vts/radio_messaging_test.cpp
new file mode 100644
index 0000000..8abd91d
--- /dev/null
+++ b/radio/aidl/vts/radio_messaging_test.cpp
@@ -0,0 +1,199 @@
+/*
+ * 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/radio/config/IRadioConfig.h>
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+
+#include "radio_messaging_utils.h"
+
+#define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk())
+
+void RadioMessagingTest::SetUp() {
+    std::string serviceName = GetParam();
+
+    if (!isServiceValidForDeviceConfiguration(serviceName)) {
+        ALOGI("Skipped the test due to device configuration.");
+        GTEST_SKIP();
+    }
+
+    radio_messaging = IRadioMessaging::fromBinder(
+            ndk::SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
+    ASSERT_NE(nullptr, radio_messaging.get());
+
+    radioRsp_messaging = ndk::SharedRefBase::make<RadioMessagingResponse>(*this);
+    ASSERT_NE(nullptr, radioRsp_messaging.get());
+
+    count_ = 0;
+
+    radioInd_messaging = ndk::SharedRefBase::make<RadioMessagingIndication>(*this);
+    ASSERT_NE(nullptr, radioInd_messaging.get());
+
+    radio_messaging->setResponseFunctions(radioRsp_messaging, radioInd_messaging);
+
+    // Assert IRadioSim exists and SIM is present before testing
+    radio_sim = sim::IRadioSim::fromBinder(ndk::SpAIBinder(
+            AServiceManager_waitForService("android.hardware.radio.sim.IRadioSim/slot1")));
+    ASSERT_NE(nullptr, radio_sim.get());
+    updateSimCardStatus();
+    EXPECT_EQ(CardStatus::STATE_PRESENT, cardStatus.cardState);
+
+    // Assert IRadioConfig exists before testing
+    radio_config = config::IRadioConfig::fromBinder(ndk::SpAIBinder(
+            AServiceManager_waitForService("android.hardware.radio.config.IRadioConfig/default")));
+    ASSERT_NE(nullptr, radio_config.get());
+}
+
+/*
+ * Test IRadioMessaging.sendSms() for the response returned.
+ */
+TEST_P(RadioMessagingTest, sendSms) {
+    LOG(DEBUG) << "sendSms";
+    serial = GetRandomSerialNumber();
+    GsmSmsMessage msg;
+    msg.smscPdu = "";
+    msg.pdu = "01000b916105770203f3000006d4f29c3e9b01";
+
+    radio_messaging->sendSms(serial, msg);
+
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_messaging->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_messaging->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(
+                radioRsp_messaging->rspInfo.error,
+                {RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE, RadioError::SIM_ABSENT},
+                CHECK_GENERAL_ERROR));
+        EXPECT_EQ(0, radioRsp_messaging->sendSmsResult.errorCode);
+    }
+    LOG(DEBUG) << "sendSms finished";
+}
+
+/*
+ * Test IRadioMessaging.sendSmsExpectMore() for the response returned.
+ */
+TEST_P(RadioMessagingTest, sendSmsExpectMore) {
+    LOG(DEBUG) << "sendSmsExpectMore";
+    serial = GetRandomSerialNumber();
+    GsmSmsMessage msg;
+    msg.smscPdu = "";
+    msg.pdu = "01000b916105770203f3000006d4f29c3e9b01";
+
+    radio_messaging->sendSmsExpectMore(serial, msg);
+
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_messaging->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_messaging->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(
+                radioRsp_messaging->rspInfo.error,
+                {RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE, RadioError::SIM_ABSENT},
+                CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "sendSmsExpectMore finished";
+}
+
+/*
+ * Test IRadioMessaging.sendCdmaSms() for the response returned.
+ */
+TEST_P(RadioMessagingTest, sendCdmaSms) {
+    LOG(DEBUG) << "sendCdmaSms";
+    serial = GetRandomSerialNumber();
+
+    // Create a CdmaSmsAddress
+    CdmaSmsAddress cdmaSmsAddress;
+    cdmaSmsAddress.digitMode = CdmaSmsAddress::DIGIT_MODE_FOUR_BIT;
+    cdmaSmsAddress.isNumberModeDataNetwork = false;
+    cdmaSmsAddress.numberType = CdmaSmsAddress::NUMBER_TYPE_UNKNOWN;
+    cdmaSmsAddress.numberPlan = CdmaSmsAddress::NUMBER_PLAN_UNKNOWN;
+    cdmaSmsAddress.digits = (std::vector<uint8_t>){11, 1, 6, 5, 10, 7, 7, 2, 10, 3, 10, 3};
+
+    // Create a CdmaSmsSubAddress
+    CdmaSmsSubaddress cdmaSmsSubaddress;
+    cdmaSmsSubaddress.subaddressType = CdmaSmsSubaddress::SUBADDRESS_TYPE_NSAP;
+    cdmaSmsSubaddress.odd = false;
+    cdmaSmsSubaddress.digits = (std::vector<uint8_t>){};
+
+    // Create a CdmaSmsMessage
+    CdmaSmsMessage cdmaSmsMessage;
+    cdmaSmsMessage.teleserviceId = 4098;
+    cdmaSmsMessage.isServicePresent = false;
+    cdmaSmsMessage.serviceCategory = 0;
+    cdmaSmsMessage.address = cdmaSmsAddress;
+    cdmaSmsMessage.subAddress = cdmaSmsSubaddress;
+    cdmaSmsMessage.bearerData =
+            (std::vector<uint8_t>){15, 0, 3, 32, 3, 16, 1, 8, 16, 53, 76, 68, 6, 51, 106, 0};
+
+    radio_messaging->sendCdmaSms(serial, cdmaSmsMessage);
+
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_messaging->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_messaging->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(
+                radioRsp_messaging->rspInfo.error,
+                {RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE, RadioError::SIM_ABSENT},
+                CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "sendCdmaSms finished";
+}
+
+/*
+ * Test IRadioMessaging.sendCdmaSmsExpectMore() for the response returned.
+ */
+TEST_P(RadioMessagingTest, sendCdmaSmsExpectMore) {
+    serial = GetRandomSerialNumber();
+
+    // Create a CdmaSmsAddress
+    CdmaSmsAddress cdmaSmsAddress;
+    cdmaSmsAddress.digitMode = CdmaSmsAddress::DIGIT_MODE_FOUR_BIT;
+    cdmaSmsAddress.isNumberModeDataNetwork = false;
+    cdmaSmsAddress.numberType = CdmaSmsAddress::NUMBER_TYPE_UNKNOWN;
+    cdmaSmsAddress.numberPlan = CdmaSmsAddress::NUMBER_PLAN_UNKNOWN;
+    cdmaSmsAddress.digits = (std::vector<uint8_t>){11, 1, 6, 5, 10, 7, 7, 2, 10, 3, 10, 3};
+
+    // Create a CdmaSmsSubAddress
+    CdmaSmsSubaddress cdmaSmsSubaddress;
+    cdmaSmsSubaddress.subaddressType = CdmaSmsSubaddress::SUBADDRESS_TYPE_NSAP;
+    cdmaSmsSubaddress.odd = false;
+    cdmaSmsSubaddress.digits = (std::vector<uint8_t>){};
+
+    // Create a CdmaSmsMessage
+    CdmaSmsMessage cdmaSmsMessage;
+    cdmaSmsMessage.teleserviceId = 4098;
+    cdmaSmsMessage.isServicePresent = false;
+    cdmaSmsMessage.serviceCategory = 0;
+    cdmaSmsMessage.address = cdmaSmsAddress;
+    cdmaSmsMessage.subAddress = cdmaSmsSubaddress;
+    cdmaSmsMessage.bearerData =
+            (std::vector<uint8_t>){15, 0, 3, 32, 3, 16, 1, 8, 16, 53, 76, 68, 6, 51, 106, 0};
+
+    radio_messaging->sendCdmaSmsExpectMore(serial, cdmaSmsMessage);
+
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_messaging->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_messaging->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(
+                radioRsp_messaging->rspInfo.error,
+                {RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE, RadioError::SIM_ABSENT},
+                CHECK_GENERAL_ERROR));
+    }
+}
diff --git a/radio/aidl/vts/radio_messaging_utils.h b/radio/aidl/vts/radio_messaging_utils.h
new file mode 100644
index 0000000..7bb99cd
--- /dev/null
+++ b/radio/aidl/vts/radio_messaging_utils.h
@@ -0,0 +1,152 @@
+/*
+ * 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/radio/messaging/BnRadioMessagingIndication.h>
+#include <aidl/android/hardware/radio/messaging/BnRadioMessagingResponse.h>
+#include <aidl/android/hardware/radio/messaging/IRadioMessaging.h>
+
+#include "radio_aidl_hal_utils.h"
+
+using namespace aidl::android::hardware::radio::messaging;
+
+class RadioMessagingTest;
+
+/* Callback class for radio messaging response */
+class RadioMessagingResponse : public BnRadioMessagingResponse {
+  protected:
+    RadioServiceTest& parent_messaging;
+
+  public:
+    RadioMessagingResponse(RadioServiceTest& parent_messaging);
+    virtual ~RadioMessagingResponse() = default;
+
+    RadioResponseInfo rspInfo;
+    SendSmsResult sendSmsResult;
+
+    virtual ndk::ScopedAStatus acknowledgeIncomingGsmSmsWithPduResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus acknowledgeLastIncomingCdmaSmsResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus acknowledgeLastIncomingGsmSmsResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus acknowledgeRequest(int32_t serial) override;
+
+    virtual ndk::ScopedAStatus cancelPendingUssdResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus deleteSmsOnRuimResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus deleteSmsOnSimResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus getCdmaBroadcastConfigResponse(
+            const RadioResponseInfo& info,
+            const std::vector<CdmaBroadcastSmsConfigInfo>& configs) override;
+
+    virtual ndk::ScopedAStatus getGsmBroadcastConfigResponse(
+            const RadioResponseInfo& info,
+            const std::vector<GsmBroadcastSmsConfigInfo>& configs) override;
+
+    virtual ndk::ScopedAStatus getSmscAddressResponse(const RadioResponseInfo& info,
+                                                      const std::string& smsc) override;
+
+    virtual ndk::ScopedAStatus reportSmsMemoryStatusResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus sendCdmaSmsExpectMoreResponse(const RadioResponseInfo& info,
+                                                             const SendSmsResult& sms) override;
+
+    virtual ndk::ScopedAStatus sendCdmaSmsResponse(const RadioResponseInfo& info,
+                                                   const SendSmsResult& sms) override;
+
+    virtual ndk::ScopedAStatus sendImsSmsResponse(const RadioResponseInfo& info,
+                                                  const SendSmsResult& sms) override;
+
+    virtual ndk::ScopedAStatus sendSmsExpectMoreResponse(const RadioResponseInfo& info,
+                                                         const SendSmsResult& sms) override;
+
+    virtual ndk::ScopedAStatus sendSmsResponse(const RadioResponseInfo& info,
+                                               const SendSmsResult& sms) override;
+
+    virtual ndk::ScopedAStatus sendUssdResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setCdmaBroadcastActivationResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setCdmaBroadcastConfigResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setGsmBroadcastActivationResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setGsmBroadcastConfigResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setSmscAddressResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus writeSmsToRuimResponse(const RadioResponseInfo& info,
+                                                      int32_t index) override;
+
+    virtual ndk::ScopedAStatus writeSmsToSimResponse(const RadioResponseInfo& info,
+                                                     int32_t index) override;
+};
+
+/* Callback class for radio messaging indication */
+class RadioMessagingIndication : public BnRadioMessagingIndication {
+  protected:
+    RadioServiceTest& parent_messaging;
+
+  public:
+    RadioMessagingIndication(RadioServiceTest& parent_messaging);
+    virtual ~RadioMessagingIndication() = default;
+
+    virtual ndk::ScopedAStatus cdmaNewSms(RadioIndicationType type,
+                                          const CdmaSmsMessage& msg) override;
+
+    virtual ndk::ScopedAStatus cdmaRuimSmsStorageFull(RadioIndicationType type) override;
+
+    virtual ndk::ScopedAStatus newBroadcastSms(RadioIndicationType type,
+                                               const std::vector<uint8_t>& data) override;
+
+    virtual ndk::ScopedAStatus newSms(RadioIndicationType type,
+                                      const std::vector<uint8_t>& pdu) override;
+
+    virtual ndk::ScopedAStatus newSmsOnSim(RadioIndicationType type, int32_t recordNumber) override;
+
+    virtual ndk::ScopedAStatus newSmsStatusReport(RadioIndicationType type,
+                                                  const std::vector<uint8_t>& pdu) override;
+
+    virtual ndk::ScopedAStatus onUssd(RadioIndicationType type, UssdModeType modeType,
+                                      const std::string& msg) override;
+
+    virtual ndk::ScopedAStatus simSmsStorageFull(RadioIndicationType type) override;
+};
+
+// The main test class for Radio AIDL Messaging.
+class RadioMessagingTest : public ::testing::TestWithParam<std::string>, public RadioServiceTest {
+  public:
+    virtual void SetUp() override;
+
+    /* radio messaging service handle */
+    std::shared_ptr<IRadioMessaging> radio_messaging;
+    /* radio messaging response handle */
+    std::shared_ptr<RadioMessagingResponse> radioRsp_messaging;
+    /* radio messaging indication handle */
+    std::shared_ptr<RadioMessagingIndication> radioInd_messaging;
+};
diff --git a/radio/aidl/vts/radio_modem_indication.cpp b/radio/aidl/vts/radio_modem_indication.cpp
new file mode 100644
index 0000000..0bfcd66
--- /dev/null
+++ b/radio/aidl/vts/radio_modem_indication.cpp
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "radio_modem_utils.h"
+
+RadioModemIndication::RadioModemIndication(RadioServiceTest& parent) : parent_modem(parent) {}
+
+ndk::ScopedAStatus RadioModemIndication::hardwareConfigChanged(
+        RadioIndicationType /*type*/, const std::vector<HardwareConfig>& /*configs*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioModemIndication::modemReset(RadioIndicationType /*type*/,
+                                                    const std::string& /*reason*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioModemIndication::radioCapabilityIndication(RadioIndicationType /*type*/,
+                                                                   const RadioCapability& /*rc*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioModemIndication::radioStateChanged(RadioIndicationType /*type*/,
+                                                           RadioState /*radioState*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioModemIndication::rilConnected(RadioIndicationType /*type*/) {
+    return ndk::ScopedAStatus::ok();
+}
diff --git a/radio/aidl/vts/radio_modem_response.cpp b/radio/aidl/vts/radio_modem_response.cpp
new file mode 100644
index 0000000..53bfab4
--- /dev/null
+++ b/radio/aidl/vts/radio_modem_response.cpp
@@ -0,0 +1,96 @@
+/*
+ * 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 "radio_modem_utils.h"
+
+RadioModemResponse::RadioModemResponse(RadioServiceTest& parent) : parent_modem(parent) {}
+
+ndk::ScopedAStatus RadioModemResponse::acknowledgeRequest(int32_t /*serial*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioModemResponse::enableModemResponse(const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioModemResponse::getBasebandVersionResponse(const RadioResponseInfo& /*info*/,
+                                                                  const std::string& /*version*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioModemResponse::getDeviceIdentityResponse(const RadioResponseInfo& /*info*/,
+                                                                 const std::string& /*imei*/,
+                                                                 const std::string& /*imeisv*/,
+                                                                 const std::string& /*esn*/,
+                                                                 const std::string& /*meid*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioModemResponse::getHardwareConfigResponse(
+        const RadioResponseInfo& /*info*/, const std::vector<HardwareConfig>& /*config*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioModemResponse::getModemActivityInfoResponse(
+        const RadioResponseInfo& /*info*/, const ActivityStatsInfo& /*activityInfo*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioModemResponse::getModemStackStatusResponse(
+        const RadioResponseInfo& /*info*/, const bool /*enabled*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioModemResponse::getRadioCapabilityResponse(const RadioResponseInfo& /*info*/,
+                                                                  const RadioCapability& /*rc*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioModemResponse::nvReadItemResponse(const RadioResponseInfo& /*info*/,
+                                                          const std::string& /*result*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioModemResponse::nvResetConfigResponse(const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioModemResponse::nvWriteCdmaPrlResponse(const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioModemResponse::nvWriteItemResponse(const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioModemResponse::requestShutdownResponse(const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioModemResponse::sendDeviceStateResponse(const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioModemResponse::setRadioCapabilityResponse(const RadioResponseInfo& /*info*/,
+                                                                  const RadioCapability& /*rc*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioModemResponse::setRadioPowerResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_modem.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
diff --git a/radio/aidl/vts/radio_modem_test.cpp b/radio/aidl/vts/radio_modem_test.cpp
new file mode 100644
index 0000000..b40bb7b
--- /dev/null
+++ b/radio/aidl/vts/radio_modem_test.cpp
@@ -0,0 +1,89 @@
+/*
+ * 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/radio/config/IRadioConfig.h>
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+
+#include "radio_modem_utils.h"
+
+#define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk())
+
+void RadioModemTest::SetUp() {
+    std::string serviceName = GetParam();
+
+    if (!isServiceValidForDeviceConfiguration(serviceName)) {
+        ALOGI("Skipped the test due to device configuration.");
+        GTEST_SKIP();
+    }
+
+    radio_modem = IRadioModem::fromBinder(
+            ndk::SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
+    ASSERT_NE(nullptr, radio_modem.get());
+
+    radioRsp_modem = ndk::SharedRefBase::make<RadioModemResponse>(*this);
+    ASSERT_NE(nullptr, radioRsp_modem.get());
+
+    count_ = 0;
+
+    radioInd_modem = ndk::SharedRefBase::make<RadioModemIndication>(*this);
+    ASSERT_NE(nullptr, radioInd_modem.get());
+
+    radio_modem->setResponseFunctions(radioRsp_modem, radioInd_modem);
+
+    // Assert IRadioSim exists and SIM is present before testing
+    radio_sim = sim::IRadioSim::fromBinder(ndk::SpAIBinder(
+            AServiceManager_waitForService("android.hardware.radio.sim.IRadioSim/slot1")));
+    ASSERT_NE(nullptr, radio_sim.get());
+    updateSimCardStatus();
+    EXPECT_EQ(CardStatus::STATE_PRESENT, cardStatus.cardState);
+
+    // Assert IRadioConfig exists before testing
+    radio_config = config::IRadioConfig::fromBinder(ndk::SpAIBinder(
+            AServiceManager_waitForService("android.hardware.radio.config.IRadioConfig/default")));
+    ASSERT_NE(nullptr, radio_config.get());
+}
+
+/*
+ * Test IRadioModem.setRadioPower() for the response returned.
+ */
+TEST_P(RadioModemTest, setRadioPower_emergencyCall_cancelled) {
+    // Set radio power to off.
+    serial = GetRandomSerialNumber();
+    radio_modem->setRadioPower(serial, false, false, false);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_modem->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_modem->rspInfo.serial);
+    EXPECT_EQ(RadioError::NONE, radioRsp_modem->rspInfo.error);
+
+    // Set radio power to on with forEmergencyCall being true. This should put modem to only scan
+    // emergency call bands.
+    serial = GetRandomSerialNumber();
+    radio_modem->setRadioPower(serial, true, true, true);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_modem->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_modem->rspInfo.serial);
+    EXPECT_EQ(RadioError::NONE, radioRsp_modem->rspInfo.error);
+
+    // Set radio power to on with forEmergencyCall being false. This should put modem in regular
+    // operation modem.
+    serial = GetRandomSerialNumber();
+    radio_modem->setRadioPower(serial, true, false, false);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_modem->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_modem->rspInfo.serial);
+    EXPECT_EQ(RadioError::NONE, radioRsp_modem->rspInfo.error);
+}
diff --git a/radio/aidl/vts/radio_modem_utils.h b/radio/aidl/vts/radio_modem_utils.h
new file mode 100644
index 0000000..8779e0c
--- /dev/null
+++ b/radio/aidl/vts/radio_modem_utils.h
@@ -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.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/radio/modem/BnRadioModemIndication.h>
+#include <aidl/android/hardware/radio/modem/BnRadioModemResponse.h>
+#include <aidl/android/hardware/radio/modem/IRadioModem.h>
+
+#include "radio_aidl_hal_utils.h"
+
+using namespace aidl::android::hardware::radio::modem;
+
+class RadioModemTest;
+
+/* Callback class for radio modem response */
+class RadioModemResponse : public BnRadioModemResponse {
+  protected:
+    RadioServiceTest& parent_modem;
+
+  public:
+    RadioModemResponse(RadioServiceTest& parent_modem);
+    virtual ~RadioModemResponse() = default;
+
+    RadioResponseInfo rspInfo;
+    bool isModemEnabled;
+    bool enableModemResponseToggle;
+
+    virtual ndk::ScopedAStatus acknowledgeRequest(int32_t serial) override;
+
+    virtual ndk::ScopedAStatus enableModemResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus getBasebandVersionResponse(const RadioResponseInfo& info,
+                                                          const std::string& version) override;
+
+    virtual ndk::ScopedAStatus getDeviceIdentityResponse(const RadioResponseInfo& info,
+                                                         const std::string& imei,
+                                                         const std::string& imeisv,
+                                                         const std::string& esn,
+                                                         const std::string& meid) override;
+
+    virtual ndk::ScopedAStatus getHardwareConfigResponse(
+            const RadioResponseInfo& info, const std::vector<HardwareConfig>& config) override;
+
+    virtual ndk::ScopedAStatus getModemActivityInfoResponse(
+            const RadioResponseInfo& info, const ActivityStatsInfo& activityInfo) override;
+
+    virtual ndk::ScopedAStatus getModemStackStatusResponse(const RadioResponseInfo& info,
+                                                           const bool enabled) override;
+
+    virtual ndk::ScopedAStatus getRadioCapabilityResponse(const RadioResponseInfo& info,
+                                                          const RadioCapability& rc) override;
+
+    virtual ndk::ScopedAStatus nvReadItemResponse(const RadioResponseInfo& info,
+                                                  const std::string& result) override;
+
+    virtual ndk::ScopedAStatus nvResetConfigResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus nvWriteCdmaPrlResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus nvWriteItemResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus requestShutdownResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus sendDeviceStateResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setRadioCapabilityResponse(const RadioResponseInfo& info,
+                                                          const RadioCapability& rc) override;
+
+    virtual ndk::ScopedAStatus setRadioPowerResponse(const RadioResponseInfo& info) override;
+};
+
+/* Callback class for radio modem indication */
+class RadioModemIndication : public BnRadioModemIndication {
+  protected:
+    RadioServiceTest& parent_modem;
+
+  public:
+    RadioModemIndication(RadioServiceTest& parent_modem);
+    virtual ~RadioModemIndication() = default;
+
+    virtual ndk::ScopedAStatus hardwareConfigChanged(
+            RadioIndicationType type, const std::vector<HardwareConfig>& configs) override;
+
+    virtual ndk::ScopedAStatus modemReset(RadioIndicationType type,
+                                          const std::string& reason) override;
+
+    virtual ndk::ScopedAStatus radioCapabilityIndication(RadioIndicationType type,
+                                                         const RadioCapability& rc) override;
+
+    virtual ndk::ScopedAStatus radioStateChanged(RadioIndicationType type,
+                                                 RadioState radioState) override;
+
+    virtual ndk::ScopedAStatus rilConnected(RadioIndicationType type) override;
+};
+
+// The main test class for Radio AIDL Modem.
+class RadioModemTest : public ::testing::TestWithParam<std::string>, public RadioServiceTest {
+  public:
+    virtual void SetUp() override;
+
+    /* radio modem service handle */
+    std::shared_ptr<IRadioModem> radio_modem;
+    /* radio modem response handle */
+    std::shared_ptr<RadioModemResponse> radioRsp_modem;
+    /* radio modem indication handle */
+    std::shared_ptr<RadioModemIndication> radioInd_modem;
+};
diff --git a/radio/aidl/vts/radio_network_indication.cpp b/radio/aidl/vts/radio_network_indication.cpp
new file mode 100644
index 0000000..7acbff4
--- /dev/null
+++ b/radio/aidl/vts/radio_network_indication.cpp
@@ -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.
+ */
+
+#include "radio_network_utils.h"
+
+RadioNetworkIndication::RadioNetworkIndication(RadioServiceTest& parent) : parent_network(parent) {}
+
+ndk::ScopedAStatus RadioNetworkIndication::barringInfoChanged(
+        RadioIndicationType /*type*/, const CellIdentity& /*cellIdentity*/,
+        const std::vector<BarringInfo>& /*barringInfos*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkIndication::cdmaPrlChanged(RadioIndicationType /*type*/,
+                                                          int32_t /*version*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkIndication::cellInfoList(RadioIndicationType /*type*/,
+                                                        const std::vector<CellInfo>& /*records*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkIndication::currentLinkCapacityEstimate(
+        RadioIndicationType /*type*/, const LinkCapacityEstimate& /*lce*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkIndication::currentPhysicalChannelConfigs(
+        RadioIndicationType /*type*/, const std::vector<PhysicalChannelConfig>& /*configs*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkIndication::currentSignalStrength(
+        RadioIndicationType /*type*/, const SignalStrength& /*signalStrength*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkIndication::imsNetworkStateChanged(RadioIndicationType /*type*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkIndication::networkScanResult(RadioIndicationType /*type*/,
+                                                             const NetworkScanResult& /*result*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkIndication::networkStateChanged(RadioIndicationType /*type*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkIndication::nitzTimeReceived(RadioIndicationType /*type*/,
+                                                            const std::string& /*nitzTime*/,
+                                                            int64_t /*receivedTime*/,
+                                                            int64_t /*age*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkIndication::registrationFailed(RadioIndicationType /*type*/,
+                                                              const CellIdentity& /*cellIdentity*/,
+                                                              const std::string& /*chosenPlmn*/,
+                                                              int32_t /*domain*/,
+                                                              int32_t /*causeCode*/,
+                                                              int32_t /*additionalCauseCode*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkIndication::restrictedStateChanged(RadioIndicationType /*type*/,
+                                                                  PhoneRestrictedState /*state*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkIndication::suppSvcNotify(RadioIndicationType /*type*/,
+                                                         const SuppSvcNotification& /*suppSvc*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkIndication::voiceRadioTechChanged(RadioIndicationType /*type*/,
+                                                                 RadioTechnology /*rat*/) {
+    return ndk::ScopedAStatus::ok();
+}
diff --git a/radio/aidl/vts/radio_network_response.cpp b/radio/aidl/vts/radio_network_response.cpp
new file mode 100644
index 0000000..ccae0f3
--- /dev/null
+++ b/radio/aidl/vts/radio_network_response.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 "radio_network_utils.h"
+
+RadioNetworkResponse::RadioNetworkResponse(RadioServiceTest& parent) : parent_network(parent) {}
+
+ndk::ScopedAStatus RadioNetworkResponse::acknowledgeRequest(int32_t /*serial*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::getAllowedNetworkTypesBitmapResponse(
+        const RadioResponseInfo& info, const int32_t networkTypeBitmap) {
+    rspInfo = info;
+    networkTypeBitmapResponse = networkTypeBitmap;
+    parent_network.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::getAvailableBandModesResponse(
+        const RadioResponseInfo& /*info*/, const std::vector<RadioBandMode>& /*bandModes*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::getAvailableNetworksResponse(
+        const RadioResponseInfo& info, const std::vector<OperatorInfo>& operatorInfos) {
+    rspInfo = info;
+    networkInfos = operatorInfos;
+    parent_network.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::getBarringInfoResponse(
+        const RadioResponseInfo& /*info*/, const CellIdentity& /*cellIdentity*/,
+        const std::vector<BarringInfo>& /*barringInfos*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::getCdmaRoamingPreferenceResponse(
+        const RadioResponseInfo& /*info*/, CdmaRoamingType /*type*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::getCellInfoListResponse(
+        const RadioResponseInfo& /*info*/, const std::vector<CellInfo>& /*cellInfo*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::getDataRegistrationStateResponse(
+        const RadioResponseInfo& info, const RegStateResult& /*regResponse*/) {
+    rspInfo = info;
+    parent_network.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::getImsRegistrationStateResponse(
+        const RadioResponseInfo& /*info*/, bool /*isRegistered*/,
+        RadioTechnologyFamily /*ratFamily*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::getNetworkSelectionModeResponse(
+        const RadioResponseInfo& /*info*/, bool /*manual*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::getOperatorResponse(const RadioResponseInfo& /*info*/,
+                                                             const std::string& /*longName*/,
+                                                             const std::string& /*shortName*/,
+                                                             const std::string& /*numeric*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::getSignalStrengthResponse(
+        const RadioResponseInfo& /*info*/, const SignalStrength& /*sig_strength*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::getSystemSelectionChannelsResponse(
+        const RadioResponseInfo& info, const std::vector<RadioAccessSpecifier>& /*specifier*/) {
+    rspInfo = info;
+    parent_network.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::getUsageSettingResponse(const RadioResponseInfo& info,
+                                                                 const UsageSetting usageSetting) {
+    rspInfo = info;
+    this->usageSetting = usageSetting;
+    parent_network.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::getVoiceRadioTechnologyResponse(
+        const RadioResponseInfo& /*info*/, RadioTechnology /*rat*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::getVoiceRegistrationStateResponse(
+        const RadioResponseInfo& info, const RegStateResult& regResponse) {
+    rspInfo = info;
+    voiceRegResp.regState = regResponse.regState;
+    parent_network.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::isNrDualConnectivityEnabledResponse(
+        const RadioResponseInfo& info, bool isEnabled) {
+    rspInfo = info;
+    isNrDualConnectivityEnabled = isEnabled;
+    parent_network.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::setAllowedNetworkTypesBitmapResponse(
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_network.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::setBandModeResponse(const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::setBarringPasswordResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::setCdmaRoamingPreferenceResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::setCellInfoListRateResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::setIndicationFilterResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::setLinkCapacityReportingCriteriaResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::setLocationUpdatesResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::setNetworkSelectionModeAutomaticResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::setNetworkSelectionModeManualResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::setNrDualConnectivityStateResponse(
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_network.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::setSignalStrengthReportingCriteriaResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::setSuppServiceNotificationsResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::setSystemSelectionChannelsResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::setUsageSettingResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_network.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::startNetworkScanResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::stopNetworkScanResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::supplyNetworkDepersonalizationResponse(
+        const RadioResponseInfo& /*info*/, int32_t /*remainingRetries*/) {
+    return ndk::ScopedAStatus::ok();
+}
diff --git a/radio/aidl/vts/radio_network_test.cpp b/radio/aidl/vts/radio_network_test.cpp
new file mode 100644
index 0000000..93c4c35
--- /dev/null
+++ b/radio/aidl/vts/radio_network_test.cpp
@@ -0,0 +1,265 @@
+/*
+ * 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/radio/RadioAccessFamily.h>
+#include <aidl/android/hardware/radio/config/IRadioConfig.h>
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+
+#include "radio_network_utils.h"
+
+#define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk())
+
+void RadioNetworkTest::SetUp() {
+    std::string serviceName = GetParam();
+
+    if (!isServiceValidForDeviceConfiguration(serviceName)) {
+        ALOGI("Skipped the test due to device configuration.");
+        GTEST_SKIP();
+    }
+
+    radio_network = IRadioNetwork::fromBinder(
+            ndk::SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
+    ASSERT_NE(nullptr, radio_network.get());
+
+    radioRsp_network = ndk::SharedRefBase::make<RadioNetworkResponse>(*this);
+    ASSERT_NE(nullptr, radioRsp_network.get());
+
+    count_ = 0;
+
+    radioInd_network = ndk::SharedRefBase::make<RadioNetworkIndication>(*this);
+    ASSERT_NE(nullptr, radioInd_network.get());
+
+    radio_network->setResponseFunctions(radioRsp_network, radioInd_network);
+
+    // Assert IRadioSim exists and SIM is present before testing
+    radio_sim = sim::IRadioSim::fromBinder(ndk::SpAIBinder(
+            AServiceManager_waitForService("android.hardware.radio.sim.IRadioSim/slot1")));
+    ASSERT_NE(nullptr, radio_sim.get());
+    updateSimCardStatus();
+    EXPECT_EQ(CardStatus::STATE_PRESENT, cardStatus.cardState);
+
+    // Assert IRadioConfig exists before testing
+    radio_config = config::IRadioConfig::fromBinder(ndk::SpAIBinder(
+            AServiceManager_waitForService("android.hardware.radio.config.IRadioConfig/default")));
+    ASSERT_NE(nullptr, radio_config.get());
+}
+
+/*
+ * Test IRadioNetwork.setAllowedNetworkTypesBitmap for the response returned.
+ */
+TEST_P(RadioNetworkTest, setAllowedNetworkTypesBitmap) {
+    serial = GetRandomSerialNumber();
+    int32_t allowedNetworkTypesBitmap = static_cast<int32_t>(RadioAccessFamily::LTE);
+
+    radio_network->setAllowedNetworkTypesBitmap(serial, allowedNetworkTypesBitmap);
+
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+    ASSERT_TRUE(CheckAnyOfErrors(
+            radioRsp_network->rspInfo.error,
+            {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::OPERATION_NOT_ALLOWED,
+             RadioError::MODE_NOT_SUPPORTED, RadioError::INTERNAL_ERR, RadioError::MODEM_ERR,
+             RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED,
+             RadioError::NO_RESOURCES}));
+}
+
+/*
+ * Test IRadioNetwork.getAllowedNetworkTypesBitmap for the response returned.
+ */
+TEST_P(RadioNetworkTest, getAllowedNetworkTypesBitmap) {
+    serial = GetRandomSerialNumber();
+    int32_t allowedNetworkTypesBitmap = static_cast<int32_t>(RadioAccessFamily::LTE);
+
+    radio_network->setAllowedNetworkTypesBitmap(serial, allowedNetworkTypesBitmap);
+
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+    if (radioRsp_network->rspInfo.error == RadioError::NONE) {
+        sleep(3);  // wait for modem
+        serial = GetRandomSerialNumber();
+        radio_network->getAllowedNetworkTypesBitmap(serial);
+
+        EXPECT_EQ(std::cv_status::no_timeout, wait());
+        EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+        EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+        ASSERT_TRUE(CheckAnyOfErrors(
+                radioRsp_network->rspInfo.error,
+                {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::INTERNAL_ERR,
+                 RadioError::OPERATION_NOT_ALLOWED, RadioError::MODE_NOT_SUPPORTED,
+                 RadioError::INVALID_ARGUMENTS, RadioError::MODEM_ERR,
+                 RadioError::REQUEST_NOT_SUPPORTED, RadioError::NO_RESOURCES}));
+    }
+}
+
+/*
+ * Test IRadioNetwork.setNrDualConnectivityState() for the response returned.
+ */
+TEST_P(RadioNetworkTest, setNrDualConnectivityState) {
+    serial = GetRandomSerialNumber();
+
+    ndk::ScopedAStatus res =
+            radio_network->setNrDualConnectivityState(serial, NrDualConnectivityState::DISABLE);
+    ASSERT_OK(res);
+
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+    if (getRadioHalCapabilities()) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                                     {RadioError::REQUEST_NOT_SUPPORTED}));
+    } else {
+        ASSERT_TRUE(CheckAnyOfErrors(
+                radioRsp_network->rspInfo.error,
+                {RadioError::RADIO_NOT_AVAILABLE, RadioError::INTERNAL_ERR,
+                 RadioError::INVALID_STATE, RadioError::REQUEST_NOT_SUPPORTED, RadioError::NONE}));
+    }
+}
+
+/*
+ * Test IRadioNetwork.isNrDualConnectivityEnabled() for the response returned.
+ */
+TEST_P(RadioNetworkTest, isNrDualConnectivityEnabled) {
+    serial = GetRandomSerialNumber();
+
+    ndk::ScopedAStatus res = radio_network->isNrDualConnectivityEnabled(serial);
+    ASSERT_OK(res);
+
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+    if (getRadioHalCapabilities()) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                                     {RadioError::REQUEST_NOT_SUPPORTED}));
+    } else {
+        ASSERT_TRUE(CheckAnyOfErrors(
+                radioRsp_network->rspInfo.error,
+                {RadioError::RADIO_NOT_AVAILABLE, RadioError::INTERNAL_ERR, RadioError::NONE}));
+    }
+}
+
+void RadioNetworkTest::invokeAndExpectResponse(
+        std::function<ndk::ScopedAStatus(int32_t serial)> request,
+        std::vector<RadioError> errors_to_check) {
+    serial = GetRandomSerialNumber();
+
+    ndk::ScopedAStatus res = request(serial);
+    ASSERT_OK(res);
+
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, errors_to_check));
+}
+
+/*
+ * Test IRadioNetwork.getUsageSetting()
+ *
+ * Verify that the usage setting can be retrieved.
+ */
+TEST_P(RadioNetworkTest, getUsageSetting) {
+    invokeAndExpectResponse([&](int serial) { return radio_network->getUsageSetting(serial); },
+                            {RadioError::RADIO_NOT_AVAILABLE, RadioError::INVALID_STATE,
+                             RadioError::SIM_ABSENT, RadioError::INTERNAL_ERR, RadioError::NONE});
+
+    ASSERT_TRUE(radioRsp_network->usageSetting == UsageSetting::VOICE_CENTRIC ||
+                radioRsp_network->usageSetting == UsageSetting::DATA_CENTRIC);
+}
+
+void RadioNetworkTest::testSetUsageSetting_InvalidValues(std::vector<RadioError> errors) {
+    invokeAndExpectResponse(
+            [&](int serial) {
+                return radio_network->setUsageSetting(serial,
+                                                      UsageSetting(0) /*below valid range*/);
+            },
+            errors);
+    invokeAndExpectResponse(
+            [&](int serial) {
+                return radio_network->setUsageSetting(serial, UsageSetting(-1) /*negative*/);
+            },
+            errors);
+    invokeAndExpectResponse(
+            [&](int serial) {
+                return radio_network->setUsageSetting(serial,
+                                                      UsageSetting(3) /*above valid range*/);
+            },
+            errors);
+}
+
+/*
+ * Test IRadioNetwork.setUsageSetting() and IRadioNetwork.getUsageSetting()
+ *
+ * Verify the following:
+ * -That the usage setting can be retrieved.
+ * -That the usage setting can be successfully set to allowed values.
+ * -That the usage setting cannot be set to invalid values.
+ */
+TEST_P(RadioNetworkTest, setUsageSetting) {
+    invokeAndExpectResponse([&](int serial) { return radio_network->getUsageSetting(serial); },
+                            {RadioError::RADIO_NOT_AVAILABLE, RadioError::INVALID_STATE,
+                             RadioError::SIM_ABSENT, RadioError::INTERNAL_ERR, RadioError::NONE});
+
+    if (radioRsp_network->rspInfo.error != RadioError::NONE) {
+        // Test only for invalid values, with the only allowable response being the same error
+        // that was previously provided, or an error indicating invalid arguments.
+        testSetUsageSetting_InvalidValues(
+                {radioRsp_network->rspInfo.error, RadioError::INVALID_ARGUMENTS});
+        // It is unsafe to proceed with setting valid values without knowing the starting value, but
+        // we expect errors anyway, so not necessary.
+        return;
+    } else {
+        // Because querying succeeded, the device is in a valid state to test for invalid values
+        // and the only thing that can change is that we expect to have an EINVAL return each time.
+        testSetUsageSetting_InvalidValues({RadioError::INVALID_ARGUMENTS});
+    }
+
+    // Store the original setting value to reset later.
+    const UsageSetting originalSetting = radioRsp_network->usageSetting;
+
+    // Choose the "other" value that is not the current value for test.
+    const UsageSetting testSetting = radioRsp_network->usageSetting == UsageSetting::VOICE_CENTRIC
+                                             ? UsageSetting::DATA_CENTRIC
+                                             : UsageSetting::VOICE_CENTRIC;
+
+    // Set an alternative setting; it may either succeed or be disallowed as out of range for
+    // the current device (if the device only supports its current mode).
+    invokeAndExpectResponse(
+            [&](int serial) { return radio_network->setUsageSetting(serial, testSetting); },
+            {RadioError::INVALID_ARGUMENTS, RadioError::NONE});
+
+    // If there was no error, then we expect the test setting to be set, or if there is an error
+    // we expect the original setting to be maintained.
+    const UsageSetting expectedSetting =
+            radioRsp_network->rspInfo.error == RadioError::NONE ? testSetting : originalSetting;
+    invokeAndExpectResponse([&](int serial) { return radio_network->getUsageSetting(serial); },
+                            {RadioError::NONE});
+
+    const UsageSetting updatedSetting = radioRsp_network->usageSetting;
+
+    // Re-set the original setting, which must always succeed.
+    invokeAndExpectResponse(
+            [&](int serial) { return radio_network->setUsageSetting(serial, originalSetting); },
+            {RadioError::NONE});
+
+    // Check that indeed the updated setting was set. We do this after resetting to original
+    // conditions to avoid early-exiting the test and leaving the device in a modified state.
+    ASSERT_TRUE(expectedSetting == updatedSetting);
+    // Check that indeed the original setting was reset.
+    ASSERT_TRUE(originalSetting == radioRsp_network->usageSetting);
+}
diff --git a/radio/aidl/vts/radio_network_utils.h b/radio/aidl/vts/radio_network_utils.h
new file mode 100644
index 0000000..9f76769
--- /dev/null
+++ b/radio/aidl/vts/radio_network_utils.h
@@ -0,0 +1,221 @@
+/*
+ * 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/radio/network/BnRadioNetworkIndication.h>
+#include <aidl/android/hardware/radio/network/BnRadioNetworkResponse.h>
+#include <aidl/android/hardware/radio/network/IRadioNetwork.h>
+
+#include "radio_aidl_hal_utils.h"
+
+using namespace aidl::android::hardware::radio::network;
+
+class RadioNetworkTest;
+
+/* Callback class for radio network response */
+class RadioNetworkResponse : public BnRadioNetworkResponse {
+  protected:
+    RadioServiceTest& parent_network;
+
+  public:
+    RadioNetworkResponse(RadioServiceTest& parent_network);
+    virtual ~RadioNetworkResponse() = default;
+
+    RadioResponseInfo rspInfo;
+    std::vector<RadioBandMode> radioBandModes;
+    std::vector<OperatorInfo> networkInfos;
+    bool isNrDualConnectivityEnabled;
+    int networkTypeBitmapResponse;
+    RegStateResult voiceRegResp;
+    CellIdentity barringCellIdentity;
+    std::vector<BarringInfo> barringInfos;
+    UsageSetting usageSetting;
+
+    virtual ndk::ScopedAStatus acknowledgeRequest(int32_t serial) override;
+
+    virtual ndk::ScopedAStatus getAllowedNetworkTypesBitmapResponse(
+            const RadioResponseInfo& info, const int32_t networkTypeBitmap) override;
+
+    virtual ndk::ScopedAStatus getAvailableBandModesResponse(
+            const RadioResponseInfo& info, const std::vector<RadioBandMode>& bandModes) override;
+
+    virtual ndk::ScopedAStatus getAvailableNetworksResponse(
+            const RadioResponseInfo& info, const std::vector<OperatorInfo>& networkInfos) override;
+
+    virtual ndk::ScopedAStatus getBarringInfoResponse(
+            const RadioResponseInfo& info, const CellIdentity& cellIdentity,
+            const std::vector<BarringInfo>& barringInfos) override;
+
+    virtual ndk::ScopedAStatus getCdmaRoamingPreferenceResponse(const RadioResponseInfo& info,
+                                                                CdmaRoamingType type) override;
+
+    virtual ndk::ScopedAStatus getCellInfoListResponse(
+            const RadioResponseInfo& info, const std::vector<CellInfo>& cellInfo) override;
+
+    virtual ndk::ScopedAStatus getDataRegistrationStateResponse(
+            const RadioResponseInfo& info, const RegStateResult& dataRegResponse) override;
+
+    virtual ndk::ScopedAStatus getImsRegistrationStateResponse(
+            const RadioResponseInfo& info, bool isRegistered,
+            RadioTechnologyFamily ratFamily) override;
+
+    virtual ndk::ScopedAStatus getNetworkSelectionModeResponse(const RadioResponseInfo& info,
+                                                               bool manual) override;
+
+    virtual ndk::ScopedAStatus getOperatorResponse(const RadioResponseInfo& info,
+                                                   const std::string& longName,
+                                                   const std::string& shortName,
+                                                   const std::string& numeric) override;
+
+    virtual ndk::ScopedAStatus getSignalStrengthResponse(
+            const RadioResponseInfo& info, const SignalStrength& sigStrength) override;
+
+    virtual ndk::ScopedAStatus getSystemSelectionChannelsResponse(
+            const RadioResponseInfo& info,
+            const std::vector<RadioAccessSpecifier>& specifier) override;
+
+    virtual ndk::ScopedAStatus getUsageSettingResponse(const RadioResponseInfo& info,
+                                                       UsageSetting usageSetting) override;
+
+    virtual ndk::ScopedAStatus getVoiceRadioTechnologyResponse(const RadioResponseInfo& info,
+                                                               RadioTechnology rat) override;
+
+    virtual ndk::ScopedAStatus getVoiceRegistrationStateResponse(
+            const RadioResponseInfo& info, const RegStateResult& voiceRegResponse) override;
+
+    virtual ndk::ScopedAStatus isNrDualConnectivityEnabledResponse(const RadioResponseInfo& info,
+                                                                   bool isEnabled) override;
+
+    virtual ndk::ScopedAStatus setAllowedNetworkTypesBitmapResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setBandModeResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setBarringPasswordResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setCdmaRoamingPreferenceResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setCellInfoListRateResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setIndicationFilterResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setLinkCapacityReportingCriteriaResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setLocationUpdatesResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setNetworkSelectionModeAutomaticResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setNetworkSelectionModeManualResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setNrDualConnectivityStateResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setSignalStrengthReportingCriteriaResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setSuppServiceNotificationsResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setSystemSelectionChannelsResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setUsageSettingResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus startNetworkScanResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus stopNetworkScanResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus supplyNetworkDepersonalizationResponse(
+            const RadioResponseInfo& info, int32_t remainingRetries) override;
+};
+
+/* Callback class for radio network indication */
+class RadioNetworkIndication : public BnRadioNetworkIndication {
+  protected:
+    RadioServiceTest& parent_network;
+
+  public:
+    RadioNetworkIndication(RadioServiceTest& parent_network);
+    virtual ~RadioNetworkIndication() = default;
+
+    virtual ndk::ScopedAStatus barringInfoChanged(
+            RadioIndicationType type, const CellIdentity& cellIdentity,
+            const std::vector<BarringInfo>& barringInfos) override;
+
+    virtual ndk::ScopedAStatus cdmaPrlChanged(RadioIndicationType type, int32_t version) override;
+
+    virtual ndk::ScopedAStatus cellInfoList(RadioIndicationType type,
+                                            const std::vector<CellInfo>& records) override;
+
+    virtual ndk::ScopedAStatus currentLinkCapacityEstimate(
+            RadioIndicationType type, const LinkCapacityEstimate& lce) override;
+
+    virtual ndk::ScopedAStatus currentPhysicalChannelConfigs(
+            RadioIndicationType type, const std::vector<PhysicalChannelConfig>& configs) override;
+
+    virtual ndk::ScopedAStatus currentSignalStrength(RadioIndicationType type,
+                                                     const SignalStrength& signalStrength) override;
+
+    virtual ndk::ScopedAStatus imsNetworkStateChanged(RadioIndicationType type) override;
+
+    virtual ndk::ScopedAStatus networkScanResult(RadioIndicationType type,
+                                                 const NetworkScanResult& result) override;
+
+    virtual ndk::ScopedAStatus networkStateChanged(RadioIndicationType type) override;
+
+    virtual ndk::ScopedAStatus nitzTimeReceived(RadioIndicationType type,
+                                                const std::string& nitzTime, int64_t receivedTimeMs,
+                                                int64_t ageMs) override;
+
+    virtual ndk::ScopedAStatus registrationFailed(RadioIndicationType type,
+                                                  const CellIdentity& cellIdentity,
+                                                  const std::string& chosenPlmn, int32_t domain,
+                                                  int32_t causeCode,
+                                                  int32_t additionalCauseCode) override;
+
+    virtual ndk::ScopedAStatus restrictedStateChanged(RadioIndicationType type,
+                                                      PhoneRestrictedState state) override;
+
+    virtual ndk::ScopedAStatus suppSvcNotify(RadioIndicationType type,
+                                             const SuppSvcNotification& suppSvc) override;
+
+    virtual ndk::ScopedAStatus voiceRadioTechChanged(RadioIndicationType type,
+                                                     RadioTechnology rat) override;
+};
+
+// The main test class for Radio AIDL Network.
+class RadioNetworkTest : public ::testing::TestWithParam<std::string>, public RadioServiceTest {
+  public:
+    virtual void SetUp() override;
+
+    /* radio network service handle */
+    std::shared_ptr<IRadioNetwork> radio_network;
+    /* radio network response handle */
+    std::shared_ptr<RadioNetworkResponse> radioRsp_network;
+    /* radio network indication handle */
+    std::shared_ptr<RadioNetworkIndication> radioInd_network;
+
+    void invokeAndExpectResponse(std::function<ndk::ScopedAStatus(int32_t serial)> request,
+                                 std::vector<RadioError> errors_to_check);
+
+    // Helper function to reduce copy+paste
+    void testSetUsageSetting_InvalidValues(std::vector<RadioError> errors);
+};
diff --git a/radio/aidl/vts/radio_sim_indication.cpp b/radio/aidl/vts/radio_sim_indication.cpp
new file mode 100644
index 0000000..c03d947
--- /dev/null
+++ b/radio/aidl/vts/radio_sim_indication.cpp
@@ -0,0 +1,71 @@
+/*
+ * 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 "radio_sim_utils.h"
+
+RadioSimIndication::RadioSimIndication(RadioServiceTest& parent) : parent_sim(parent) {}
+
+ndk::ScopedAStatus RadioSimIndication::carrierInfoForImsiEncryption(RadioIndicationType /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimIndication::cdmaSubscriptionSourceChanged(
+        RadioIndicationType /*type*/, CdmaSubscriptionSource /*cdmaSource*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimIndication::simPhonebookChanged(RadioIndicationType /*type*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimIndication::simPhonebookRecordsReceived(
+        RadioIndicationType /*type*/, PbReceivedStatus /*status*/,
+        const std::vector<PhonebookRecordInfo>& /*records*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimIndication::simRefresh(RadioIndicationType /*type*/,
+                                                  const SimRefreshResult& /*refreshResult*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimIndication::simStatusChanged(RadioIndicationType /*type*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimIndication::stkEventNotify(RadioIndicationType /*type*/,
+                                                      const std::string& /*cmd*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimIndication::stkProactiveCommand(RadioIndicationType /*type*/,
+                                                           const std::string& /*cmd*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimIndication::stkSessionEnd(RadioIndicationType /*type*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimIndication::subscriptionStatusChanged(RadioIndicationType /*type*/,
+                                                                 bool /*activate*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimIndication::uiccApplicationsEnablementChanged(
+        RadioIndicationType /*type*/, bool /*enabled*/) {
+    return ndk::ScopedAStatus::ok();
+}
diff --git a/radio/aidl/vts/radio_sim_response.cpp b/radio/aidl/vts/radio_sim_response.cpp
new file mode 100644
index 0000000..a783f43
--- /dev/null
+++ b/radio/aidl/vts/radio_sim_response.cpp
@@ -0,0 +1,209 @@
+/*
+ * 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 "radio_sim_utils.h"
+
+RadioSimResponse::RadioSimResponse(RadioServiceTest& parent) : parent_sim(parent) {}
+
+ndk::ScopedAStatus RadioSimResponse::acknowledgeRequest(int32_t /*serial*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::areUiccApplicationsEnabledResponse(
+        const RadioResponseInfo& /*info*/, bool /*enabled*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::changeIccPin2ForAppResponse(const RadioResponseInfo& /*info*/,
+                                                                 int32_t /*remainingRetries*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::changeIccPinForAppResponse(const RadioResponseInfo& /*info*/,
+                                                                int32_t /*remainingRetries*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::enableUiccApplicationsResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::getAllowedCarriersResponse(
+        const RadioResponseInfo& /*info*/, const CarrierRestrictions& /*carriers*/,
+        SimLockMultiSimPolicy /*multiSimPolicy*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::getCdmaSubscriptionResponse(
+        const RadioResponseInfo& /*info*/, const std::string& /*mdn*/, const std::string& /*hSid*/,
+        const std::string& /*hNid*/, const std::string& /*min*/, const std::string& /*prl*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::getCdmaSubscriptionSourceResponse(
+        const RadioResponseInfo& /*info*/, CdmaSubscriptionSource /*source*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::getFacilityLockForAppResponse(
+        const RadioResponseInfo& /*info*/, int32_t /*response*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::getIccCardStatusResponse(const RadioResponseInfo& info,
+                                                              const CardStatus& card_status) {
+    rspInfo = info;
+    cardStatus = card_status;
+    parent_sim.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::getImsiForAppResponse(const RadioResponseInfo& /*info*/,
+                                                           const std::string& /*imsi*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::getSimPhonebookCapacityResponse(
+        const RadioResponseInfo& info, const PhonebookCapacity& pbCapacity) {
+    rspInfo = info;
+    capacity = pbCapacity;
+    parent_sim.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::getSimPhonebookRecordsResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_sim.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::iccCloseLogicalChannelResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::iccIoForAppResponse(const RadioResponseInfo& /*info*/,
+                                                         const IccIoResult& /*iccIo*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::iccOpenLogicalChannelResponse(
+        const RadioResponseInfo& /*info*/, int32_t /*channelId*/,
+        const std::vector<uint8_t>& /*selectResponse*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::iccTransmitApduBasicChannelResponse(
+        const RadioResponseInfo& /*info*/, const IccIoResult& /*result*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::iccTransmitApduLogicalChannelResponse(
+        const RadioResponseInfo& /*info*/, const IccIoResult& /*result*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::reportStkServiceIsRunningResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::requestIccSimAuthenticationResponse(
+        const RadioResponseInfo& /*info*/, const IccIoResult& /*result*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::sendEnvelopeResponse(const RadioResponseInfo& /*info*/,
+                                                          const std::string& /*commandResponse*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::sendEnvelopeWithStatusResponse(
+        const RadioResponseInfo& /*info*/, const IccIoResult& /*iccIo*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::sendTerminalResponseToSimResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::setAllowedCarriersResponse(const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::setCarrierInfoForImsiEncryptionResponse(
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_sim.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::setCdmaSubscriptionSourceResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::setFacilityLockForAppResponse(
+        const RadioResponseInfo& /*info*/, int32_t /*retry*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::setSimCardPowerResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_sim.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::setUiccSubscriptionResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::supplyIccPin2ForAppResponse(const RadioResponseInfo& /*info*/,
+                                                                 int32_t /*remainingRetries*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::supplyIccPinForAppResponse(const RadioResponseInfo& /*info*/,
+                                                                int32_t /*remainingRetries*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::supplyIccPuk2ForAppResponse(const RadioResponseInfo& /*info*/,
+                                                                 int32_t /*remainingRetries*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::supplyIccPukForAppResponse(const RadioResponseInfo& /*info*/,
+                                                                int32_t /*remainingRetries*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::supplySimDepersonalizationResponse(
+        const RadioResponseInfo& /*info*/, PersoSubstate /*persoType*/,
+        int32_t /*remainingRetries*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::updateSimPhonebookRecordsResponse(
+        const RadioResponseInfo& info, int32_t recordIndex) {
+    rspInfo = info;
+    updatedRecordIndex = recordIndex;
+    parent_sim.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
diff --git a/radio/aidl/vts/radio_sim_test.cpp b/radio/aidl/vts/radio_sim_test.cpp
new file mode 100644
index 0000000..5db77f6
--- /dev/null
+++ b/radio/aidl/vts/radio_sim_test.cpp
@@ -0,0 +1,262 @@
+/*
+ * 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/radio/config/IRadioConfig.h>
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+
+#include "radio_sim_utils.h"
+
+#define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk())
+
+void RadioSimTest::SetUp() {
+    std::string serviceName = GetParam();
+
+    if (!isServiceValidForDeviceConfiguration(serviceName)) {
+        ALOGI("Skipped the test due to device configuration.");
+        GTEST_SKIP();
+    }
+
+    radio_sim = IRadioSim::fromBinder(
+            ndk::SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
+    ASSERT_NE(nullptr, radio_sim.get());
+
+    radioRsp_sim = ndk::SharedRefBase::make<RadioSimResponse>(*this);
+    ASSERT_NE(nullptr, radioRsp_sim.get());
+
+    count_ = 0;
+
+    radioInd_sim = ndk::SharedRefBase::make<RadioSimIndication>(*this);
+    ASSERT_NE(nullptr, radioInd_sim.get());
+
+    radio_sim->setResponseFunctions(radioRsp_sim, radioInd_sim);
+    // Assert SIM is present before testing
+    updateSimCardStatus();
+    EXPECT_EQ(CardStatus::STATE_PRESENT, cardStatus.cardState);
+
+    // Assert IRadioConfig exists before testing
+    radio_config = config::IRadioConfig::fromBinder(ndk::SpAIBinder(
+            AServiceManager_waitForService("android.hardware.radio.config.IRadioConfig/default")));
+    ASSERT_NE(nullptr, radio_config.get());
+}
+
+void RadioSimTest::updateSimCardStatus() {
+    serial = GetRandomSerialNumber();
+    radio_sim->getIccCardStatus(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+    EXPECT_EQ(RadioError::NONE, radioRsp_sim->rspInfo.error);
+}
+
+/*
+ * Test IRadioSim.setSimCardPower() for the response returned.
+ */
+TEST_P(RadioSimTest, setSimCardPower) {
+    /* Test setSimCardPower power down */
+    serial = GetRandomSerialNumber();
+    radio_sim->setSimCardPower(serial, CardPowerState::POWER_DOWN);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_sim->rspInfo.error,
+                                 {RadioError::NONE, RadioError::INVALID_ARGUMENTS,
+                                  RadioError::RADIO_NOT_AVAILABLE, RadioError::SIM_ERR}));
+
+    // setSimCardPower does not return  until the request is handled, and should not trigger
+    // CardStatus::STATE_ABSENT when turning off power
+    if (radioRsp_sim->rspInfo.error == RadioError::NONE) {
+        /* Wait some time for setting sim power down and then verify it */
+        updateSimCardStatus();
+        // We cannot assert the consistency of CardState here due to b/203031664
+        // EXPECT_EQ(CardStatus::STATE_PRESENT, cardStatus.cardState);
+        // applications should be an empty vector of AppStatus
+        EXPECT_EQ(0, cardStatus.applications.size());
+    }
+
+    // Give some time for modem to fully power down the SIM card
+    sleep(MODEM_SET_SIM_POWER_DELAY_IN_SECONDS);
+
+    /* Test setSimCardPower power up */
+    serial = GetRandomSerialNumber();
+    radio_sim->setSimCardPower(serial, CardPowerState::POWER_UP);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_sim->rspInfo.error,
+                                 {RadioError::NONE, RadioError::INVALID_ARGUMENTS,
+                                  RadioError::RADIO_NOT_AVAILABLE, RadioError::SIM_ERR}));
+
+    // Give some time for modem to fully power up the SIM card
+    sleep(MODEM_SET_SIM_POWER_DELAY_IN_SECONDS);
+
+    // setSimCardPower does not return  until the request is handled. Just verify that we still
+    // have CardStatus::STATE_PRESENT after turning the power back on
+    if (radioRsp_sim->rspInfo.error == RadioError::NONE) {
+        updateSimCardStatus();
+        EXPECT_EQ(CardStatus::STATE_PRESENT, cardStatus.cardState);
+    }
+}
+
+/*
+ * Test IRadioSim.setCarrierInfoForImsiEncryption() for the response returned.
+ */
+TEST_P(RadioSimTest, setCarrierInfoForImsiEncryption) {
+    serial = GetRandomSerialNumber();
+    ImsiEncryptionInfo imsiInfo;
+    imsiInfo.mcc = "310";
+    imsiInfo.mnc = "004";
+    imsiInfo.carrierKey = (std::vector<uint8_t>){1, 2, 3, 4, 5, 6};
+    imsiInfo.keyIdentifier = "Test";
+    imsiInfo.expirationTime = 20180101;
+    imsiInfo.keyType = ImsiEncryptionInfo::PUBLIC_KEY_TYPE_EPDG;
+
+    radio_sim->setCarrierInfoForImsiEncryption(serial, imsiInfo);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_sim->rspInfo.error,
+                                     {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
+    }
+}
+
+/*
+ * Test IRadioSim.getSimPhonebookRecords() for the response returned.
+ */
+TEST_P(RadioSimTest, getSimPhonebookRecords) {
+    serial = GetRandomSerialNumber();
+    radio_sim->getSimPhonebookRecords(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(
+                CheckAnyOfErrors(radioRsp_sim->rspInfo.error,
+                                 {RadioError::INVALID_SIM_STATE, RadioError::RADIO_NOT_AVAILABLE,
+                                  RadioError::MODEM_ERR, RadioError::INVALID_ARGUMENTS,
+                                  RadioError::REQUEST_NOT_SUPPORTED},
+                                 CHECK_GENERAL_ERROR));
+    } else if (cardStatus.cardState == CardStatus::STATE_PRESENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_sim->rspInfo.error,
+                                     {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED},
+                                     CHECK_GENERAL_ERROR));
+    }
+}
+
+/*
+ * Test IRadioSim.getSimPhonebookCapacity for the response returned.
+ */
+TEST_P(RadioSimTest, getSimPhonebookCapacity) {
+    serial = GetRandomSerialNumber();
+    radio_sim->getSimPhonebookCapacity(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(
+                CheckAnyOfErrors(radioRsp_sim->rspInfo.error,
+                                 {RadioError::INVALID_SIM_STATE, RadioError::RADIO_NOT_AVAILABLE,
+                                  RadioError::MODEM_ERR, RadioError::INVALID_ARGUMENTS,
+                                  RadioError::REQUEST_NOT_SUPPORTED},
+                                 CHECK_GENERAL_ERROR));
+    } else if (cardStatus.cardState == CardStatus::STATE_PRESENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_sim->rspInfo.error,
+                                     {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED},
+                                     CHECK_GENERAL_ERROR));
+
+        PhonebookCapacity pbCapacity = radioRsp_sim->capacity;
+        if (pbCapacity.maxAdnRecords > 0) {
+            EXPECT_TRUE(pbCapacity.maxNameLen > 0 && pbCapacity.maxNumberLen > 0);
+            EXPECT_TRUE(pbCapacity.usedAdnRecords <= pbCapacity.maxAdnRecords);
+        }
+
+        if (pbCapacity.maxEmailRecords > 0) {
+            EXPECT_TRUE(pbCapacity.maxEmailLen > 0);
+            EXPECT_TRUE(pbCapacity.usedEmailRecords <= pbCapacity.maxEmailRecords);
+        }
+
+        if (pbCapacity.maxAdditionalNumberRecords > 0) {
+            EXPECT_TRUE(pbCapacity.maxAdditionalNumberLen > 0);
+            EXPECT_TRUE(pbCapacity.usedAdditionalNumberRecords <=
+                        pbCapacity.maxAdditionalNumberRecords);
+        }
+    }
+}
+
+/*
+ * Test IRadioSim.updateSimPhonebookRecords() for the response returned.
+ */
+TEST_P(RadioSimTest, updateSimPhonebookRecords) {
+    serial = GetRandomSerialNumber();
+    radio_sim->getSimPhonebookCapacity(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(
+                CheckAnyOfErrors(radioRsp_sim->rspInfo.error,
+                                 {RadioError::INVALID_SIM_STATE, RadioError::RADIO_NOT_AVAILABLE,
+                                  RadioError::MODEM_ERR, RadioError::INVALID_ARGUMENTS,
+                                  RadioError::REQUEST_NOT_SUPPORTED},
+                                 CHECK_GENERAL_ERROR));
+    } else if (cardStatus.cardState == CardStatus::STATE_PRESENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_sim->rspInfo.error,
+                                     {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED},
+                                     CHECK_GENERAL_ERROR));
+        PhonebookCapacity pbCapacity = radioRsp_sim->capacity;
+
+        serial = GetRandomSerialNumber();
+        radio_sim->getSimPhonebookRecords(serial);
+
+        EXPECT_EQ(std::cv_status::no_timeout, wait());
+        EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+        EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_sim->rspInfo.error,
+                                     {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED},
+                                     CHECK_GENERAL_ERROR));
+
+        if (pbCapacity.maxAdnRecords > 0 && pbCapacity.usedAdnRecords < pbCapacity.maxAdnRecords) {
+            // Add a phonebook record
+            PhonebookRecordInfo recordInfo;
+            recordInfo.recordId = 0;
+            recordInfo.name = "ABC";
+            recordInfo.number = "1234567890";
+            serial = GetRandomSerialNumber();
+            radio_sim->updateSimPhonebookRecords(serial, recordInfo);
+
+            EXPECT_EQ(std::cv_status::no_timeout, wait());
+            EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+            EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+            EXPECT_EQ(RadioError::NONE, radioRsp_sim->rspInfo.error);
+            int index = radioRsp_sim->updatedRecordIndex;
+            EXPECT_TRUE(index > 0);
+
+            // Deleted a phonebook record
+            recordInfo.recordId = index;
+            recordInfo.name = "";
+            recordInfo.number = "";
+            serial = GetRandomSerialNumber();
+            radio_sim->updateSimPhonebookRecords(serial, recordInfo);
+
+            EXPECT_EQ(std::cv_status::no_timeout, wait());
+            EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+            EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+            EXPECT_EQ(RadioError::NONE, radioRsp_sim->rspInfo.error);
+        }
+    }
+}
diff --git a/radio/aidl/vts/radio_sim_utils.h b/radio/aidl/vts/radio_sim_utils.h
new file mode 100644
index 0000000..b5e365d
--- /dev/null
+++ b/radio/aidl/vts/radio_sim_utils.h
@@ -0,0 +1,205 @@
+/*
+ * 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/radio/sim/BnRadioSimIndication.h>
+#include <aidl/android/hardware/radio/sim/BnRadioSimResponse.h>
+#include <aidl/android/hardware/radio/sim/IRadioSim.h>
+
+#include "radio_aidl_hal_utils.h"
+
+using namespace aidl::android::hardware::radio::sim;
+
+class RadioSimTest;
+
+/* Callback class for radio SIM response */
+class RadioSimResponse : public BnRadioSimResponse {
+  protected:
+    RadioServiceTest& parent_sim;
+
+  public:
+    RadioSimResponse(RadioServiceTest& parent_sim);
+    virtual ~RadioSimResponse() = default;
+
+    RadioResponseInfo rspInfo;
+    CarrierRestrictions carrierRestrictionsResp;
+    SimLockMultiSimPolicy multiSimPolicyResp;
+    bool canToggleUiccApplicationsEnablement;
+    bool areUiccApplicationsEnabled;
+    PhonebookCapacity capacity;
+    int32_t updatedRecordIndex;
+
+    virtual ndk::ScopedAStatus acknowledgeRequest(int32_t serial) override;
+
+    virtual ndk::ScopedAStatus areUiccApplicationsEnabledResponse(const RadioResponseInfo& info,
+                                                                  bool enabled) override;
+
+    virtual ndk::ScopedAStatus changeIccPin2ForAppResponse(const RadioResponseInfo& info,
+                                                           int32_t remainingRetries) override;
+
+    virtual ndk::ScopedAStatus changeIccPinForAppResponse(const RadioResponseInfo& info,
+                                                          int32_t remainingRetries) override;
+
+    virtual ndk::ScopedAStatus enableUiccApplicationsResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus getAllowedCarriersResponse(
+            const RadioResponseInfo& info, const CarrierRestrictions& carriers,
+            const SimLockMultiSimPolicy multiSimPolicy) override;
+
+    virtual ndk::ScopedAStatus getCdmaSubscriptionResponse(
+            const RadioResponseInfo& info, const std::string& mdn, const std::string& hSid,
+            const std::string& hNid, const std::string& min, const std::string& prl) override;
+
+    virtual ndk::ScopedAStatus getCdmaSubscriptionSourceResponse(
+            const RadioResponseInfo& info, CdmaSubscriptionSource source) override;
+
+    virtual ndk::ScopedAStatus getFacilityLockForAppResponse(const RadioResponseInfo& info,
+                                                             int32_t response) override;
+
+    virtual ndk::ScopedAStatus getIccCardStatusResponse(const RadioResponseInfo& info,
+                                                        const CardStatus& cardStatus) override;
+
+    virtual ndk::ScopedAStatus getImsiForAppResponse(const RadioResponseInfo& info,
+                                                     const std::string& imsi) override;
+
+    virtual ndk::ScopedAStatus getSimPhonebookCapacityResponse(
+            const RadioResponseInfo& info, const PhonebookCapacity& capacity) override;
+
+    virtual ndk::ScopedAStatus getSimPhonebookRecordsResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus iccCloseLogicalChannelResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus iccIoForAppResponse(const RadioResponseInfo& info,
+                                                   const IccIoResult& iccIo) override;
+
+    virtual ndk::ScopedAStatus iccOpenLogicalChannelResponse(
+            const RadioResponseInfo& info, int32_t channelId,
+            const std::vector<uint8_t>& selectResponse) override;
+
+    virtual ndk::ScopedAStatus iccTransmitApduBasicChannelResponse(
+            const RadioResponseInfo& info, const IccIoResult& result) override;
+
+    virtual ndk::ScopedAStatus iccTransmitApduLogicalChannelResponse(
+            const RadioResponseInfo& info, const IccIoResult& result) override;
+
+    virtual ndk::ScopedAStatus reportStkServiceIsRunningResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus requestIccSimAuthenticationResponse(
+            const RadioResponseInfo& info, const IccIoResult& result) override;
+
+    virtual ndk::ScopedAStatus sendEnvelopeResponse(const RadioResponseInfo& info,
+                                                    const std::string& commandResponse) override;
+
+    virtual ndk::ScopedAStatus sendEnvelopeWithStatusResponse(const RadioResponseInfo& info,
+                                                              const IccIoResult& iccIo) override;
+
+    virtual ndk::ScopedAStatus sendTerminalResponseToSimResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setAllowedCarriersResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setCarrierInfoForImsiEncryptionResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setCdmaSubscriptionSourceResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setFacilityLockForAppResponse(const RadioResponseInfo& info,
+                                                             int32_t retry) override;
+
+    virtual ndk::ScopedAStatus setSimCardPowerResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setUiccSubscriptionResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus supplyIccPin2ForAppResponse(const RadioResponseInfo& info,
+                                                           int32_t remainingRetries) override;
+
+    virtual ndk::ScopedAStatus supplyIccPinForAppResponse(const RadioResponseInfo& info,
+                                                          int32_t remainingRetries) override;
+
+    virtual ndk::ScopedAStatus supplyIccPuk2ForAppResponse(const RadioResponseInfo& info,
+                                                           int32_t remainingRetries) override;
+
+    virtual ndk::ScopedAStatus supplyIccPukForAppResponse(const RadioResponseInfo& info,
+                                                          int32_t remainingRetries) override;
+
+    virtual ndk::ScopedAStatus supplySimDepersonalizationResponse(
+            const RadioResponseInfo& info, PersoSubstate persoType,
+            int32_t remainingRetries) override;
+
+    virtual ndk::ScopedAStatus updateSimPhonebookRecordsResponse(
+            const RadioResponseInfo& info, int32_t updatedRecordIndex) override;
+};
+
+/* Callback class for radio SIM indication */
+class RadioSimIndication : public BnRadioSimIndication {
+  protected:
+    RadioServiceTest& parent_sim;
+
+  public:
+    RadioSimIndication(RadioServiceTest& parent_sim);
+    virtual ~RadioSimIndication() = default;
+
+    virtual ndk::ScopedAStatus carrierInfoForImsiEncryption(RadioIndicationType info) override;
+
+    virtual ndk::ScopedAStatus cdmaSubscriptionSourceChanged(
+            RadioIndicationType type, CdmaSubscriptionSource cdmaSource) override;
+
+    virtual ndk::ScopedAStatus simPhonebookChanged(RadioIndicationType type) override;
+
+    virtual ndk::ScopedAStatus simPhonebookRecordsReceived(
+            RadioIndicationType type, PbReceivedStatus status,
+            const std::vector<PhonebookRecordInfo>& records) override;
+
+    virtual ndk::ScopedAStatus simRefresh(RadioIndicationType type,
+                                          const SimRefreshResult& refreshResult) override;
+
+    virtual ndk::ScopedAStatus simStatusChanged(RadioIndicationType type) override;
+
+    virtual ndk::ScopedAStatus stkEventNotify(RadioIndicationType type,
+                                              const std::string& cmd) override;
+
+    virtual ndk::ScopedAStatus stkProactiveCommand(RadioIndicationType type,
+                                                   const std::string& cmd) override;
+
+    virtual ndk::ScopedAStatus stkSessionEnd(RadioIndicationType type) override;
+
+    virtual ndk::ScopedAStatus subscriptionStatusChanged(RadioIndicationType type,
+                                                         bool activate) override;
+
+    virtual ndk::ScopedAStatus uiccApplicationsEnablementChanged(RadioIndicationType type,
+                                                                 bool enabled) override;
+};
+
+// The main test class for Radio AIDL SIM.
+class RadioSimTest : public ::testing::TestWithParam<std::string>, public RadioServiceTest {
+  public:
+    virtual void SetUp() override;
+
+    /* Override updateSimCardStatus in RadioServiceTest to not call setResponseFunctions */
+    void updateSimCardStatus();
+
+    /* radio SIM service handle in RadioServiceTest */
+    /* radio SIM response handle */
+    std::shared_ptr<RadioSimResponse> radioRsp_sim;
+    /* radio SIM indication handle */
+    std::shared_ptr<RadioSimIndication> radioInd_sim;
+};
diff --git a/radio/aidl/vts/radio_voice_indication.cpp b/radio/aidl/vts/radio_voice_indication.cpp
new file mode 100644
index 0000000..d814c18
--- /dev/null
+++ b/radio/aidl/vts/radio_voice_indication.cpp
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "radio_voice_utils.h"
+
+RadioVoiceIndication::RadioVoiceIndication(RadioServiceTest& parent) : parent_voice(parent) {}
+
+ndk::ScopedAStatus RadioVoiceIndication::callRing(RadioIndicationType /*type*/, bool /*isGsm*/,
+                                                  const CdmaSignalInfoRecord& /*record*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceIndication::callStateChanged(RadioIndicationType /*type*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceIndication::cdmaCallWaiting(
+        RadioIndicationType /*type*/, const CdmaCallWaiting& /*callWaitingRecord*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceIndication::cdmaInfoRec(
+        RadioIndicationType /*type*/, const std::vector<CdmaInformationRecord>& /*records*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceIndication::cdmaOtaProvisionStatus(RadioIndicationType /*type*/,
+                                                                CdmaOtaProvisionStatus /*status*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceIndication::currentEmergencyNumberList(
+        RadioIndicationType /*type*/, const std::vector<EmergencyNumber>& /*emergencyNumberList*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceIndication::enterEmergencyCallbackMode(RadioIndicationType /*type*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceIndication::exitEmergencyCallbackMode(RadioIndicationType /*type*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceIndication::indicateRingbackTone(RadioIndicationType /*type*/,
+                                                              bool /*start*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceIndication::onSupplementaryServiceIndication(
+        RadioIndicationType /*type*/, const StkCcUnsolSsResult& /*ss*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceIndication::resendIncallMute(RadioIndicationType /*type*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceIndication::srvccStateNotify(RadioIndicationType /*type*/,
+                                                          SrvccState /*state*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceIndication::stkCallControlAlphaNotify(RadioIndicationType /*type*/,
+                                                                   const std::string& /*alpha*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceIndication::stkCallSetup(RadioIndicationType /*type*/,
+                                                      int64_t /*timeout*/) {
+    return ndk::ScopedAStatus::ok();
+}
diff --git a/radio/aidl/vts/radio_voice_response.cpp b/radio/aidl/vts/radio_voice_response.cpp
new file mode 100644
index 0000000..a491613
--- /dev/null
+++ b/radio/aidl/vts/radio_voice_response.cpp
@@ -0,0 +1,191 @@
+/*
+ * 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 "radio_voice_utils.h"
+
+RadioVoiceResponse::RadioVoiceResponse(RadioServiceTest& parent) : parent_voice(parent) {}
+
+ndk::ScopedAStatus RadioVoiceResponse::acceptCallResponse(const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::acknowledgeRequest(int32_t /*serial*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::conferenceResponse(const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::dialResponse(const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::emergencyDialResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_voice.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::exitEmergencyCallbackModeResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::explicitCallTransferResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::getCallForwardStatusResponse(
+        const RadioResponseInfo& /*info*/,
+        const std::vector<CallForwardInfo>& /*callForwardInfos*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::getCallWaitingResponse(const RadioResponseInfo& /*info*/,
+                                                              bool /*enable*/,
+                                                              int32_t /*serviceClass*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::getClipResponse(const RadioResponseInfo& /*info*/,
+                                                       ClipStatus /*status*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::getClirResponse(const RadioResponseInfo& /*info*/,
+                                                       int32_t /*n*/, int32_t /*m*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::getCurrentCallsResponse(const RadioResponseInfo& info,
+                                                               const std::vector<Call>& calls) {
+    rspInfo = info;
+    currentCalls = calls;
+    parent_voice.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::getLastCallFailCauseResponse(
+        const RadioResponseInfo& /*info*/, const LastCallFailCauseInfo& /*failCauseInfo*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::getMuteResponse(const RadioResponseInfo& /*info*/,
+                                                       bool /*enable*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::getPreferredVoicePrivacyResponse(
+        const RadioResponseInfo& /*info*/, bool /*enable*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::getTtyModeResponse(const RadioResponseInfo& /*info*/,
+                                                          TtyMode /*mode*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::handleStkCallSetupRequestFromSimResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::hangupConnectionResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_voice.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::hangupForegroundResumeBackgroundResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::hangupWaitingOrBackgroundResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::isVoNrEnabledResponse(const RadioResponseInfo& /*info*/,
+                                                             bool /*enabled*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::rejectCallResponse(const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::sendBurstDtmfResponse(const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::sendCdmaFeatureCodeResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::sendDtmfResponse(const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::separateConnectionResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::setCallForwardResponse(const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::setCallWaitingResponse(const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::setClirResponse(const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::setMuteResponse(const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::setPreferredVoicePrivacyResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::setTtyModeResponse(const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::setVoNrEnabledResponse(const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::startDtmfResponse(const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::stopDtmfResponse(const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::switchWaitingOrHoldingAndActiveResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
diff --git a/radio/aidl/vts/radio_voice_test.cpp b/radio/aidl/vts/radio_voice_test.cpp
new file mode 100644
index 0000000..717f3f0
--- /dev/null
+++ b/radio/aidl/vts/radio_voice_test.cpp
@@ -0,0 +1,267 @@
+/*
+ * 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/radio/config/IRadioConfig.h>
+#include <aidl/android/hardware/radio/voice/EmergencyServiceCategory.h>
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+
+#include "radio_voice_utils.h"
+
+#define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk())
+
+void RadioVoiceTest::SetUp() {
+    std::string serviceName = GetParam();
+
+    if (!isServiceValidForDeviceConfiguration(serviceName)) {
+        ALOGI("Skipped the test due to device configuration.");
+        GTEST_SKIP();
+    }
+
+    radio_voice = IRadioVoice::fromBinder(
+            ndk::SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
+    ASSERT_NE(nullptr, radio_voice.get());
+
+    radioRsp_voice = ndk::SharedRefBase::make<RadioVoiceResponse>(*this);
+    ASSERT_NE(nullptr, radioRsp_voice.get());
+
+    count_ = 0;
+
+    radioInd_voice = ndk::SharedRefBase::make<RadioVoiceIndication>(*this);
+    ASSERT_NE(nullptr, radioInd_voice.get());
+
+    radio_voice->setResponseFunctions(radioRsp_voice, radioInd_voice);
+
+    // Assert IRadioSim exists and SIM is present before testing
+    radio_sim = sim::IRadioSim::fromBinder(ndk::SpAIBinder(
+            AServiceManager_waitForService("android.hardware.radio.sim.IRadioSim/slot1")));
+    ASSERT_NE(nullptr, radio_sim.get());
+    updateSimCardStatus();
+    EXPECT_EQ(CardStatus::STATE_PRESENT, cardStatus.cardState);
+
+    // Assert IRadioConfig exists before testing
+    radio_config = config::IRadioConfig::fromBinder(ndk::SpAIBinder(
+            AServiceManager_waitForService("android.hardware.radio.config.IRadioConfig/default")));
+    ASSERT_NE(nullptr, radio_config.get());
+
+    if (isDsDsEnabled() || isTsTsEnabled()) {
+        radio_network = IRadioNetwork::fromBinder(ndk::SpAIBinder(AServiceManager_waitForService(
+                "android.hardware.radio.network.IRadioNetwork/slot1")));
+        ASSERT_NE(nullptr, radio_network.get());
+        radioRsp_network = ndk::SharedRefBase::make<RadioNetworkResponse>(*this);
+        radioInd_network = ndk::SharedRefBase::make<RadioNetworkIndication>(*this);
+        radio_network->setResponseFunctions(radioRsp_network, radioInd_network);
+    }
+}
+
+ndk::ScopedAStatus RadioVoiceTest::clearPotentialEstablishedCalls() {
+    // Get the current call Id to hangup the established emergency call.
+    serial = GetRandomSerialNumber();
+    radio_voice->getCurrentCalls(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+
+    // Hang up to disconnect the established call channels.
+    for (const Call& call : radioRsp_voice->currentCalls) {
+        serial = GetRandomSerialNumber();
+        radio_voice->hangup(serial, call.index);
+        ALOGI("Hang up to disconnect the established call channel: %d", call.index);
+        EXPECT_EQ(std::cv_status::no_timeout, wait());
+        // Give some time for modem to disconnect the established call channel.
+        sleep(MODEM_EMERGENCY_CALL_DISCONNECT_TIME);
+    }
+
+    // Verify there are no more current calls.
+    serial = GetRandomSerialNumber();
+    radio_voice->getCurrentCalls(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(0, radioRsp_voice->currentCalls.size());
+    return ndk::ScopedAStatus::ok();
+}
+
+/*
+ * Test IRadioVoice.emergencyDial() for the response returned.
+ */
+TEST_P(RadioVoiceTest, emergencyDial) {
+    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");
+    }
+
+    serial = GetRandomSerialNumber();
+
+    Dial dialInfo;
+    dialInfo.address = std::string("911");
+    int32_t categories = static_cast<int32_t>(EmergencyServiceCategory::UNSPECIFIED);
+    std::vector<std::string> urns = {""};
+    EmergencyCallRouting routing = EmergencyCallRouting::UNKNOWN;
+
+    ndk::ScopedAStatus res =
+            radio_voice->emergencyDial(serial, dialInfo, categories, urns, routing, true, true);
+    ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+    ALOGI("emergencyDial, rspInfo.error = %s\n", toString(radioRsp_voice->rspInfo.error).c_str());
+
+    RadioError rspEmergencyDial = radioRsp_voice->rspInfo.error;
+    // In DSDS or TSTS, we only check the result if the current slot is IN_SERVICE
+    // or Emergency_Only.
+    if (isDsDsEnabled() || isTsTsEnabled()) {
+        serial = GetRandomSerialNumber();
+        radio_network->getVoiceRegistrationState(serial);
+        EXPECT_EQ(std::cv_status::no_timeout, wait());
+        if (isVoiceEmergencyOnly(radioRsp_network->voiceRegResp.regState) ||
+            isVoiceInService(radioRsp_network->voiceRegResp.regState)) {
+            EXPECT_EQ(RadioError::NONE, rspEmergencyDial);
+        }
+    } else {
+        EXPECT_EQ(RadioError::NONE, rspEmergencyDial);
+    }
+
+    // Give some time for modem to establish the emergency call channel.
+    sleep(MODEM_EMERGENCY_CALL_ESTABLISH_TIME);
+
+    // Disconnect all the potential established calls to prevent them affecting other tests.
+    clearPotentialEstablishedCalls();
+}
+
+/*
+ * Test IRadioVoice.emergencyDial() with specified service and its response returned.
+ */
+TEST_P(RadioVoiceTest, emergencyDial_withServices) {
+    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");
+    }
+
+    serial = GetRandomSerialNumber();
+
+    Dial dialInfo;
+    dialInfo.address = std::string("911");
+    int32_t categories = static_cast<int32_t>(EmergencyServiceCategory::AMBULANCE);
+    std::vector<std::string> urns = {"urn:service:sos.ambulance"};
+    EmergencyCallRouting routing = EmergencyCallRouting::UNKNOWN;
+
+    ndk::ScopedAStatus res =
+            radio_voice->emergencyDial(serial, dialInfo, categories, urns, routing, true, true);
+    ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+    ALOGI("emergencyDial_withServices, rspInfo.error = %s\n",
+          toString(radioRsp_voice->rspInfo.error).c_str());
+    RadioError rspEmergencyDial = radioRsp_voice->rspInfo.error;
+
+    // In DSDS or TSTS, we only check the result if the current slot is IN_SERVICE
+    // or Emergency_Only.
+    if (isDsDsEnabled() || isTsTsEnabled()) {
+        serial = GetRandomSerialNumber();
+        radio_network->getVoiceRegistrationState(serial);
+        EXPECT_EQ(std::cv_status::no_timeout, wait());
+        if (isVoiceEmergencyOnly(radioRsp_network->voiceRegResp.regState) ||
+            isVoiceInService(radioRsp_network->voiceRegResp.regState)) {
+            EXPECT_EQ(RadioError::NONE, rspEmergencyDial);
+        }
+    } else {
+        EXPECT_EQ(RadioError::NONE, rspEmergencyDial);
+    }
+    // Give some time for modem to establish the emergency call channel.
+    sleep(MODEM_EMERGENCY_CALL_ESTABLISH_TIME);
+
+    // Disconnect all the potential established calls to prevent them affecting other tests.
+    clearPotentialEstablishedCalls();
+}
+
+/*
+ * Test IRadioVoice.emergencyDial() with known emergency call routing and its response returned.
+ */
+TEST_P(RadioVoiceTest, emergencyDial_withEmergencyRouting) {
+    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");
+    }
+
+    serial = GetRandomSerialNumber();
+
+    Dial dialInfo;
+    dialInfo.address = std::string("911");
+    int32_t categories = static_cast<int32_t>(EmergencyServiceCategory::UNSPECIFIED);
+    std::vector<std::string> urns = {""};
+    EmergencyCallRouting routing = EmergencyCallRouting::EMERGENCY;
+
+    ndk::ScopedAStatus res =
+            radio_voice->emergencyDial(serial, dialInfo, categories, urns, routing, true, true);
+    ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+    ALOGI("emergencyDial_withEmergencyRouting, rspInfo.error = %s\n",
+          toString(radioRsp_voice->rspInfo.error).c_str());
+    RadioError rspEmergencyDial = radioRsp_voice->rspInfo.error;
+
+    // In DSDS or TSTS, we only check the result if the current slot is IN_SERVICE
+    // or Emergency_Only.
+    if (isDsDsEnabled() || isTsTsEnabled()) {
+        serial = GetRandomSerialNumber();
+        radio_network->getVoiceRegistrationState(serial);
+        EXPECT_EQ(std::cv_status::no_timeout, wait());
+        if (isVoiceEmergencyOnly(radioRsp_network->voiceRegResp.regState) ||
+            isVoiceInService(radioRsp_network->voiceRegResp.regState)) {
+            EXPECT_EQ(RadioError::NONE, rspEmergencyDial);
+        }
+    } else {
+        EXPECT_EQ(RadioError::NONE, rspEmergencyDial);
+    }
+
+    // Give some time for modem to establish the emergency call channel.
+    sleep(MODEM_EMERGENCY_CALL_ESTABLISH_TIME);
+
+    // Disconnect all the potential established calls to prevent them affecting other tests.
+    clearPotentialEstablishedCalls();
+}
+
+/*
+ * Test IRadioVoice.getCurrentCalls() for the response returned.
+ */
+TEST_P(RadioVoiceTest, getCurrentCalls) {
+    serial = GetRandomSerialNumber();
+    radio_voice->getCurrentCalls(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+    EXPECT_EQ(RadioError::NONE, radioRsp_voice->rspInfo.error);
+}
diff --git a/radio/aidl/vts/radio_voice_utils.h b/radio/aidl/vts/radio_voice_utils.h
new file mode 100644
index 0000000..d61bf1e
--- /dev/null
+++ b/radio/aidl/vts/radio_voice_utils.h
@@ -0,0 +1,196 @@
+/*
+ * 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/radio/voice/BnRadioVoiceIndication.h>
+#include <aidl/android/hardware/radio/voice/BnRadioVoiceResponse.h>
+#include <aidl/android/hardware/radio/voice/IRadioVoice.h>
+
+#include "radio_aidl_hal_utils.h"
+#include "radio_network_utils.h"
+
+using namespace aidl::android::hardware::radio::voice;
+
+class RadioVoiceTest;
+
+/* Callback class for radio voice response */
+class RadioVoiceResponse : public BnRadioVoiceResponse {
+  protected:
+    RadioServiceTest& parent_voice;
+
+  public:
+    RadioVoiceResponse(RadioServiceTest& parent_voice);
+    virtual ~RadioVoiceResponse() = default;
+
+    RadioResponseInfo rspInfo;
+    std::vector<Call> currentCalls;
+
+    virtual ndk::ScopedAStatus acceptCallResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus acknowledgeRequest(int32_t serial) override;
+
+    virtual ndk::ScopedAStatus conferenceResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus dialResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus emergencyDialResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus exitEmergencyCallbackModeResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus explicitCallTransferResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus getCallForwardStatusResponse(
+            const RadioResponseInfo& info,
+            const std::vector<CallForwardInfo>& call_forwardInfos) override;
+
+    virtual ndk::ScopedAStatus getCallWaitingResponse(const RadioResponseInfo& info, bool enable,
+                                                      int32_t serviceClass) override;
+
+    virtual ndk::ScopedAStatus getClipResponse(const RadioResponseInfo& info,
+                                               ClipStatus status) override;
+
+    virtual ndk::ScopedAStatus getClirResponse(const RadioResponseInfo& info, int32_t n,
+                                               int32_t m) override;
+
+    virtual ndk::ScopedAStatus getCurrentCallsResponse(const RadioResponseInfo& info,
+                                                       const std::vector<Call>& calls) override;
+
+    virtual ndk::ScopedAStatus getLastCallFailCauseResponse(
+            const RadioResponseInfo& info, const LastCallFailCauseInfo& failCauseInfo) override;
+
+    virtual ndk::ScopedAStatus getMuteResponse(const RadioResponseInfo& info, bool enable) override;
+
+    virtual ndk::ScopedAStatus getPreferredVoicePrivacyResponse(const RadioResponseInfo& info,
+                                                                bool enable) override;
+
+    virtual ndk::ScopedAStatus getTtyModeResponse(const RadioResponseInfo& info,
+                                                  TtyMode mode) override;
+
+    virtual ndk::ScopedAStatus handleStkCallSetupRequestFromSimResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus hangupConnectionResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus hangupForegroundResumeBackgroundResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus hangupWaitingOrBackgroundResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus isVoNrEnabledResponse(const RadioResponseInfo& info,
+                                                     bool enable) override;
+
+    virtual ndk::ScopedAStatus rejectCallResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus sendBurstDtmfResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus sendCdmaFeatureCodeResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus sendDtmfResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus separateConnectionResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setCallForwardResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setCallWaitingResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setClirResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setMuteResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setPreferredVoicePrivacyResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setTtyModeResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setVoNrEnabledResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus startDtmfResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus stopDtmfResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus switchWaitingOrHoldingAndActiveResponse(
+            const RadioResponseInfo& info) override;
+};
+
+/* Callback class for radio voice indication */
+class RadioVoiceIndication : public BnRadioVoiceIndication {
+  protected:
+    RadioServiceTest& parent_voice;
+
+  public:
+    RadioVoiceIndication(RadioServiceTest& parent_voice);
+    virtual ~RadioVoiceIndication() = default;
+
+    virtual ndk::ScopedAStatus callRing(RadioIndicationType type, bool isGsm,
+                                        const CdmaSignalInfoRecord& record) override;
+
+    virtual ndk::ScopedAStatus callStateChanged(RadioIndicationType type) override;
+
+    virtual ndk::ScopedAStatus cdmaCallWaiting(RadioIndicationType type,
+                                               const CdmaCallWaiting& callWaitingRecord) override;
+
+    virtual ndk::ScopedAStatus cdmaInfoRec(
+            RadioIndicationType type, const std::vector<CdmaInformationRecord>& records) override;
+
+    virtual ndk::ScopedAStatus cdmaOtaProvisionStatus(RadioIndicationType type,
+                                                      CdmaOtaProvisionStatus status) override;
+
+    virtual ndk::ScopedAStatus currentEmergencyNumberList(
+            RadioIndicationType type,
+            const std::vector<EmergencyNumber>& emergencyNumberList) override;
+
+    virtual ndk::ScopedAStatus enterEmergencyCallbackMode(RadioIndicationType type) override;
+
+    virtual ndk::ScopedAStatus exitEmergencyCallbackMode(RadioIndicationType type) override;
+
+    virtual ndk::ScopedAStatus indicateRingbackTone(RadioIndicationType type, bool start) override;
+
+    virtual ndk::ScopedAStatus onSupplementaryServiceIndication(
+            RadioIndicationType type, const StkCcUnsolSsResult& ss) override;
+
+    virtual ndk::ScopedAStatus resendIncallMute(RadioIndicationType type) override;
+
+    virtual ndk::ScopedAStatus srvccStateNotify(RadioIndicationType type,
+                                                SrvccState state) override;
+
+    virtual ndk::ScopedAStatus stkCallControlAlphaNotify(RadioIndicationType type,
+                                                         const std::string& alpha) override;
+
+    virtual ndk::ScopedAStatus stkCallSetup(RadioIndicationType type, int64_t timeout) override;
+};
+
+// The main test class for Radio AIDL Voice.
+class RadioVoiceTest : public ::testing::TestWithParam<std::string>, public RadioServiceTest {
+  protected:
+    /* Clear Potential Established Calls */
+    virtual ndk::ScopedAStatus clearPotentialEstablishedCalls();
+    std::shared_ptr<network::IRadioNetwork> radio_network;
+    std::shared_ptr<RadioNetworkResponse> radioRsp_network;
+    std::shared_ptr<RadioNetworkIndication> radioInd_network;
+
+  public:
+    virtual void SetUp() override;
+
+    /* radio voice service handle */
+    std::shared_ptr<IRadioVoice> radio_voice;
+    /* radio voice response handle */
+    std::shared_ptr<RadioVoiceResponse> radioRsp_voice;
+    /* radio voice indication handle */
+    std::shared_ptr<RadioVoiceIndication> radioInd_voice;
+};
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/dice/aidl/Android.bp b/security/dice/aidl/Android.bp
new file mode 100644
index 0000000..af9dd33
--- /dev/null
+++ b/security/dice/aidl/Android.bp
@@ -0,0 +1,47 @@
+// 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 {
+    // 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.security.dice",
+    vendor_available: true,
+    srcs: [
+        "android/hardware/security/dice/*.aidl",
+    ],
+    stability: "vintf",
+    backend: {
+        java: {
+            enabled: false,
+            platform_apis: false,
+        },
+        ndk: {
+            vndk: {
+                enabled: true,
+            },
+            apps_enabled: false,
+        },
+        rust: {
+            enabled: true,
+        },
+    },
+    //     versions: ["1"],
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl b/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/Bcc.aidl
similarity index 86%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl
copy to security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/Bcc.aidl
index df07c9c..5af7358 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl
+++ b/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/Bcc.aidl
@@ -1,5 +1,5 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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.
@@ -31,9 +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;
-@VintfStability
-parcelable ColorTransformPayload {
-  float[] matrix;
-  android.hardware.graphics.common.ColorTransform hint;
+package android.hardware.security.dice;
+/* @hide */
+@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability
+parcelable Bcc {
+  byte[] data;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl b/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/BccHandover.aidl
similarity index 83%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl
copy to security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/BccHandover.aidl
index df07c9c..ab50c36 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl
+++ b/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/BccHandover.aidl
@@ -1,5 +1,5 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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.
@@ -31,9 +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;
-@VintfStability
-parcelable ColorTransformPayload {
-  float[] matrix;
-  android.hardware.graphics.common.ColorTransform hint;
+package android.hardware.security.dice;
+/* @hide */
+@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability
+parcelable BccHandover {
+  byte[] cdiAttest;
+  byte[] cdiSeal;
+  android.hardware.security.dice.Bcc bcc;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl b/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/Config.aidl
similarity index 86%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl
copy to security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/Config.aidl
index df07c9c..78dd2f8 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl
+++ b/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/Config.aidl
@@ -1,5 +1,5 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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.
@@ -31,9 +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;
-@VintfStability
-parcelable ColorTransformPayload {
-  float[] matrix;
-  android.hardware.graphics.common.ColorTransform hint;
+package android.hardware.security.dice;
+/* @hide */
+@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability
+parcelable Config {
+  byte[] desc;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl b/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/IDiceDevice.aidl
similarity index 70%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl
copy to security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/IDiceDevice.aidl
index df07c9c..383f4d1 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl
+++ b/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/IDiceDevice.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,9 +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;
-@VintfStability
-parcelable ColorTransformPayload {
-  float[] matrix;
-  android.hardware.graphics.common.ColorTransform hint;
+package android.hardware.security.dice;
+/* @hide */
+@SensitiveData @VintfStability
+interface IDiceDevice {
+  android.hardware.security.dice.Signature sign(in android.hardware.security.dice.InputValues[] id, in byte[] payload);
+  android.hardware.security.dice.Bcc getAttestationChain(in android.hardware.security.dice.InputValues[] inputValues);
+  android.hardware.security.dice.BccHandover derive(in android.hardware.security.dice.InputValues[] inputValues);
+  void demote(in android.hardware.security.dice.InputValues[] inputValues);
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl b/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/InputValues.aidl
similarity index 76%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl
copy to security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/InputValues.aidl
index df07c9c..79583fb 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl
+++ b/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/InputValues.aidl
@@ -1,5 +1,5 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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.
@@ -31,9 +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;
-@VintfStability
-parcelable ColorTransformPayload {
-  float[] matrix;
-  android.hardware.graphics.common.ColorTransform hint;
+package android.hardware.security.dice;
+/* @hide */
+@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability
+parcelable InputValues {
+  byte[] codeHash;
+  android.hardware.security.dice.Config config;
+  byte[] authorityHash;
+  @nullable byte[] authorityDescriptor;
+  android.hardware.security.dice.Mode mode = android.hardware.security.dice.Mode.NOT_INITIALIZED;
+  byte[] hidden;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.aidl b/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/Mode.aidl
similarity index 89%
rename from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.aidl
rename to security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/Mode.aidl
index b87870d..295c32e 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.aidl
+++ b/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/Mode.aidl
@@ -1,5 +1,5 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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.
@@ -31,9 +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.security.dice;
+/* @hide */
 @Backing(type="int") @VintfStability
-enum HandleIndex {
-  EMPTY = -1,
-  CACHED = -2,
+enum Mode {
+  NOT_INITIALIZED = 0,
+  NORMAL = 1,
+  DEBUG = 2,
+  RECOVERY = 3,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.aidl b/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/ResponseCode.aidl
similarity index 88%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.aidl
copy to security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/ResponseCode.aidl
index b87870d..c13afa6 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.aidl
+++ b/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/ResponseCode.aidl
@@ -1,5 +1,5 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * Copyright 2020, The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -31,9 +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.security.dice;
 @Backing(type="int") @VintfStability
-enum HandleIndex {
-  EMPTY = -1,
-  CACHED = -2,
+enum ResponseCode {
+  PERMISSION_DENIED = 1,
+  SYSTEM_ERROR = 2,
+  NOT_IMPLEMENTED = 3,
+  DEMOTION_FAILED = 4,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl b/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/Signature.aidl
similarity index 86%
rename from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl
rename to security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/Signature.aidl
index df07c9c..294170d 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl
+++ b/security/dice/aidl/aidl_api/android.hardware.security.dice/current/android/hardware/security/dice/Signature.aidl
@@ -1,5 +1,5 @@
-/**
- * Copyright (c) 2021, The Android Open Source Project
+/*
+ * 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.
@@ -31,9 +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;
-@VintfStability
-parcelable ColorTransformPayload {
-  float[] matrix;
-  android.hardware.graphics.common.ColorTransform hint;
+package android.hardware.security.dice;
+/* @hide */
+@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability
+parcelable Signature {
+  byte[] data;
 }
diff --git a/security/dice/aidl/android/hardware/security/dice/Bcc.aidl b/security/dice/aidl/android/hardware/security/dice/Bcc.aidl
new file mode 100644
index 0000000..983915e
--- /dev/null
+++ b/security/dice/aidl/android/hardware/security/dice/Bcc.aidl
@@ -0,0 +1,36 @@
+/*
+ * 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.security.dice;
+
+/**
+ * A DICE certificate chain following the Boot Certificate Chain (BCC) specification.
+ * @hide
+ */
+@VintfStability
+@RustDerive(Clone=true, Eq=true, PartialEq=true, Ord=true, PartialOrd=true, Hash=true)
+parcelable Bcc {
+    /**
+     * The DICE certificate chain CBOR encoded following the BCC specification. The CDDL
+     * specification for BCC can be found here [1].
+     *
+     * @see <a
+     *         href="https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl">
+     *    BCC CDDL specification
+     * </a>
+     */
+    byte[] data;
+}
diff --git a/security/dice/aidl/android/hardware/security/dice/BccHandover.aidl b/security/dice/aidl/android/hardware/security/dice/BccHandover.aidl
new file mode 100644
index 0000000..d522cef
--- /dev/null
+++ b/security/dice/aidl/android/hardware/security/dice/BccHandover.aidl
@@ -0,0 +1,46 @@
+/*
+ * 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.security.dice;
+
+import android.hardware.security.dice.Bcc;
+
+/**
+ * Represents one set of DICE artifacts.
+ *
+ * @hide
+ */
+@VintfStability
+@RustDerive(Clone=true, Eq=true, PartialEq=true, Ord=true, PartialOrd=true, Hash=true)
+parcelable BccHandover {
+    /**
+     * CDI_attest. Must a exactly 32 bytes of data.
+     */
+    byte[] cdiAttest;
+    /**
+     * CDI_seal. Must a exactly 32 bytes of data.
+     */
+    byte[] cdiSeal;
+    /**
+     * CBOR encoded BCC.
+     *
+     * @see <a
+     *         href="https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl">
+     *    BCC CDDL specification
+     * </a>
+     */
+    Bcc bcc;
+}
diff --git a/security/dice/aidl/android/hardware/security/dice/Config.aidl b/security/dice/aidl/android/hardware/security/dice/Config.aidl
new file mode 100644
index 0000000..6decfc5
--- /dev/null
+++ b/security/dice/aidl/android/hardware/security/dice/Config.aidl
@@ -0,0 +1,38 @@
+/*
+ * 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.security.dice;
+
+/**
+ * DICE config descriptor as described in at
+ * <a
+ * href="https://pigweed.googlesource.com/open-dice/+/refs/heads/main/docs/specification.md#input-values">
+ *     input-values
+ * </a>
+ * @hide
+ */
+@VintfStability
+@RustDerive(Clone=true, Eq=true, PartialEq=true, Ord=true, PartialOrd=true, Hash=true)
+parcelable Config {
+    /**
+     * A free form descriptor. This should follow the BCC Configuration Descriptor.
+     * @see <a
+     *         href="https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl">
+     *     BccPayload field -4670548
+     * </a>
+     */
+    byte[] desc;
+}
diff --git a/security/dice/aidl/android/hardware/security/dice/IDiceDevice.aidl b/security/dice/aidl/android/hardware/security/dice/IDiceDevice.aidl
new file mode 100644
index 0000000..709aede
--- /dev/null
+++ b/security/dice/aidl/android/hardware/security/dice/IDiceDevice.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.security.dice;
+
+import android.hardware.security.dice.Bcc;
+import android.hardware.security.dice.BccHandover;
+import android.hardware.security.dice.InputValues;
+import android.hardware.security.dice.Signature;
+
+/**
+ * IDiceDevice specifies an interface that allows access to the Android instance's DICE artifacts.
+ *
+ * <h2>Features</h2>
+ *
+ * The dice device provides access to the component's CDI_SEAL and CDI_ATTEST secrets as well
+ * as to its attestation certificate chain. The "component" is the Android instance running this
+ * HAL service and the secrets and attestation chain must include all boot stage components,
+ * the kernel, and the verified boot information (VBA).
+ *
+ * Implementations provide the following operations:
+ * <li> sign - Signing a payload with a key derived from CDI_ATTEST.
+ * <li> getAttestationChain - Retrieve the component's attestation certificate chain.
+ * <li> derive - Retrieve the component's DICE artifacts.
+ *
+ * @see <a
+ *         href="https://pigweed.googlesource.com/open-dice/+/refs/heads/main/docs/specification.md">
+ *     Open-dice Specification
+ * </a>
+ * @see <a
+ *         href="https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/keymint/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl">
+ *     Boot Certificate Chain (BCC) CDDL specification
+ * </a>
+ * @hide
+ */
+@SensitiveData
+@VintfStability
+interface IDiceDevice {
+    /**
+     * Uses the a key derived from the component's, or a child's given by <code>inputValues</code>,
+     * attestation secret to sign the payload using RFC 8032 Pure Ed25519 and returns the
+     * signature. The payload is limited to 1024 bytes.
+     *
+     * @see <a href="https://datatracker.ietf.org/doc/html/rfc8032">RFC 8032</a>
+     */
+    Signature sign(in InputValues[] id, in byte[] payload);
+
+    /**
+     * Returns the attestation chain of the component if <code>inputValues</code> is empty or the
+     * chain to the given child of the component identified by the <code>inputValues</code> vector.
+     *
+     * ## Error as service specific exception:
+     *     ResponseCode::PERMISSION_DENIED if the caller is not sufficiently privileged.
+     */
+    Bcc getAttestationChain(in InputValues[] inputValues);
+
+    /**
+     * This function allows a client to become a resident node. A resident node is a node that
+     * manages its own dice secrets as opposed to using them by proxy, i.e., by calling sign
+     * and getAttestationChain. Called with empty <code>inputValues</code> vectors, an
+     * implementation returns the component's DICE secrets. If the <code>inputValues</code> vector
+     * is given the appropriate derivations are performed starting from the component's level.
+     *
+     * ## Error as service specific exception:
+     *     ResponseCode::PERMISSION_DENIED if the implementation does not allow resident nodes
+     *     at the client's level.
+     */
+    BccHandover derive(in InputValues[] inputValues);
+
+    /**
+     * This demotes the implementation of this interface.
+     * When called, the implementation performs appropriate derivation steps using
+     * <code>inputValues</code>, traversing the vector in ascending order. Then it replaces its
+     * stored DICE artifacts with the newly derived ones.
+     *
+     * IMPORTANT: When the function returns, all remnants of the previous DICE artifacts must
+     * have been purged from memory.
+     *
+     * This operation is not reversible until the next reboot. Further demotion is always
+     * possible.
+     *
+     * ## Error as service specific exception:
+     *     ResponseCode::DEMOTION_FAILED if the implementation failed to demote itself
+     *     or was unable to purge previous DICE artifacts from memory.
+     */
+    void demote(in InputValues[] inputValues);
+}
diff --git a/security/dice/aidl/android/hardware/security/dice/InputValues.aidl b/security/dice/aidl/android/hardware/security/dice/InputValues.aidl
new file mode 100644
index 0000000..e44ef22
--- /dev/null
+++ b/security/dice/aidl/android/hardware/security/dice/InputValues.aidl
@@ -0,0 +1,58 @@
+/*
+ * 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.security.dice;
+
+import android.hardware.security.dice.Config;
+import android.hardware.security.dice.Mode;
+
+/**
+ * DICE input values for certificate and CDI generation.
+ *
+ * @see <a
+ *         href="https://pigweed.googlesource.com/open-dice/+/refs/heads/main/docs/specification.md#input-values">
+ *     Open-dice input-values
+ * </a>
+ * @hide
+ */
+@RustDerive(Clone=true, Eq=true, PartialEq=true, Ord=true, PartialOrd=true, Hash=true)
+@VintfStability
+parcelable InputValues {
+    /**
+     * The target code hash. Must be exactly 64 bytes.
+     */
+    byte[] codeHash;
+    /**
+     * The configuration data.
+     */
+    Config config;
+    /**
+     * The authority hash. Must be exactly 64 bytes. Must be all zero if unused.
+     */
+    byte[] authorityHash;
+    /**
+     * Optional free form authorityDescriptor.
+     */
+    @nullable byte[] authorityDescriptor;
+    /**
+     * The mode of operation. Normal, Debug, Maintenance, or not initialized.
+     */
+    Mode mode = Mode.NOT_INITIALIZED;
+    /**
+     * Optional hidden values. Must be exactly 64 bytes. Must be all zero if unused.
+     */
+    byte[] hidden;
+}
diff --git a/security/dice/aidl/android/hardware/security/dice/Mode.aidl b/security/dice/aidl/android/hardware/security/dice/Mode.aidl
new file mode 100644
index 0000000..3b3bfdc
--- /dev/null
+++ b/security/dice/aidl/android/hardware/security/dice/Mode.aidl
@@ -0,0 +1,38 @@
+/*
+ * 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.security.dice;
+
+/**
+ * DICE mode values as defined at
+ *
+ * @see <a
+ *         href="https://pigweed.googlesource.com/open-dice/+/refs/heads/main/docs/specification.md#mode-value-details">
+ *     open-dice mode-value-details
+ * </a>
+ * @hide
+ */
+@Backing(type="int")
+@VintfStability
+enum Mode {
+    NOT_INITIALIZED = 0,
+    NORMAL = 1,
+    DEBUG = 2,
+    /**
+     * The recovery mode is also referred to as "maintenance" mode.
+     */
+    RECOVERY = 3,
+}
diff --git a/security/dice/aidl/android/hardware/security/dice/ResponseCode.aidl b/security/dice/aidl/android/hardware/security/dice/ResponseCode.aidl
new file mode 100644
index 0000000..3e77cf7
--- /dev/null
+++ b/security/dice/aidl/android/hardware/security/dice/ResponseCode.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2020, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.security.dice;
+
+@Backing(type="int")
+/**
+ * These response codes are used as service specific exception codes by
+ * IDiceDevice.
+ * @hide
+ */
+@VintfStability
+enum ResponseCode {
+    /**
+     * The caller has insufficient privilege to access the DICE API.
+     */
+    PERMISSION_DENIED = 1,
+    /**
+     * An unexpected error occurred, likely with IO or IPC.
+     */
+    SYSTEM_ERROR = 2,
+    /**
+     * Returned if the called function is not implemented.
+     */
+    NOT_IMPLEMENTED = 3,
+    /**
+     * An attempt to demote the implementation failed.
+     */
+    DEMOTION_FAILED = 4,
+}
diff --git a/security/dice/aidl/android/hardware/security/dice/Signature.aidl b/security/dice/aidl/android/hardware/security/dice/Signature.aidl
new file mode 100644
index 0000000..ea3594f
--- /dev/null
+++ b/security/dice/aidl/android/hardware/security/dice/Signature.aidl
@@ -0,0 +1,32 @@
+/*
+ * 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.security.dice;
+
+/**
+ * This parcelable represents a Signature. It is used as return value of IDiceNode::sign.
+ *
+ * @hide
+ */
+@RustDerive(Clone=true, Eq=true, PartialEq=true, Ord=true, PartialOrd=true, Hash=true)
+@VintfStability
+parcelable Signature {
+    /**
+     * The RFC 8032 PureEd25519 signature.
+     * @see <a href="https://datatracker.ietf.org/doc/html/rfc8032">RFC 8032</a>
+     */
+    byte[] data;
+}
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/KeyCreationResult.aidl b/security/keymint/aidl/android/hardware/security/keymint/KeyCreationResult.aidl
index fd6bf65..16bbc5c 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/KeyCreationResult.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/KeyCreationResult.aidl
@@ -122,9 +122,9 @@
      * straightforward translation of the KeyMint tag/value parameter lists to ASN.1.
      *
      * KeyDescription ::= SEQUENCE {
-     *     attestationVersion         INTEGER, # Value 100
+     *     attestationVersion         INTEGER, # Value 200
      *     attestationSecurityLevel   SecurityLevel, # See below
-     *     keyMintVersion             INTEGER, # Value 100
+     *     keyMintVersion             INTEGER, # Value 200
      *     keymintSecurityLevel       SecurityLevel, # See below
      *     attestationChallenge       OCTET_STRING, # Tag::ATTESTATION_CHALLENGE from attestParams
      *     uniqueId                   OCTET_STRING, # Empty unless key has Tag::INCLUDE_UNIQUE_ID
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 73c3820..727c6b7 100644
--- a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
+++ b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
@@ -81,7 +81,8 @@
 
         AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
         AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
-        EXPECT_TRUE(verify_attestation_record("foo", "bar", sw_enforced, hw_enforced, SecLevel(),
+        EXPECT_TRUE(verify_attestation_record(AidlVersion(), "foo", "bar", sw_enforced, hw_enforced,
+                                              SecLevel(),
                                               attested_key_cert_chain[0].encodedCertificate));
 
         // Attestation by itself is not valid (last entry is not self-signed).
@@ -113,7 +114,8 @@
 
         hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
         sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
-        EXPECT_TRUE(verify_attestation_record("foo2", "bar2", sw_enforced, hw_enforced, SecLevel(),
+        EXPECT_TRUE(verify_attestation_record(AidlVersion(), "foo2", "bar2", sw_enforced,
+                                              hw_enforced, SecLevel(),
                                               attested_key_cert_chain[0].encodedCertificate));
 
         // Attestation by itself is not valid (last entry is not self-signed).
@@ -154,12 +156,13 @@
         sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
 
         // The client-specified CREATION_DATETIME should be in sw_enforced.
-        // Its presence will also trigger verify_attestation_record() to check that it
-        // is in the attestation extension with a matching value.
+        // Its presence will also trigger verify_attestation_record() to check that
+        // it is in the attestation extension with a matching value.
         EXPECT_TRUE(sw_enforced.Contains(TAG_CREATION_DATETIME, timestamp))
                 << "expected CREATION_TIMESTAMP in sw_enforced:" << sw_enforced
                 << " not in hw_enforced:" << hw_enforced;
-        EXPECT_TRUE(verify_attestation_record("foo", "bar", sw_enforced, hw_enforced, SecLevel(),
+        EXPECT_TRUE(verify_attestation_record(AidlVersion(), "foo", "bar", sw_enforced, hw_enforced,
+                                              SecLevel(),
                                               attested_key_cert_chain[0].encodedCertificate));
 
         // Attestation by itself is not valid (last entry is not self-signed).
@@ -175,6 +178,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
@@ -217,7 +238,7 @@
 
     AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attest_key_characteristics);
     AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attest_key_characteristics);
-    EXPECT_TRUE(verify_attestation_record(challenge, app_id,  //
+    EXPECT_TRUE(verify_attestation_record(AidlVersion(), challenge, app_id,  //
                                           sw_enforced, hw_enforced, SecLevel(),
                                           attest_key_cert_chain[0].encodedCertificate));
 
@@ -252,7 +273,8 @@
 
     AuthorizationSet hw_enforced2 = HwEnforcedAuthorizations(attested_key_characteristics);
     AuthorizationSet sw_enforced2 = SwEnforcedAuthorizations(attested_key_characteristics);
-    EXPECT_TRUE(verify_attestation_record("foo", "bar", sw_enforced2, hw_enforced2, SecLevel(),
+    EXPECT_TRUE(verify_attestation_record(AidlVersion(), "foo", "bar", sw_enforced2, hw_enforced2,
+                                          SecLevel(),
                                           attested_key_cert_chain[0].encodedCertificate));
 
     // Attestation by itself is not valid (last entry is not self-signed).
@@ -313,7 +335,8 @@
         AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
         AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
         ASSERT_GT(cert_chain_list[i].size(), 0);
-        EXPECT_TRUE(verify_attestation_record("foo", "bar", sw_enforced, hw_enforced, SecLevel(),
+        EXPECT_TRUE(verify_attestation_record(AidlVersion(), "foo", "bar", sw_enforced, hw_enforced,
+                                              SecLevel(),
                                               cert_chain_list[i][0].encodedCertificate));
 
         if (i > 0) {
@@ -385,7 +408,8 @@
         AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
         AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
         ASSERT_GT(cert_chain_list[i].size(), 0);
-        EXPECT_TRUE(verify_attestation_record("foo", "bar", sw_enforced, hw_enforced, SecLevel(),
+        EXPECT_TRUE(verify_attestation_record(AidlVersion(), "foo", "bar", sw_enforced, hw_enforced,
+                                              SecLevel(),
                                               cert_chain_list[i][0].encodedCertificate));
 
         if (i > 0) {
@@ -412,6 +436,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 ....
@@ -474,7 +516,8 @@
         AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
         AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
         ASSERT_GT(cert_chain_list[i].size(), 0);
-        EXPECT_TRUE(verify_attestation_record("foo", "bar", sw_enforced, hw_enforced, SecLevel(),
+        EXPECT_TRUE(verify_attestation_record(AidlVersion(), "foo", "bar", sw_enforced, hw_enforced,
+                                              SecLevel(),
                                               cert_chain_list[i][0].encodedCertificate));
 
         if (i > 0) {
@@ -588,7 +631,8 @@
 
         AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
         AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
-        EXPECT_TRUE(verify_attestation_record("foo", "bar", sw_enforced, hw_enforced, SecLevel(),
+        EXPECT_TRUE(verify_attestation_record(AidlVersion(), "foo", "bar", sw_enforced, hw_enforced,
+                                              SecLevel(),
                                               attested_key_cert_chain[0].encodedCertificate));
 
         // Attestation by itself is not valid (last entry is not self-signed).
@@ -619,7 +663,8 @@
 
         hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
         sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
-        EXPECT_TRUE(verify_attestation_record("foo", "bar", sw_enforced, hw_enforced, SecLevel(),
+        EXPECT_TRUE(verify_attestation_record(AidlVersion(), "foo", "bar", sw_enforced, hw_enforced,
+                                              SecLevel(),
                                               attested_key_cert_chain[0].encodedCertificate));
 
         // Attestation by itself is not valid (last entry is not self-signed).
@@ -724,8 +769,8 @@
         // attestation extension should contain them, so make sure the extra tag is added.
         hw_enforced.push_back(tag);
 
-        EXPECT_TRUE(verify_attestation_record("challenge", "foo", sw_enforced, hw_enforced,
-                                              SecLevel(),
+        EXPECT_TRUE(verify_attestation_record(AidlVersion(), "challenge", "foo", sw_enforced,
+                                              hw_enforced, SecLevel(),
                                               attested_key_cert_chain[0].encodedCertificate));
     }
     CheckedDeleteKey(&attest_key.keyBlob);
diff --git a/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp b/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp
index 3cbffbf..d4bbd69 100644
--- a/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp
+++ b/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp
@@ -52,8 +52,9 @@
         EXPECT_TRUE(ChainSignaturesAreValid(cert_chain_, /* strict_issuer_check= */ false));
 
         AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics);
-        EXPECT_TRUE(verify_attestation_record("challenge", "foo", sw_enforced, hw_enforced,
-                                              SecLevel(), cert_chain_[0].encodedCertificate));
+        EXPECT_TRUE(verify_attestation_record(AidlVersion(), "challenge", "foo", sw_enforced,
+                                              hw_enforced, SecLevel(),
+                                              cert_chain_[0].encodedCertificate));
     }
 };
 
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
index 6140df1..02462fc 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
@@ -127,6 +127,16 @@
     return attest_rec;
 }
 
+void check_attestation_version(uint32_t attestation_version, int32_t aidl_version) {
+    // Version numbers in attestation extensions should be a multiple of 100.
+    EXPECT_EQ(attestation_version % 100, 0);
+
+    // The multiplier should never be higher than the AIDL version, but can be less
+    // (for example, if the implementation is from an earlier version but the HAL service
+    // uses the default libraries and so reports the current AIDL version).
+    EXPECT_TRUE((attestation_version / 100) <= aidl_version);
+}
+
 bool avb_verification_enabled() {
     char value[PROPERTY_VALUE_MAX];
     return property_get("ro.boot.vbmeta.device_state", value, "") != 0;
@@ -223,6 +233,15 @@
     vendor_patch_level_ = getVendorPatchlevel();
 }
 
+int32_t KeyMintAidlTestBase::AidlVersion() {
+    int32_t version = 0;
+    auto status = keymint_->getInterfaceVersion(&version);
+    if (!status.isOk()) {
+        ADD_FAILURE() << "Failed to determine interface version";
+    }
+    return version;
+}
+
 void KeyMintAidlTestBase::SetUp() {
     if (AServiceManager_isDeclared(GetParam().c_str())) {
         ::ndk::SpAIBinder binder(AServiceManager_waitForService(GetParam().c_str()));
@@ -518,6 +537,9 @@
     Status result;
     if (!output) return ErrorCode::UNEXPECTED_NULL_POINTER;
 
+    EXPECT_NE(op_, nullptr);
+    if (!op_) return ErrorCode::UNEXPECTED_NULL_POINTER;
+
     std::vector<uint8_t> o_put;
     result = op_->update(vector<uint8_t>(input.begin(), input.end()), {}, {}, &o_put);
 
@@ -1304,7 +1326,8 @@
     verify_subject(cert.get(), subject, self_signed);
 }
 
-bool verify_attestation_record(const string& challenge,                //
+bool verify_attestation_record(int32_t aidl_version,                   //
+                               const string& challenge,                //
                                const string& app_id,                   //
                                AuthorizationSet expected_sw_enforced,  //
                                AuthorizationSet expected_hw_enforced,  //
@@ -1342,7 +1365,7 @@
     EXPECT_EQ(ErrorCode::OK, error);
     if (error != ErrorCode::OK) return false;
 
-    EXPECT_EQ(att_attestation_version, 100U);
+    check_attestation_version(att_attestation_version, aidl_version);
     vector<uint8_t> appId(app_id.begin(), app_id.end());
 
     // check challenge and app id only if we expects a non-fake certificate
@@ -1353,7 +1376,7 @@
         expected_sw_enforced.push_back(TAG_ATTESTATION_APPLICATION_ID, appId);
     }
 
-    EXPECT_EQ(att_keymint_version, 100U);
+    check_attestation_version(att_keymint_version, aidl_version);
     EXPECT_EQ(security_level, att_keymint_security_level);
     EXPECT_EQ(security_level, att_attestation_security_level);
 
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
index 7b3b9d4..61f9d4d 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
@@ -73,6 +73,7 @@
 
     void InitializeKeyMint(std::shared_ptr<IKeyMintDevice> keyMint);
     IKeyMintDevice& keyMint() { return *keymint_; }
+    int32_t AidlVersion();
     uint32_t os_version() { return os_version_; }
     uint32_t os_patch_level() { return os_patch_level_; }
     uint32_t vendor_patch_level() { return vendor_patch_level_; }
@@ -333,7 +334,8 @@
                                const uint64_t expected_serial,  //
                                const string& subject, bool self_signed);
 
-bool verify_attestation_record(const string& challenge,                //
+bool verify_attestation_record(int aidl_version,                       //
+                               const string& challenge,                //
                                const string& app_id,                   //
                                AuthorizationSet expected_sw_enforced,  //
                                AuthorizationSet expected_hw_enforced,  //
diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
index d8b19dc..dd3719b 100644
--- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
@@ -942,7 +942,7 @@
 
         AuthorizationSet hw_enforced = HwEnforcedAuthorizations(key_characteristics);
         AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics);
-        EXPECT_TRUE(verify_attestation_record(challenge, app_id,  //
+        EXPECT_TRUE(verify_attestation_record(AidlVersion(), challenge, app_id,  //
                                               sw_enforced, hw_enforced, SecLevel(),
                                               cert_chain_[0].encodedCertificate));
 
@@ -1093,7 +1093,7 @@
 
     AuthorizationSet hw_enforced = HwEnforcedAuthorizations(key_characteristics);
     AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics);
-    EXPECT_TRUE(verify_attestation_record(challenge, app_id,  //
+    EXPECT_TRUE(verify_attestation_record(AidlVersion(), challenge, app_id,  //
                                           sw_enforced, hw_enforced, SecLevel(),
                                           cert_chain_[0].encodedCertificate));
 
@@ -1315,7 +1315,7 @@
 
         AuthorizationSet hw_enforced = HwEnforcedAuthorizations(key_characteristics);
         AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics);
-        EXPECT_TRUE(verify_attestation_record(challenge, app_id,  //
+        EXPECT_TRUE(verify_attestation_record(AidlVersion(), challenge, app_id,  //
                                               sw_enforced, hw_enforced, SecLevel(),
                                               cert_chain_[0].encodedCertificate));
 
@@ -1444,7 +1444,7 @@
 
         AuthorizationSet hw_enforced = HwEnforcedAuthorizations(key_characteristics);
         AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics);
-        EXPECT_TRUE(verify_attestation_record(challenge, app_id,  //
+        EXPECT_TRUE(verify_attestation_record(AidlVersion(), challenge, app_id,  //
                                               sw_enforced, hw_enforced, SecLevel(),
                                               cert_chain_[0].encodedCertificate));
 
@@ -1523,8 +1523,9 @@
 
         // Verifying the attestation record will check for the specific tag because
         // it's included in the authorizations.
-        EXPECT_TRUE(verify_attestation_record(challenge, app_id, sw_enforced, hw_enforced,
-                                              SecLevel(), cert_chain_[0].encodedCertificate));
+        EXPECT_TRUE(verify_attestation_record(AidlVersion(), challenge, app_id, sw_enforced,
+                                              hw_enforced, SecLevel(),
+                                              cert_chain_[0].encodedCertificate));
 
         CheckedDeleteKey(&key_blob);
     }
@@ -1621,8 +1622,9 @@
 
         // Verifying the attestation record will check for the specific tag because
         // it's included in the authorizations.
-        EXPECT_TRUE(verify_attestation_record(challenge, app_id, sw_enforced, hw_enforced,
-                                              SecLevel(), cert_chain_[0].encodedCertificate));
+        EXPECT_TRUE(verify_attestation_record(AidlVersion(), challenge, app_id, sw_enforced,
+                                              hw_enforced, SecLevel(),
+                                              cert_chain_[0].encodedCertificate));
 
         CheckedDeleteKey(&key_blob);
     }
@@ -1668,9 +1670,9 @@
         AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics_);
 
         // Check that the unique ID field in the extension is non-empty.
-        EXPECT_TRUE(verify_attestation_record(challenge, app_id, sw_enforced, hw_enforced,
-                                              SecLevel(), cert_chain_[0].encodedCertificate,
-                                              unique_id));
+        EXPECT_TRUE(verify_attestation_record(AidlVersion(), challenge, app_id, sw_enforced,
+                                              hw_enforced, SecLevel(),
+                                              cert_chain_[0].encodedCertificate, unique_id));
         EXPECT_GT(unique_id->size(), 0);
         CheckedDeleteKey();
     };
@@ -1765,8 +1767,9 @@
 
     AuthorizationSet hw_enforced = HwEnforcedAuthorizations(key_characteristics);
     AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics);
-    EXPECT_TRUE(verify_attestation_record(challenge, attest_app_id, sw_enforced, hw_enforced,
-                                          SecLevel(), cert_chain_[0].encodedCertificate));
+    EXPECT_TRUE(verify_attestation_record(AidlVersion(), challenge, attest_app_id, sw_enforced,
+                                          hw_enforced, SecLevel(),
+                                          cert_chain_[0].encodedCertificate));
 
     // Check that the app id is not in the cert.
     string app_id = "clientid";
@@ -1919,7 +1922,7 @@
 
         AuthorizationSet hw_enforced = HwEnforcedAuthorizations(key_characteristics);
         AuthorizationSet sw_enforced = SwEnforcedAuthorizations(key_characteristics);
-        EXPECT_TRUE(verify_attestation_record(challenge, app_id,  //
+        EXPECT_TRUE(verify_attestation_record(AidlVersion(), challenge, app_id,  //
                                               sw_enforced, hw_enforced, SecLevel(),
                                               cert_chain_[0].encodedCertificate));
 
@@ -3352,6 +3355,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.
@@ -3470,6 +3493,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.
@@ -6661,7 +6700,7 @@
 
 typedef KeyMintAidlTestBase KeyAgreementTest;
 
-int CurveToOpenSslCurveName(EcCurve curve) {
+static int EcdhCurveToOpenSslCurveName(EcCurve curve) {
     switch (curve) {
         case EcCurve::P_224:
             return NID_secp224r1;
@@ -6671,6 +6710,8 @@
             return NID_secp384r1;
         case EcCurve::P_521:
             return NID_secp521r1;
+        case EcCurve::CURVE_25519:
+            return NID_X25519;
     }
 }
 
@@ -6692,7 +6733,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/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp b/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
index 76fb79b..c9d506f 100644
--- a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
+++ b/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
@@ -236,9 +236,11 @@
     vector<Certificate> attested_key_cert_chain = std::move(creationResult.certificateChain);
     EXPECT_EQ(attested_key_cert_chain.size(), 1);
 
+    int32_t aidl_version = 0;
+    ASSERT_TRUE(keyMint->getInterfaceVersion(&aidl_version).isOk());
     AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
     AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
-    EXPECT_TRUE(verify_attestation_record("foo", "bar", sw_enforced, hw_enforced,
+    EXPECT_TRUE(verify_attestation_record(aidl_version, "foo", "bar", sw_enforced, hw_enforced,
                                           info.securityLevel,
                                           attested_key_cert_chain[0].encodedCertificate));
 
diff --git a/sensors/aidl/Android.bp b/sensors/aidl/Android.bp
new file mode 100644
index 0000000..7324abf
--- /dev/null
+++ b/sensors/aidl/Android.bp
@@ -0,0 +1,23 @@
+aidl_interface {
+    name: "android.hardware.sensors",
+    vendor_available: true,
+    srcs: ["android/hardware/sensors/*.aidl"],
+    imports: [
+        "android.hardware.common-V2",
+        "android.hardware.common.fmq-V1",
+    ],
+    stability: "vintf",
+    backend: {
+        cpp: {
+            enabled: false,
+        },
+        java: {
+            enabled: false,
+        },
+        ndk: {
+            vndk: {
+                enabled: true,
+            },
+        },
+    },
+}
diff --git a/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/AdditionalInfo.aidl b/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/AdditionalInfo.aidl
new file mode 100644
index 0000000..5184723
--- /dev/null
+++ b/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/AdditionalInfo.aidl
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.sensors;
+@FixedSize @VintfStability
+parcelable AdditionalInfo {
+  android.hardware.sensors.AdditionalInfo.AdditionalInfoType type;
+  int serial;
+  android.hardware.sensors.AdditionalInfo.AdditionalInfoPayload payload;
+  @FixedSize @VintfStability
+  union AdditionalInfoPayload {
+    android.hardware.sensors.AdditionalInfo.AdditionalInfoPayload.Int32Values dataInt32;
+    android.hardware.sensors.AdditionalInfo.AdditionalInfoPayload.FloatValues dataFloat;
+    @FixedSize @VintfStability
+    parcelable Int32Values {
+      int[14] values;
+    }
+    @FixedSize @VintfStability
+    parcelable FloatValues {
+      float[14] values;
+    }
+  }
+  @Backing(type="int") @VintfStability
+  enum AdditionalInfoType {
+    AINFO_BEGIN = 0,
+    AINFO_END = 1,
+    AINFO_UNTRACKED_DELAY = 65536,
+    AINFO_INTERNAL_TEMPERATURE = 65537,
+    AINFO_VEC3_CALIBRATION = 65538,
+    AINFO_SENSOR_PLACEMENT = 65539,
+    AINFO_SAMPLING = 65540,
+    AINFO_CHANNEL_NOISE = 131072,
+    AINFO_CHANNEL_SAMPLER = 131073,
+    AINFO_CHANNEL_FILTER = 131074,
+    AINFO_CHANNEL_LINEAR_TRANSFORM = 131075,
+    AINFO_CHANNEL_NONLINEAR_MAP = 131076,
+    AINFO_CHANNEL_RESAMPLER = 131077,
+    AINFO_LOCAL_GEOMAGNETIC_FIELD = 196608,
+    AINFO_LOCAL_GRAVITY = 196609,
+    AINFO_DOCK_STATE = 196610,
+    AINFO_HIGH_PERFORMANCE_MODE = 196611,
+    AINFO_MAGNETIC_FIELD_CALIBRATION = 196612,
+    AINFO_CUSTOM_START = 268435456,
+    AINFO_DEBUGGING_START = 1073741824,
+  }
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl b/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/DynamicSensorInfo.aidl
similarity index 80%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl
copy to sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/DynamicSensorInfo.aidl
index df07c9c..0c9a493 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl
+++ b/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/DynamicSensorInfo.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,9 +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;
-@VintfStability
-parcelable ColorTransformPayload {
-  float[] matrix;
-  android.hardware.graphics.common.ColorTransform hint;
+package android.hardware.sensors;
+@FixedSize @VintfStability
+parcelable DynamicSensorInfo {
+  boolean connected;
+  int sensorHandle;
+  android.hardware.sensors.DynamicSensorInfo.Uuid uuid;
+  @FixedSize @VintfStability
+  parcelable Uuid {
+    byte[16] values;
+  }
 }
diff --git a/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/Event.aidl b/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/Event.aidl
new file mode 100644
index 0000000..c92ab1a
--- /dev/null
+++ b/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/Event.aidl
@@ -0,0 +1,110 @@
+/*
+ * 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.sensors;
+@FixedSize @VintfStability
+parcelable Event {
+  long timestamp;
+  int sensorHandle;
+  android.hardware.sensors.SensorType sensorType;
+  android.hardware.sensors.Event.EventPayload payload;
+  @FixedSize @VintfStability
+  union EventPayload {
+    android.hardware.sensors.Event.EventPayload.Vec3 vec3;
+    android.hardware.sensors.Event.EventPayload.Vec4 vec4;
+    android.hardware.sensors.Event.EventPayload.Uncal uncal;
+    android.hardware.sensors.Event.EventPayload.MetaData meta;
+    float scalar;
+    long stepCount;
+    android.hardware.sensors.Event.EventPayload.HeartRate heartRate;
+    android.hardware.sensors.Event.EventPayload.Pose6Dof pose6DOF;
+    android.hardware.sensors.DynamicSensorInfo dynamic;
+    android.hardware.sensors.AdditionalInfo additional;
+    android.hardware.sensors.Event.EventPayload.Data data;
+    android.hardware.sensors.Event.EventPayload.HeadTracker headTracker;
+    @FixedSize @VintfStability
+    parcelable Vec4 {
+      float x;
+      float y;
+      float z;
+      float w;
+    }
+    @FixedSize @VintfStability
+    parcelable Vec3 {
+      float x;
+      float y;
+      float z;
+      android.hardware.sensors.SensorStatus status;
+    }
+    @FixedSize @VintfStability
+    parcelable Uncal {
+      float x;
+      float y;
+      float z;
+      float xBias;
+      float yBias;
+      float zBias;
+    }
+    @FixedSize @VintfStability
+    parcelable HeadTracker {
+      float rx;
+      float ry;
+      float rz;
+      float vx;
+      float vy;
+      float vz;
+      int discontinuityCount;
+    }
+    @FixedSize @VintfStability
+    parcelable HeartRate {
+      float bpm;
+      android.hardware.sensors.SensorStatus status;
+    }
+    @FixedSize @VintfStability
+    parcelable MetaData {
+      android.hardware.sensors.Event.EventPayload.MetaData.MetaDataEventType what;
+      @Backing(type="int") @VintfStability
+      enum MetaDataEventType {
+        META_DATA_FLUSH_COMPLETE = 1,
+      }
+    }
+    @FixedSize @VintfStability
+    parcelable Pose6Dof {
+      float[15] values;
+    }
+    @FixedSize @VintfStability
+    parcelable Data {
+      float[16] values;
+    }
+  }
+}
diff --git a/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/ISensors.aidl b/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/ISensors.aidl
new file mode 100644
index 0000000..f60f5bb
--- /dev/null
+++ b/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/ISensors.aidl
@@ -0,0 +1,89 @@
+/*
+ * 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.sensors;
+@VintfStability
+interface ISensors {
+  void activate(in int sensorHandle, in boolean enabled);
+  void batch(in int sensorHandle, in long samplingPeriodNs, in long maxReportLatencyNs);
+  int configDirectReport(in int sensorHandle, in int channelHandle, in android.hardware.sensors.ISensors.RateLevel rate);
+  void flush(in int sensorHandle);
+  android.hardware.sensors.SensorInfo[] getSensorsList();
+  void initialize(in android.hardware.common.fmq.MQDescriptor<android.hardware.sensors.Event,android.hardware.common.fmq.SynchronizedReadWrite> eventQueueDescriptor, in android.hardware.common.fmq.MQDescriptor<int,android.hardware.common.fmq.SynchronizedReadWrite> wakeLockDescriptor, in android.hardware.sensors.ISensorsCallback sensorsCallback);
+  void injectSensorData(in android.hardware.sensors.Event event);
+  int registerDirectChannel(in android.hardware.sensors.ISensors.SharedMemInfo mem);
+  void setOperationMode(in android.hardware.sensors.ISensors.OperationMode mode);
+  void unregisterDirectChannel(in int channelHandle);
+  const int ERROR_NO_MEMORY = -12;
+  const int ERROR_BAD_VALUE = -22;
+  const int WAKE_LOCK_TIMEOUT_SECONDS = 1;
+  const int EVENT_QUEUE_FLAG_BITS_READ_AND_PROCESS = 1;
+  const int EVENT_QUEUE_FLAG_BITS_EVENTS_READ = 2;
+  const int WAKE_LOCK_QUEUE_FLAG_BITS_DATA_WRITTEN = 1;
+  const int DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_FIELD = 0;
+  const int DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_REPORT_TOKEN = 4;
+  const int DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_SENSOR_TYPE = 8;
+  const int DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_ATOMIC_COUNTER = 12;
+  const int DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_TIMESTAMP = 16;
+  const int DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_DATA = 24;
+  const int DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_RESERVED = 88;
+  const int DIRECT_REPORT_SENSOR_EVENT_TOTAL_LENGTH = 104;
+  @Backing(type="int") @VintfStability
+  enum RateLevel {
+    STOP = 0,
+    NORMAL = 1,
+    FAST = 2,
+    VERY_FAST = 3,
+  }
+  @Backing(type="int") @VintfStability
+  enum OperationMode {
+    NORMAL = 0,
+    DATA_INJECTION = 1,
+  }
+  @VintfStability
+  parcelable SharedMemInfo {
+    android.hardware.sensors.ISensors.SharedMemInfo.SharedMemType type;
+    android.hardware.sensors.ISensors.SharedMemInfo.SharedMemFormat format;
+    int size;
+    android.hardware.common.NativeHandle memoryHandle;
+    @Backing(type="int") @VintfStability
+    enum SharedMemFormat {
+      SENSORS_EVENT = 1,
+    }
+    @Backing(type="int") @VintfStability
+    enum SharedMemType {
+      ASHMEM = 1,
+      GRALLOC = 2,
+    }
+  }
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl b/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/ISensorsCallback.aidl
similarity index 82%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl
copy to sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/ISensorsCallback.aidl
index df07c9c..78ab567 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl
+++ b/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/ISensorsCallback.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,9 +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.sensors;
 @VintfStability
-parcelable ColorTransformPayload {
-  float[] matrix;
-  android.hardware.graphics.common.ColorTransform hint;
+interface ISensorsCallback {
+  void onDynamicSensorsConnected(in android.hardware.sensors.SensorInfo[] sensorInfos);
+  void onDynamicSensorsDisconnected(in int[] sensorHandles);
 }
diff --git a/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/SensorInfo.aidl b/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/SensorInfo.aidl
new file mode 100644
index 0000000..996be3d
--- /dev/null
+++ b/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/SensorInfo.aidl
@@ -0,0 +1,71 @@
+/*
+ * 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.sensors;
+@VintfStability
+parcelable SensorInfo {
+  int sensorHandle;
+  String name;
+  String vendor;
+  int version;
+  android.hardware.sensors.SensorType type;
+  String typeAsString;
+  float maxRange;
+  float resolution;
+  float power;
+  int minDelayUs;
+  int fifoReservedEventCount;
+  int fifoMaxEventCount;
+  String requiredPermission;
+  int maxDelayUs;
+  int flags;
+  const int SENSOR_FLAG_BITS_WAKE_UP = 1;
+  const int SENSOR_FLAG_BITS_CONTINUOUS_MODE = 0;
+  const int SENSOR_FLAG_BITS_ON_CHANGE_MODE = 2;
+  const int SENSOR_FLAG_BITS_ONE_SHOT_MODE = 4;
+  const int SENSOR_FLAG_BITS_SPECIAL_REPORTING_MODE = 6;
+  const int SENSOR_FLAG_BITS_DATA_INJECTION = 16;
+  const int SENSOR_FLAG_BITS_DYNAMIC_SENSOR = 32;
+  const int SENSOR_FLAG_BITS_ADDITIONAL_INFO = 64;
+  const int SENSOR_FLAG_BITS_DIRECT_CHANNEL_ASHMEM = 1024;
+  const int SENSOR_FLAG_BITS_DIRECT_CHANNEL_GRALLOC = 2048;
+  const int SENSOR_FLAG_BITS_MASK_REPORTING_MODE = 14;
+  const int SENSOR_FLAG_BITS_MASK_DIRECT_REPORT = 896;
+  const int SENSOR_FLAG_BITS_MASK_DIRECT_CHANNEL = 3072;
+  const int SENSOR_FLAG_SHIFT_REPORTING_MODE = 1;
+  const int SENSOR_FLAG_SHIFT_DATA_INJECTION = 4;
+  const int SENSOR_FLAG_SHIFT_DYNAMIC_SENSOR = 5;
+  const int SENSOR_FLAG_SHIFT_ADDITIONAL_INFO = 6;
+  const int SENSOR_FLAG_SHIFT_DIRECT_REPORT = 7;
+  const int SENSOR_FLAG_SHIFT_DIRECT_CHANNEL = 10;
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl b/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/SensorStatus.aidl
similarity index 83%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl
copy to sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/SensorStatus.aidl
index df07c9c..4521710 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl
+++ b/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/SensorStatus.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,9 +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;
-@VintfStability
-parcelable ColorTransformPayload {
-  float[] matrix;
-  android.hardware.graphics.common.ColorTransform hint;
+package android.hardware.sensors;
+@Backing(type="byte") @VintfStability
+enum SensorStatus {
+  NO_CONTACT = -1,
+  UNRELIABLE = 0,
+  ACCURACY_LOW = 1,
+  ACCURACY_MEDIUM = 2,
+  ACCURACY_HIGH = 3,
 }
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl b/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/SensorType.aidl
similarity index 60%
copy from bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl
copy to sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/SensorType.aidl
index 9efafca..3d7ab45 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCapabilities.aidl
+++ b/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/SensorType.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright 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.
@@ -31,21 +31,45 @@
 // 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.bluetooth.audio;
-@VintfStability
-parcelable LeAudioCapabilities {
-  android.hardware.bluetooth.audio.LeAudioMode mode;
-  android.hardware.bluetooth.audio.CodecType codecType;
-  android.hardware.bluetooth.audio.AudioLocation supportedChannel;
-  int supportedChannelCount;
-  android.hardware.bluetooth.audio.LeAudioCapabilities.LeaudioCodecCapabilities leaudioCodecCapabilities;
-  @VintfStability
-  parcelable VendorCapabilities {
-    ParcelableHolder extension;
-  }
-  @VintfStability
-  union LeaudioCodecCapabilities {
-    android.hardware.bluetooth.audio.Lc3Capabilities lc3Capabilities;
-    android.hardware.bluetooth.audio.LeAudioCapabilities.VendorCapabilities vendorCapabillities;
-  }
+package android.hardware.sensors;
+@Backing(type="int") @VintfStability
+enum SensorType {
+  META_DATA = 0,
+  ACCELEROMETER = 1,
+  MAGNETIC_FIELD = 2,
+  ORIENTATION = 3,
+  GYROSCOPE = 4,
+  LIGHT = 5,
+  PRESSURE = 6,
+  PROXIMITY = 8,
+  GRAVITY = 9,
+  LINEAR_ACCELERATION = 10,
+  ROTATION_VECTOR = 11,
+  RELATIVE_HUMIDITY = 12,
+  AMBIENT_TEMPERATURE = 13,
+  MAGNETIC_FIELD_UNCALIBRATED = 14,
+  GAME_ROTATION_VECTOR = 15,
+  GYROSCOPE_UNCALIBRATED = 16,
+  SIGNIFICANT_MOTION = 17,
+  STEP_DETECTOR = 18,
+  STEP_COUNTER = 19,
+  GEOMAGNETIC_ROTATION_VECTOR = 20,
+  HEART_RATE = 21,
+  TILT_DETECTOR = 22,
+  WAKE_GESTURE = 23,
+  GLANCE_GESTURE = 24,
+  PICK_UP_GESTURE = 25,
+  WRIST_TILT_GESTURE = 26,
+  DEVICE_ORIENTATION = 27,
+  POSE_6DOF = 28,
+  STATIONARY_DETECT = 29,
+  MOTION_DETECT = 30,
+  HEART_BEAT = 31,
+  DYNAMIC_SENSOR_META = 32,
+  ADDITIONAL_INFO = 33,
+  LOW_LATENCY_OFFBODY_DETECT = 34,
+  ACCELEROMETER_UNCALIBRATED = 35,
+  HINGE_ANGLE = 36,
+  HEAD_TRACKER = 37,
+  DEVICE_PRIVATE_BASE = 65536,
 }
diff --git a/sensors/aidl/android/hardware/sensors/AdditionalInfo.aidl b/sensors/aidl/android/hardware/sensors/AdditionalInfo.aidl
new file mode 100644
index 0000000..9fe2d39
--- /dev/null
+++ b/sensors/aidl/android/hardware/sensors/AdditionalInfo.aidl
@@ -0,0 +1,234 @@
+/*
+ * 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.sensors;
+
+@FixedSize
+@VintfStability
+parcelable AdditionalInfo {
+    /**
+     * type of payload data, see AdditionalInfoType
+     */
+    AdditionalInfoType type;
+
+    /**
+     * sequence number of this frame for this type
+     */
+    int serial;
+
+    AdditionalInfoPayload payload;
+
+    @FixedSize
+    @VintfStability
+    union AdditionalInfoPayload {
+        Int32Values dataInt32;
+        FloatValues dataFloat;
+
+        @FixedSize
+        @VintfStability
+        parcelable Int32Values {
+            int[14] values;
+        }
+
+        @FixedSize
+        @VintfStability
+        parcelable FloatValues {
+            float[14] values;
+        }
+    }
+
+    @VintfStability
+    @Backing(type="int")
+    enum AdditionalInfoType {
+        /**
+         * Marks the beginning of additional information frames
+         */
+        AINFO_BEGIN = 0,
+
+        /**
+         * Marks the end of additional information frames
+         */
+        AINFO_END = 1,
+
+        /**
+         * Estimation of the delay that is not tracked by sensor timestamps. This
+         * includes delay introduced by sensor front-end filtering, data transport,
+         * etc.
+         * float[2]: delay in seconds, standard deviation of estimated value
+         */
+        AINFO_UNTRACKED_DELAY = 0x10000,
+
+        /**
+         * float: Celsius temperature
+         */
+        AINFO_INTERNAL_TEMPERATURE,
+
+        /**
+         * First three rows of a homogeneous matrix, which represents calibration to
+         * a three-element vector raw sensor reading.
+         * float[12]: 3x4 matrix in row major order
+         */
+        AINFO_VEC3_CALIBRATION,
+
+        /**
+         * Provides the orientation and location of the sensor element in terms of
+         * the Android coordinate system. This data is given as a 3x4 matrix
+         * consisting of a 3x3 rotation matrix (R) concatenated with a 3x1 location
+         * vector (t). The rotation matrix provides the orientation of the Android
+         * device coordinate frame relative to the local coordinate frame of the
+         * sensor. Note that assuming the axes conventions of the sensor are the
+         * same as Android, this is the inverse of the matrix applied to raw
+         * samples read from the sensor to convert them into the Android
+         * representation. The location vector represents the translation from the
+         * origin of the Android sensor coordinate system to the geometric center
+         * of the sensor, specified in millimeters (mm).
+         *
+         * float[12]: 3x4 matrix in row major order [R; t]
+         *
+         * Example:
+         *     This raw buffer: {0, 1, 0, 0, -1, 0, 0, 10, 0, 0, 1, -2.5}
+         *     Corresponds to this 3x4 matrix:
+         *         0 1 0    0
+         *        -1 0 0   10
+         *         0 0 1 -2.5
+         *     The sensor is oriented such that:
+         *         - the device X axis corresponds to the sensor's local -Y axis
+         *         - the device Y axis corresponds to the sensor's local X axis
+         *         - the device Z axis and sensor's local Z axis are equivalent
+         *     In other words, if viewing the origin of the Android coordinate
+         *     system from the positive Z direction, the device coordinate frame is
+         *     to be rotated 90 degrees counter-clockwise about the Z axis to align
+         *     with the sensor's local coordinate frame. Equivalently, a vector in
+         *     the Android coordinate frame may be multiplied with R to rotate it
+         *     90 degrees clockwise (270 degrees counter-clockwise), yielding its
+         *     representation in the sensor's coordinate frame.
+         *     Relative to the origin of the Android coordinate system, the physical
+         *     center of the sensor is located 10mm in the positive Y direction, and
+         *     2.5mm in the negative Z direction.
+         */
+        AINFO_SENSOR_PLACEMENT,
+
+        /**
+         * float[2]: raw sample period in seconds,
+         *           standard deviation of sampling period
+         */
+        AINFO_SAMPLING,
+
+        /**
+         * int32_t: noise type
+         * float[n]: parameters
+         */
+        AINFO_CHANNEL_NOISE = 0x20000,
+
+        /**
+         * float[3]: sample period, standard deviation of sample period,
+         * quantization unit
+         */
+        AINFO_CHANNEL_SAMPLER,
+
+        /**
+         * Represents a filter:
+         *   \sum_j a_j y[n-j] == \sum_i b_i x[n-i]
+         *
+         * int32_t[3]: number of feedforward coeffients M,
+         *             number of feedback coefficients N (for FIR filter, N = 1).
+         *             bit mask that represents which element the filter is applied
+         *             to. (bit 0==1 means this filter applies to vector element 0).
+         * float[M+N]: filter coefficients (b0, b1, ..., b_{M-1}), then
+         *             (a0, a1, ..., a_{N-1}), a0 is always 1.
+         *
+         * Multiple frames may be needed for higher number of taps.
+         */
+        AINFO_CHANNEL_FILTER,
+
+        /**
+         * int32_t[2]: size in (row, column) ... 1st frame
+         * float[n]: matrix element values in row major order.
+         */
+        AINFO_CHANNEL_LINEAR_TRANSFORM,
+
+        /**
+         * int32_t[2]: extrapolate method, interpolate method
+         * float[n]: mapping key points in pairs, (in, out)...
+         *           (may be used to model saturation).
+         */
+        AINFO_CHANNEL_NONLINEAR_MAP,
+
+        /**
+         * int32_t: resample method (0-th order, 1st order...)
+         * float[1]: resample ratio (upsampling if < 1.0, downsampling if > 1.0).
+         */
+        AINFO_CHANNEL_RESAMPLER,
+
+        /**
+         * Operation environment parameters section
+         * Types in the following section is sent down (instead of reported from)
+         * device as additional information to aid sensor operation. Data is sent
+         * via injectSensorData() function to sensor handle -1 denoting all sensors
+         * in device.
+         *
+         *
+         * Local geomagnetic field information based on device geo location. This
+         * type is primarily for for magnetic field calibration and rotation vector
+         * sensor fusion.
+         * float[3]: strength (uT), declination and inclination angle (rad).
+         */
+        AINFO_LOCAL_GEOMAGNETIC_FIELD = 0x30000,
+
+        /**
+         * Local gravitational acceleration strength at device geo location.
+         * float: gravitational acceleration norm in m/s^2.
+         */
+        AINFO_LOCAL_GRAVITY,
+
+        /**
+         * Device dock state.
+         * int32_t: dock state following Android API Intent.EXTRA_DOCK_STATE
+         * definition, undefined value is ignored.
+         */
+        AINFO_DOCK_STATE,
+
+        /**
+         * High performance mode hint. Device is able to use up more power and take
+         * more resources to improve throughput and latency in high performance mode.
+         * One possible use case is virtual reality, when sensor latency need to be
+         * carefully controlled.
+         * int32_t: 1 or 0, denote if device is in/out of high performance mode,
+         *          other values is ignored.
+         */
+        AINFO_HIGH_PERFORMANCE_MODE,
+
+        /**
+         * Magnetic field calibration hint. Device is notified when manually
+         * triggered magnetic field calibration procedure is started or stopped. The
+         * calibration procedure is assumed timed out after 1 minute from start,
+         * even if an explicit stop is not received.
+         *
+         * int32_t: 1 for start, 0 for stop, other value is ignored.
+         */
+        AINFO_MAGNETIC_FIELD_CALIBRATION,
+
+        /**
+         * Custom information
+         */
+        AINFO_CUSTOM_START = 0x10000000,
+
+        /**
+         * Debugging
+         */
+        AINFO_DEBUGGING_START = 0x40000000,
+    }
+}
diff --git a/sensors/aidl/android/hardware/sensors/DynamicSensorInfo.aidl b/sensors/aidl/android/hardware/sensors/DynamicSensorInfo.aidl
new file mode 100644
index 0000000..4b14ed0
--- /dev/null
+++ b/sensors/aidl/android/hardware/sensors/DynamicSensorInfo.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.sensors;
+
+@VintfStability
+@FixedSize
+parcelable DynamicSensorInfo {
+    boolean connected;
+
+    int sensorHandle;
+
+    /**
+     * UUID of a dynamic sensor (using RFC 4122 byte order)
+     * For UUID 12345678-90AB-CDEF-1122-334455667788 the uuid field is
+     * initialized as:
+     *   {0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, 0x11, ...}
+     */
+    Uuid uuid;
+
+    @FixedSize
+    @VintfStability
+    parcelable Uuid {
+        byte[16] values;
+    }
+}
diff --git a/sensors/aidl/android/hardware/sensors/Event.aidl b/sensors/aidl/android/hardware/sensors/Event.aidl
new file mode 100644
index 0000000..fd6a8cc
--- /dev/null
+++ b/sensors/aidl/android/hardware/sensors/Event.aidl
@@ -0,0 +1,243 @@
+/*
+ * 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.sensors;
+
+import android.hardware.sensors.AdditionalInfo;
+import android.hardware.sensors.DynamicSensorInfo;
+import android.hardware.sensors.SensorStatus;
+import android.hardware.sensors.SensorType;
+
+@VintfStability
+@FixedSize
+parcelable Event {
+    /**
+     * Time measured in nanoseconds, in "elapsedRealtimeNano()'s" timebase.
+     */
+    long timestamp;
+
+    /**
+     * sensor identifier
+     */
+    int sensorHandle;
+
+    SensorType sensorType;
+
+    /**
+     * Union discriminated on sensorType
+     */
+    EventPayload payload;
+
+    /*
+     * acceleration values are in meter per second per second (m/s^2)
+     * magnetic vector values are in micro-Tesla (uT)
+     * orientation values are in degrees
+     * gyroscope values are in rad/s
+     * temperature is in degrees centigrade (Celsius)
+     * distance in centimeters
+     * light in SI lux units
+     * pressure in hectopascal (hPa)
+     * relative humidity in percent
+     */
+    @VintfStability
+    @FixedSize
+    union EventPayload {
+        /**
+         * SensorType::ACCELEROMETER, SensorType::MAGNETIC_FIELD,
+         * SensorType::ORIENTATION, SensorType::GYROSCOPE, SensorType::GRAVITY,
+         * SensorType::LINEAR_ACCELERATION
+         */
+        Vec3 vec3;
+
+        /**
+         * SensorType::GAME_ROTATION_VECTOR
+         */
+        Vec4 vec4;
+
+        /**
+         * SensorType::MAGNETIC_FIELD_UNCALIBRATED,
+         * SensorType::GYROSCOPE_UNCALIBRATED
+         * SensorType::ACCELEROMETER_UNCALIBRATED
+         */
+        Uncal uncal;
+
+        /**
+         * SensorType::META_DATA
+         */
+        MetaData meta;
+
+        /**
+         * SensorType::DEVICE_ORIENTATION, SensorType::LIGHT, SensorType::PRESSURE,
+         * SensorType::TEMPERATURE, SensorType::PROXIMITY,
+         * SensorType::RELATIVE_HUMIDITY, SensorType::AMBIENT_TEMPERATURE,
+         * SensorType::SIGNIFICANT_MOTION, SensorType::STEP_DETECTOR,
+         * SensorType::TILT_DETECTOR, SensorType::WAKE_GESTURE,
+         * SensorType::GLANCE_GESTURE, SensorType::PICK_UP_GESTURE,
+         * SensorType::WRIST_TILT_GESTURE, SensorType::STATIONARY_DETECT,
+         * SensorType::MOTION_DETECT, SensorType::HEART_BEAT,
+         * SensorType::LOW_LATENCY_OFFBODY_DETECT
+         */
+        float scalar;
+
+        /**
+         * SensorType::STEP_COUNTER
+         */
+        long stepCount;
+
+        /**
+         * SensorType::HEART_RATE
+         */
+        HeartRate heartRate;
+
+        /**
+         * SensorType::POSE_6DOF
+         */
+        Pose6Dof pose6DOF;
+
+        /**
+         * SensorType::DYNAMIC_SENSOR_META
+         */
+        DynamicSensorInfo dynamic;
+
+        /**
+         * SensorType::ADDITIONAL_INFO
+         */
+        AdditionalInfo additional;
+
+        /**
+         * The following sensors should use the data field:
+         * - Undefined/custom sensor type >= SensorType::DEVICE_PRIVATE_BASE
+         * - SensorType::ROTATION_VECTOR, SensorType::GEOMAGNETIC_ROTATION_VECTOR:
+         *   - These are Vec4 types with an additional float accuracy field,
+         *     where data[4] is the estimated heading accuracy in radians
+         *     (-1 if unavailable, and invalid if not in the range (0, 2 * pi]).
+         */
+        Data data;
+
+        /**
+         * SensorType::HEAD_TRACKER
+         */
+        HeadTracker headTracker;
+
+        @FixedSize
+        @VintfStability
+        parcelable Vec4 {
+            float x;
+            float y;
+            float z;
+            float w;
+        }
+
+        @FixedSize
+        @VintfStability
+        parcelable Vec3 {
+            float x;
+            float y;
+            float z;
+            SensorStatus status;
+        }
+
+        @FixedSize
+        @VintfStability
+        parcelable Uncal {
+            float x;
+            float y;
+            float z;
+            float xBias;
+            float yBias;
+            float zBias;
+        }
+
+        /**
+         * Payload of the HEAD_TRACKER sensor type. Note that the axis
+         * definition of this sensor type differs from the rest of Android. See
+         * SensorType::HEAD_TRACKER for more information.
+         */
+        @FixedSize
+        @VintfStability
+        parcelable HeadTracker {
+            /**
+             * An Euler vector (rotation vector, i.e. a vector whose direction
+             * indicates the axis of rotation and magnitude indicates the angle
+             * to rotate around that axis) representing the transform from
+             * the (arbitrary, possibly slowly drifting) reference frame to the
+             * head frame. Expressed in radians. Magnitude of the vector must be
+             * in the range [0, pi], while the value of individual axes are
+             * in the range [-pi, pi].
+             */
+            float rx;
+            float ry;
+            float rz;
+
+            /**
+             * An Euler vector (rotation vector) representing the angular
+             * velocity of the head (relative to itself), in radians per second.
+             * The direction of this vector indicates the axis of rotation, and
+             * the magnitude indicates the rate of rotation.
+             */
+            float vx;
+            float vy;
+            float vz;
+
+            /**
+             * This value increments (or wraps around to 0) each time the
+             * reference frame is suddenly and significantly changed, for
+             * example if an orientation filter algorithm used for determining
+             * the orientation has had its state reset.
+             */
+            int discontinuityCount;
+        }
+
+        @FixedSize
+        @VintfStability
+        parcelable HeartRate {
+            /**
+             * Heart rate in beats per minute.
+             * Set to 0 when status is SensorStatus::UNRELIABLE or
+             * SensorStatus::NO_CONTACT
+             */
+            float bpm;
+            /**
+             * Status of the heart rate sensor for this reading.
+             */
+            SensorStatus status;
+        }
+
+        @FixedSize
+        @VintfStability
+        parcelable MetaData {
+            MetaDataEventType what;
+
+            @VintfStability
+            @Backing(type="int")
+            enum MetaDataEventType {
+                META_DATA_FLUSH_COMPLETE = 1,
+            }
+        }
+
+        @FixedSize
+        @VintfStability
+        parcelable Pose6Dof {
+            float[15] values;
+        }
+
+        @FixedSize
+        @VintfStability
+        parcelable Data {
+            float[16] values;
+        }
+    }
+}
diff --git a/sensors/aidl/android/hardware/sensors/ISensors.aidl b/sensors/aidl/android/hardware/sensors/ISensors.aidl
new file mode 100644
index 0000000..2ac1884
--- /dev/null
+++ b/sensors/aidl/android/hardware/sensors/ISensors.aidl
@@ -0,0 +1,375 @@
+/*
+ * 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.sensors;
+
+import android.hardware.common.NativeHandle;
+import android.hardware.common.fmq.MQDescriptor;
+import android.hardware.common.fmq.SynchronizedReadWrite;
+import android.hardware.sensors.Event;
+import android.hardware.sensors.ISensorsCallback;
+import android.hardware.sensors.SensorInfo;
+
+@VintfStability
+interface ISensors {
+    /**
+     * Activate/de-activate one sensor.
+     *
+     * After sensor de-activation, existing sensor events that have not
+     * been written to the event queue must be abandoned immediately so that
+     * subsequent activations do not get stale sensor events (events
+     * that are generated prior to the latter activation).
+     *
+     * @param sensorHandle is the handle of the sensor to change.
+     * @param enabled set to true to enable, or false to disable the sensor.
+     * @return Status::ok on success
+     *         EX_ILLEGAL_ARGUMENT if the sensorHandle is invalid.
+     */
+    void activate(in int sensorHandle, in boolean enabled);
+
+    /**
+     * Sets a sensor’s parameters, including sampling frequency and maximum
+     * report latency. This function can be called while the sensor is
+     * activated, in which case it must not cause any sensor measurements to
+     * be lost: transitioning from one sampling rate to the other cannot cause
+     * lost events, nor can transitioning from a high maximum report latency to
+     * a low maximum report latency.
+     *
+     * @param sensorHandle handle of sensor to be changed.
+     * @param samplingPeriodNs specifies sensor sample period in nanoseconds.
+     * @param maxReportLatencyNs allowed delay time before an event is sampled
+     *     to time of report.
+     * @return Status::ok on success
+     *         EX_ILLEGAL_ARGUMENT if any parameters are invalid.
+     */
+    void batch(in int sensorHandle, in long samplingPeriodNs, in long maxReportLatencyNs);
+
+    /**
+     * Configure direct sensor event report in direct channel.
+     *
+     * This function start, modify rate or stop direct report of a sensor in a
+     * certain direct channel.
+     *
+     * @param sensorHandle handle of sensor to be configured. When combined
+     *     with STOP rate, sensorHandle can be -1 to denote all active sensors
+     *     in the direct channel specified by channel Handle.
+     * @param channelHandle handle of direct channel to be configured.
+     * @param rate rate level, see RateLevel enum.
+     * @param out reportToken The report token, ignored if rate is STOP.
+     *     See SharedMemFormat.
+     * @return The direct report token to identify multiple sensors of the same type in a single
+     *         direct channel.
+     * @return Status::ok on success
+     *         EX_ILLEGAL_ARGUMENT if the parameter is invalid (e.g. unsupported rate level
+     *          for sensor, channelHandle does not exist, etc).
+     *         EX_UNSUPPORTED_OPERATION if this functionality is unsupported.
+     */
+    int configDirectReport(in int sensorHandle, in int channelHandle, in RateLevel rate);
+
+    /**
+     * Trigger a flush of internal FIFO.
+     *
+     * Flush adds a FLUSH_COMPLETE metadata event to the end of the "batch mode"
+     * FIFO for the specified sensor and flushes the FIFO.  If the FIFO is empty
+     * or if the sensor doesn't support batching (FIFO size zero), return
+     * SUCCESS and add a trivial FLUSH_COMPLETE event added to the event stream.
+     * This applies to all sensors other than one-shot sensors. If the sensor
+     * is a one-shot sensor, flush must return EX_ILLEGAL_ARGUMENT and not generate any
+     * flush complete metadata.  If the sensor is not active at the time flush()
+     * is called, flush() return EX_ILLEGAL_ARGUMENT.
+     *
+     * @param sensorHandle handle of sensor to be flushed.
+     * @return Status::ok on success
+     *         EX_ILLEGAL_ARGUMENT if the sensorHandle is invalid.
+     */
+    void flush(in int sensorHandle);
+
+    /**
+     * Enumerate all available (static) sensors.
+     *
+     * The SensorInfo for each sensor returned by getSensorsList must be stable
+     * from the initial call to getSensorsList after a device boot until the
+     * entire system restarts. The SensorInfo for each sensor must not change
+     * between subsequent calls to getSensorsList, even across restarts of the
+     * HAL and its dependencies (for example, the sensor handle for a given
+     * sensor must not change across HAL restarts).
+     */
+    SensorInfo[] getSensorsList();
+
+    /**
+     * Initialize the Sensors HAL's Fast Message Queues (FMQ) and callback.
+     *
+     * The Fast Message Queues (FMQ) that are used to send data between the
+     * framework and the HAL. The callback is used by the HAL to notify the
+     * framework of asynchronous events, such as a dynamic sensor connection.
+     *
+     * The Event FMQ is used to transport sensor events from the HAL to the
+     * framework. The Event FMQ is created using the eventQueueDescriptor.
+     * Data may only be written to the Event FMQ. Data must not be read from
+     * the Event FMQ since the framework is the only reader. Upon receiving
+     * sensor events, the HAL writes the sensor events to the Event FMQ.
+     *
+     * Once the HAL is finished writing sensor events to the Event FMQ, the HAL
+     * must notify the framework that sensor events are available to be read and
+     * processed. This is accomplished by either:
+     *     1) Calling the Event FMQ’s EventFlag::wake() function with
+     * EventQueueFlagBits::READ_AND_PROCESS
+     *     2) Setting the write notification in the Event FMQ’s writeBlocking()
+     *        function to EventQueueFlagBits::READ_AND_PROCESS.
+     *
+     * If the Event FMQ’s writeBlocking() function is used, the read
+     * notification must be set to EventQueueFlagBits::EVENTS_READ in order to
+     * be notified and unblocked when the framework has successfully read events
+     * from the Event FMQ.
+     *
+     * The Wake Lock FMQ is used by the framework to notify the HAL when it is
+     * safe to release its wake_lock. When the framework receives WAKE_UP events
+     * from the Event FMQ and the framework has acquired a wake_lock, the
+     * framework must write the number of WAKE_UP events processed to the Wake
+     * Lock FMQ. When the HAL reads the data from the Wake Lock FMQ, the HAL
+     * decrements its current count of unprocessed WAKE_UP events and releases
+     * its wake_lock if the current count of unprocessed WAKE_UP events is
+     * zero. It is important to note that the HAL must acquire the wake lock and
+     * update its internal state regarding the number of outstanding WAKE_UP
+     * events _before_ posting the event to the Wake Lock FMQ, in order to avoid
+     * a race condition that can lead to loss of wake lock synchronization with
+     * the framework.
+     *
+     * The framework must use the WAKE_LOCK_QUEUE_FLAG_BITS_DATA_WRITTEN value to
+     * notify the HAL that data has been written to the Wake Lock FMQ and must
+     * be read by HAL.
+     *
+     * The ISensorsCallback is used by the HAL to notify the framework of
+     * asynchronous events, such as a dynamic sensor connection.
+     *
+     * The name of any wake_lock acquired by the Sensors HAL for WAKE_UP events
+     * must begin with "SensorsHAL_WAKEUP".
+     *
+     * If WAKE_LOCK_TIMEOUT_SECONDS has elapsed since the most recent WAKE_UP
+     * event was written to the Event FMQ without receiving a message on the
+     * Wake Lock FMQ, then any held wake_lock for WAKE_UP events must be
+     * released.
+     *
+     * If either the Event FMQ or the Wake Lock FMQ is already initialized when
+     * initialize is invoked, then both existing FMQs must be discarded and the
+     * new descriptors must be used to create new FMQs within the HAL. The
+     * number of outstanding WAKE_UP events should also be reset to zero, and
+     * any outstanding wake_locks held as a result of WAKE_UP events should be
+     * released.
+     *
+     * All active sensor requests and direct channels must be closed and
+     * properly cleaned up when initialize is called in order to ensure that the
+     * HAL and framework's state is consistent (e.g. after a runtime restart).
+     *
+     * initialize must be thread safe and prevent concurrent calls
+     * to initialize from simultaneously modifying state.
+     *
+     * @param eventQueueDescriptor Fast Message Queue descriptor that is used to
+     *     create the Event FMQ which is where sensor events are written. The
+     *     descriptor is obtained from the framework's FMQ that is used to read
+     *     sensor events.
+     * @param wakeLockDescriptor Fast Message Queue descriptor that is used to
+     *     create the Wake Lock FMQ which is where wake_lock events are read
+     *     from. The descriptor is obtained from the framework's FMQ that is
+     *     used to write wake_lock events.
+     * @param sensorsCallback sensors callback that receives asynchronous data
+     *     from the Sensors HAL.
+     * @return Status::ok on success
+     *         EX_ILLEGAL_ARGUMENT if the descriptor is invalid (such as null).
+     */
+    void initialize(in MQDescriptor<Event, SynchronizedReadWrite> eventQueueDescriptor,
+            in MQDescriptor<int, SynchronizedReadWrite> wakeLockDescriptor,
+            in ISensorsCallback sensorsCallback);
+
+    /**
+     * Inject a single sensor event or push operation environment parameters to
+     * device.
+     *
+     * When device is in NORMAL mode, this function is called to push operation
+     * environment data to device. In this operation, Event is always of
+     * SensorType::AdditionalInfo type. See operation environment parameters
+     * section in AdditionalInfoType.
+     *
+     * When device is in DATA_INJECTION mode, this function is also used for
+     * injecting sensor events.
+     *
+     * Regardless of OperationMode, injected SensorType::ADDITIONAL_INFO
+     * type events should not be routed back to the sensor event queue.
+     *
+     * @see AdditionalInfoType
+     * @see OperationMode
+     * @param event sensor event to be injected
+     * @return Status::ok on success
+     *         EX_UNSUPPORTED_OPERATION if this functionality is unsupported.
+     *         EX_SECURITY if the operation is not allowed.
+     *         EX_SERVICE_SPECIFIC on error
+     *         - ERROR_BAD_VALUE if the sensor event cannot be injected.
+     */
+    void injectSensorData(in Event event);
+
+    /**
+     * Register direct report channel.
+     *
+     * Register a direct channel with supplied shared memory information. Upon
+     * return, the sensor hardware is responsible for resetting the memory
+     * content to initial value (depending on memory format settings).
+     *
+     * @param mem shared memory info data structure.
+     * @param out channelHandle The registered channel handle.
+     * @return The direct channel handle, which is positive if successfully registered, and -1
+     *         otherwise.
+     * @return Status::ok on success
+     *         EX_ILLEGAL_ARGUMENT if the shared memory information is not consistent.
+     *         EX_UNSUPPORTED_OPERATION if this functionality is unsupported.
+     *         EX_SERVICE_SPECIFIC on error
+     *         - ERROR_NO_MEMORY if shared memory cannot be used by sensor system.
+     */
+    int registerDirectChannel(in SharedMemInfo mem);
+
+    /**
+     * Place the module in a specific mode.
+     *
+     * @see OperationMode
+     * @param mode The operation mode.
+     * @return Status::ok on success
+     *         EX_UNSUPPORTED_OPERATION if requested mode is not supported.
+     *         EX_SECURITY if the operation is not allowed.
+     */
+    void setOperationMode(in OperationMode mode);
+
+    /**
+     * Unregister direct report channel.
+     *
+     * Unregister a direct channel previously registered using
+     * registerDirectChannel, and remove all active sensor report configured in
+     * still active sensor report configured in the direct channel.
+     *
+     * @param channelHandle handle of direct channel to be unregistered.
+     * @return Status::ok on success
+     *         EX_UNSUPPORTED_OPERATION if direct report is not supported.
+     */
+    void unregisterDirectChannel(in int channelHandle);
+
+    /**
+     * Direct report rate level definition. Except for SENSOR_DIRECT_RATE_STOP, each
+     * rate level covers the range (55%, 220%] * nominal report rate. For example,
+     * if config direct report specify a rate level SENSOR_DIRECT_RATE_FAST, it is
+     * legal for sensor hardware to report event at a rate greater than 110Hz, and
+     * less or equal to 440Hz. Note that rate has to remain steady without variation
+     * before new rate level is configured, i.e. if a sensor is configured to
+     * SENSOR_DIRECT_RATE_FAST and starts to report event at 256Hz, it cannot
+     * change rate to 128Hz after a few seconds of running even if 128Hz is also in
+     * the legal range of SENSOR_DIRECT_RATE_FAST. Thus, it is recommended to
+     * associate report rate with RateLvel statically for single sensor.
+     */
+    @VintfStability
+    @Backing(type="int")
+    enum RateLevel {
+        STOP,
+        NORMAL,
+        FAST,
+        VERY_FAST,
+    }
+
+    @VintfStability
+    @Backing(type="int")
+    enum OperationMode {
+        // Normal operation. Default state of the module.
+        NORMAL = 0,
+        // Loopback mode. Data is injected for the supported sensors by the sensor service in this
+        // mode.
+        DATA_INJECTION = 1,
+    }
+
+    @VintfStability
+    parcelable SharedMemInfo {
+        SharedMemType type;
+        SharedMemFormat format;
+        int size;
+        NativeHandle memoryHandle;
+
+        @VintfStability
+        @Backing(type="int")
+        enum SharedMemFormat {
+            SENSORS_EVENT = 1,
+        }
+
+        @VintfStability
+        @Backing(type="int")
+        enum SharedMemType {
+            ASHMEM = 1,
+            GRALLOC,
+        }
+    }
+
+    /**
+     * Error codes that are used as service specific errors with the AIDL return
+     * value EX_SERVICE_SPECIFIC.
+     */
+    const int ERROR_NO_MEMORY = -12;
+    const int ERROR_BAD_VALUE = -22;
+
+    /**
+     * The maximum number of seconds to wait for a message on the Wake Lock FMQ
+     * before automatically releasing any wake_lock held for a WAKE_UP event.
+     */
+    const int WAKE_LOCK_TIMEOUT_SECONDS = 1;
+
+    /**
+     * Used to notify the Event FMQ that events should be read and processed.
+     */
+    const int EVENT_QUEUE_FLAG_BITS_READ_AND_PROCESS = 1 << 0;
+
+    /**
+     * Used by the framework to signal to the HAL when events have been
+     * successfully read from the Event FMQ.
+     *
+     * If the MessageQueue::writeBlocking function is being used to write sensor
+     * events to the Event FMQ, then the readNotification parameter must be set
+     * to EVENTS_READ.
+     */
+    const int EVENT_QUEUE_FLAG_BITS_EVENTS_READ = 1 << 1;
+
+    /**
+     * Used to notify the HAL that the framework has written data to the Wake
+     * Lock FMQ.
+     */
+    const int WAKE_LOCK_QUEUE_FLAG_BITS_DATA_WRITTEN = 1 << 0;
+
+    /**
+     * Constants related to direct sensor events. The following table illustrates the
+     * data format.
+     *
+     * Offset   Type        Name
+     * -----------------------------------
+     * 0x0000   int32_t     Size (always DIRECT_REPORT_SENSOR_EVENT_TOTAL_LENGTH)
+     * 0x0004   int32_t     Sensor report token
+     * 0x0008   int32_t     Type (see SensorType.aidl)
+     * 0x000C   uint32_t    Atomic counter
+     * 0x0010   int64_t     Timestamp (see Event.aidl)
+     * 0x0018   float[16]/  Data
+     *          int64_t[8]
+     * 0x0058   int32_t[4]  Reserved (set to zero)
+     */
+    const int DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_FIELD = 0x0;
+    const int DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_REPORT_TOKEN = 0x4;
+    const int DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_SENSOR_TYPE = 0x8;
+    const int DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_ATOMIC_COUNTER = 0xC;
+    const int DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_TIMESTAMP = 0x10;
+    const int DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_DATA = 0x18;
+    const int DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_RESERVED = 0x58;
+    const int DIRECT_REPORT_SENSOR_EVENT_TOTAL_LENGTH = 104;
+}
diff --git a/sensors/aidl/android/hardware/sensors/ISensorsCallback.aidl b/sensors/aidl/android/hardware/sensors/ISensorsCallback.aidl
new file mode 100644
index 0000000..01bae52
--- /dev/null
+++ b/sensors/aidl/android/hardware/sensors/ISensorsCallback.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.sensors;
+
+import android.hardware.sensors.SensorInfo;
+
+@VintfStability
+interface ISensorsCallback {
+    /**
+     * Notify the framework that new dynamic sensors have been connected.
+     *
+     * If a dynamic sensor was previously connected and has not been
+     * disconnected, then that sensor must not be included in sensorInfos.
+     *
+     * @param sensorInfos vector of SensorInfo for each dynamic sensor that
+     *     was connected.
+     */
+    void onDynamicSensorsConnected(in SensorInfo[] sensorInfos);
+
+    /**
+     * Notify the framework that previously connected dynamic sensors have been
+     * disconnected.
+     *
+     * If a dynamic sensor was previously disconnected and has not been
+     * reconnected, then that sensor must not be included in sensorHandles.
+     *
+     * The HAL must ensure that all sensor events from departing dynamic
+     * sensors have been written to the Event FMQ before calling
+     * onDynamicSensorsDisconnected.
+     *
+     * @param sensorHandles vector of sensor handles for each dynamic sensors
+     *     that was disconnected.
+     */
+    void onDynamicSensorsDisconnected(in int[] sensorHandles);
+}
diff --git a/sensors/aidl/android/hardware/sensors/SensorInfo.aidl b/sensors/aidl/android/hardware/sensors/SensorInfo.aidl
new file mode 100644
index 0000000..35caf8b
--- /dev/null
+++ b/sensors/aidl/android/hardware/sensors/SensorInfo.aidl
@@ -0,0 +1,217 @@
+/*
+ * 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.sensors;
+
+import android.hardware.sensors.SensorType;
+
+@VintfStability
+parcelable SensorInfo {
+    /**
+     * handle that identifies this sensors. This handle is used to reference
+     * this sensor throughout the HAL API.
+     */
+    int sensorHandle;
+
+    /**
+     * Name of this sensor.
+     * All sensors of the same "type" must have a different "name".
+     */
+    String name;
+
+    /**
+     * vendor of the hardware part
+     */
+    String vendor;
+
+    /**
+     * version of the hardware part + driver. The value of this field
+     * must increase when the driver is updated in a way that changes the
+     * output of this sensor. This is important for fused sensors when the
+     * fusion algorithm is updated.
+     */
+    int version;
+
+    /**
+     * this sensor's type.
+     */
+    SensorType type;
+
+    /**
+     * type of this sensor as a string.
+     *
+     * When defining an OEM specific sensor or sensor manufacturer specific
+     * sensor, use your reserve domain name as a prefix.
+     * e.g. com.google.glass.onheaddetector
+     *
+     * For sensors of known type defined in SensorType (value <
+     * SensorType::DEVICE_PRIVATE_BASE), this can be an empty string.
+     */
+    String typeAsString;
+
+    /**
+     * maximum range of this sensor's value in SI units
+     */
+    float maxRange;
+
+    /**
+     * smallest difference between two values reported by this sensor
+     */
+    float resolution;
+
+    /**
+     * rough estimate of this sensor's power consumption in mA
+     */
+    float power;
+
+    /**
+     * this value depends on the reporting mode:
+     *
+     *   continuous: minimum sample period allowed in microseconds
+     *   on-change : 0
+     *   one-shot  :-1
+     *   special   : 0, unless otherwise noted
+     */
+    int minDelayUs;
+
+    /**
+     * number of events reserved for this sensor in the batch mode FIFO.
+     * If there is a dedicated FIFO for this sensor, then this is the
+     * size of this FIFO. If the FIFO is shared with other sensors,
+     * this is the size reserved for that sensor and it can be zero.
+     */
+    int fifoReservedEventCount;
+
+    /**
+     * maximum number of events of this sensor that could be batched.
+     * This is especially relevant when the FIFO is shared between
+     * several sensors; this value is then set to the size of that FIFO.
+     */
+    int fifoMaxEventCount;
+
+    /**
+     * permission required to see this sensor, register to it and receive data.
+     * Set to "" if no permission is required. Some sensor types like the
+     * heart rate monitor have a mandatory require_permission.
+     * For sensors that always require a specific permission, like the heart
+     * rate monitor, the android framework might overwrite this string
+     * automatically.
+     */
+    String requiredPermission;
+
+    /**
+     * This value is defined only for continuous mode and on-change sensors.
+     * It is the delay between two sensor events corresponding to the lowest
+     * frequency that this sensor supports. When lower frequencies are requested
+     * through batch()/setDelay() the events will be generated at this frequency
+     * instead.
+     * It can be used by the framework or applications to estimate when the
+     * batch FIFO may be full.
+     *
+     * continuous, on-change: maximum sampling period allowed in microseconds.
+     * one-shot, special : 0
+     */
+    int maxDelayUs;
+
+    /**
+     * Bitmasks defined in SENSOR_FLAG_BITS_* below.
+     */
+    int flags;
+
+    /**
+     * Whether this sensor wakes up the AP from suspend mode when data is
+     * available.  Whenever sensor events are delivered from a wake_up sensor,
+     * the driver needs to hold a wake_lock till the events are read by the
+     * SensorService i.e. till ISensors::poll() is called the next time.
+     * Once poll is called again it means events have been read by the
+     * SensorService, the driver can safely release the wake_lock. SensorService
+     * will continue to hold a wake_lock till the app actually reads the events.
+     */
+    const int SENSOR_FLAG_BITS_WAKE_UP = 1;
+
+    /**
+     * Reporting modes for various sensors. Each sensor will have exactly one of
+     * these modes set.
+     * The least significant 2nd, 3rd and 4th bits are used to represent four
+     * possible reporting modes.
+     */
+    const int SENSOR_FLAG_BITS_CONTINUOUS_MODE = 0;
+    const int SENSOR_FLAG_BITS_ON_CHANGE_MODE = 2;
+    const int SENSOR_FLAG_BITS_ONE_SHOT_MODE = 4;
+    const int SENSOR_FLAG_BITS_SPECIAL_REPORTING_MODE = 6;
+
+    /**
+     * Set this flag if the sensor supports data_injection mode and allows data
+     * to be injected from the SensorService. When in data_injection ONLY
+     * sensors with this flag set are injected sensor data and only sensors with
+     * this flag set are activated. Eg: Accelerometer and Step Counter sensors
+     * can be set with this flag and SensorService will inject accelerometer
+     * data and read the corresponding step counts.
+     */
+    const int SENSOR_FLAG_BITS_DATA_INJECTION = 0x10;
+
+    /**
+     * Set this flag if the sensor is a dynamically connected sensor. See
+     * DynamicSensorInfo and DYNAMIC_SENSOR_META for details.
+     */
+    const int SENSOR_FLAG_BITS_DYNAMIC_SENSOR = 0x20;
+
+    /**
+     * Set this flag if sensor additional information is supported.
+     * See ADDITIONAL_INFO and AdditionalInfo for details.
+     */
+    const int SENSOR_FLAG_BITS_ADDITIONAL_INFO = 0x40;
+
+    /**
+     * Set this flag if sensor suppor direct channel backed by ashmem.
+     * See SharedMemType and registerDirectChannel for more details.
+     */
+    const int SENSOR_FLAG_BITS_DIRECT_CHANNEL_ASHMEM = 0x400;
+
+    /**
+     * Set this flag if sensor suppor direct channel backed by gralloc HAL memory.
+     * See SharedMemType and registerDirectChannel for more details.
+     */
+    const int SENSOR_FLAG_BITS_DIRECT_CHANNEL_GRALLOC = 0x800;
+
+    /**
+     * Flags mask for reporting mode of sensor.
+     */
+    const int SENSOR_FLAG_BITS_MASK_REPORTING_MODE = 0xE;
+
+    /**
+     * Flags mask for direct report maximum rate level support.
+     * See RateLevel.
+     */
+    const int SENSOR_FLAG_BITS_MASK_DIRECT_REPORT = 0x380;
+
+    /**
+     * Flags mask for all direct channel support bits.
+     * See SharedMemType.
+     */
+    const int SENSOR_FLAG_BITS_MASK_DIRECT_CHANNEL = 0xC00;
+
+    /**
+     * Defines the number of bits different pieces of information are shifted in the
+     * SENSOR_FLAG_BITS_* bitmask.
+     */
+    const int SENSOR_FLAG_SHIFT_REPORTING_MODE = 1;
+    const int SENSOR_FLAG_SHIFT_DATA_INJECTION = 4;
+    const int SENSOR_FLAG_SHIFT_DYNAMIC_SENSOR = 5;
+    const int SENSOR_FLAG_SHIFT_ADDITIONAL_INFO = 6;
+    const int SENSOR_FLAG_SHIFT_DIRECT_REPORT = 7;
+    const int SENSOR_FLAG_SHIFT_DIRECT_CHANNEL = 10;
+}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl b/sensors/aidl/android/hardware/sensors/SensorStatus.aidl
similarity index 62%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
copy to sensors/aidl/android/hardware/sensors/SensorStatus.aidl
index a0a1d4b..0fd8697 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
+++ b/sensors/aidl/android/hardware/sensors/SensorStatus.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,
@@ -14,16 +14,14 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
-
-/**
- * Color representation as a floating point number in the range [0.0 - 1.0]
- */
+package android.hardware.sensors;
 
 @VintfStability
-parcelable FloatColor {
-    float r;
-    float g;
-    float b;
-    float a;
+@Backing(type="byte")
+enum SensorStatus {
+    NO_CONTACT = -1,
+    UNRELIABLE = 0,
+    ACCURACY_LOW = 1,
+    ACCURACY_MEDIUM = 2,
+    ACCURACY_HIGH = 3,
 }
diff --git a/sensors/aidl/android/hardware/sensors/SensorType.aidl b/sensors/aidl/android/hardware/sensors/SensorType.aidl
new file mode 100644
index 0000000..01e6bee
--- /dev/null
+++ b/sensors/aidl/android/hardware/sensors/SensorType.aidl
@@ -0,0 +1,674 @@
+/*
+ * 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.sensors;
+
+@VintfStability
+@Backing(type="int")
+enum SensorType {
+    /**
+     * META_DATA is a special event type used to populate the MetaData
+     * structure. It doesn't correspond to a physical sensor. Events of this
+     * type exist only inside the HAL, their primary purpose is to signal the
+     * completion of a flush request.
+     */
+    META_DATA = 0,
+
+    /**
+     * ACCELEROMETER
+     * reporting-mode: continuous
+     *
+     * All values are in SI units (m/s^2) and measure the acceleration of the
+     * device minus the acceleration due to gravity.
+     *
+     * Implement the non-wake-up version of this sensor and implement the
+     * wake-up version if the system possesses a wake up fifo.
+     */
+    ACCELEROMETER = 1,
+
+    /**
+     * MAGNETIC_FIELD
+     * reporting-mode: continuous
+     *
+     * All values are in micro-Tesla (uT) and measure the geomagnetic
+     * field in the X, Y and Z axis.
+     *
+     * Implement the non-wake-up version of this sensor and implement the
+     * wake-up version if the system possesses a wake up fifo.
+     */
+    MAGNETIC_FIELD = 2,
+
+    /**
+     * ORIENTATION
+     * reporting-mode: continuous
+     *
+     * All values are angles in degrees.
+     *
+     * Orientation sensors return sensor events for all 3 axes at a constant
+     * rate defined by setDelay().
+     *
+     * Implement the non-wake-up version of this sensor and implement the
+     * wake-up version if the system possesses a wake up fifo.
+     */
+    ORIENTATION = 3,
+
+    /**
+     * GYROSCOPE
+     * reporting-mode: continuous
+     *
+     * All values are in radians/second and measure the rate of rotation
+     * around the X, Y and Z axis.
+     *
+     * Implement the non-wake-up version of this sensor and implement the
+     * wake-up version if the system possesses a wake up fifo.
+     */
+    GYROSCOPE = 4,
+
+    /**
+     * LIGHT
+     * reporting-mode: on-change
+     *
+     * The light sensor value is returned in SI lux units.
+     *
+     * Both wake-up and non wake-up versions are useful.
+     */
+    LIGHT = 5,
+
+    /**
+     * PRESSURE
+     * reporting-mode: continuous
+     *
+     * The pressure sensor return the athmospheric pressure in hectopascal (hPa)
+     *
+     * Implement the non-wake-up version of this sensor and implement the
+     * wake-up version if the system possesses a wake up fifo.
+     */
+    PRESSURE = 6,
+
+    /**
+     * PROXIMITY
+     * reporting-mode: on-change
+     *
+     * The proximity sensor which turns the screen off and back on during calls
+     * is the wake-up proximity sensor. Implement wake-up proximity sensor
+     * before implementing a non wake-up proximity sensor. For the wake-up
+     * proximity sensor set the flag SENSOR_FLAG_WAKE_UP.
+     * The value corresponds to the distance to the nearest object in
+     * centimeters.
+     */
+    PROXIMITY = 8,
+
+    /**
+     * GRAVITY
+     * reporting-mode: continuous
+     *
+     * A gravity output indicates the direction of and magnitude of gravity in
+     * the devices's coordinates.
+     *
+     * Implement the non-wake-up version of this sensor and implement the
+     * wake-up version if the system possesses a wake up fifo.
+     */
+    GRAVITY = 9,
+
+    /**
+     * LINEAR_ACCELERATION
+     * reporting-mode: continuous
+     *
+     * Indicates the linear acceleration of the device in device coordinates,
+     * not including gravity.
+     *
+     * Implement the non-wake-up version of this sensor and implement the
+     * wake-up version if the system possesses a wake up fifo.
+     */
+    LINEAR_ACCELERATION = 10,
+
+    /**
+     * ROTATION_VECTOR
+     * reporting-mode: continuous
+     *
+     * The rotation vector symbolizes the orientation of the device relative to
+     * the East-North-Up coordinates frame.
+     *
+     * Note that despite the name, SensorType::ROTATION_VECTOR uses
+     * quaternion representation, rather than the rotation vector representation
+     * (aka Euler vector) seen in SensorType::HEAD_TRACKER.
+     *
+     * Implement the non-wake-up version of this sensor and implement the
+     * wake-up version if the system possesses a wake up fifo.
+     */
+    ROTATION_VECTOR = 11,
+
+    /**
+     * RELATIVE_HUMIDITY
+     * reporting-mode: on-change
+     *
+     * A relative humidity sensor measures relative ambient air humidity and
+     * returns a value in percent.
+     *
+     * Both wake-up and non wake-up versions are useful.
+     */
+    RELATIVE_HUMIDITY = 12,
+
+    /**
+     * AMBIENT_TEMPERATURE
+     * reporting-mode: on-change
+     *
+     * The ambient (room) temperature in degree Celsius.
+     *
+     * Both wake-up and non wake-up versions are useful.
+     */
+    AMBIENT_TEMPERATURE = 13,
+
+    /**
+     * MAGNETIC_FIELD_UNCALIBRATED
+     * reporting-mode: continuous
+     *
+     * Similar to MAGNETIC_FIELD, but the hard iron calibration is
+     * reported separately instead of being included in the measurement.
+     *
+     * Implement the non-wake-up version of this sensor and implement the
+     * wake-up version if the system possesses a wake up fifo.
+     */
+    MAGNETIC_FIELD_UNCALIBRATED = 14,
+
+    /**
+     * GAME_ROTATION_VECTOR
+     * reporting-mode: continuous
+     *
+     * Similar to ROTATION_VECTOR, but not using the geomagnetic
+     * field.
+     *
+     * Implement the non-wake-up version of this sensor and implement the
+     * wake-up version if the system possesses a wake up fifo.
+     */
+    GAME_ROTATION_VECTOR = 15,
+
+    /**
+     * GYROSCOPE_UNCALIBRATED
+     * reporting-mode: continuous
+     *
+     * All values are in radians/second and measure the rate of rotation
+     * around the X, Y and Z axis.
+     *
+     * Implement the non-wake-up version of this sensor and implement the
+     * wake-up version if the system possesses a wake up fifo.
+     */
+    GYROSCOPE_UNCALIBRATED = 16,
+
+    /**
+     * SIGNIFICANT_MOTION
+     * reporting-mode: one-shot
+     *
+     * A sensor of this type triggers an event each time significant motion
+     * is detected and automatically disables itself.
+     * For Significant Motion sensor to be useful, it must be defined as a
+     * wake-up sensor. (set SENSOR_FLAG_WAKE_UP). Implement the wake-up
+     * significant motion sensor. A non wake-up version is not useful.
+     * The only allowed value to return is 1.0.
+     */
+    SIGNIFICANT_MOTION = 17,
+
+    /**
+     * STEP_DETECTOR
+     * reporting-mode: special
+     *
+     * A sensor of this type triggers an event each time a step is taken
+     * by the user. The only allowed value to return is 1.0 and an event
+     * is generated for each step.
+     *
+     * Both wake-up and non wake-up versions are useful.
+     */
+    STEP_DETECTOR = 18,
+
+    /**
+     * STEP_COUNTER
+     * reporting-mode: on-change
+     *
+     * A sensor of this type returns the number of steps taken by the user since
+     * the last reboot while activated. The value is returned as a uint64_t and
+     * is reset to zero only on a system / android reboot.
+     *
+     * Implement the non-wake-up version of this sensor and implement the
+     * wake-up version if the system possesses a wake up fifo.
+     */
+    STEP_COUNTER = 19,
+
+    /**
+     * GEOMAGNETIC_ROTATION_VECTOR
+     * reporting-mode: continuous
+     *
+     *  Similar to ROTATION_VECTOR, but using a magnetometer instead
+     *  of using a gyroscope.
+     *
+     * Implement the non-wake-up version of this sensor and implement the
+     * wake-up version if the system possesses a wake up fifo.
+     */
+    GEOMAGNETIC_ROTATION_VECTOR = 20,
+
+    /**
+     * HEART_RATE
+     * reporting-mode: on-change
+     *
+     *  A sensor of this type returns the current heart rate.
+     *  The events contain the current heart rate in beats per minute (BPM) and
+     *  the status of the sensor during the measurement. See "HeartRate" below
+     *  for more details.
+     *
+     *  Because this sensor is on-change, events must be generated when and only
+     *  when heart_rate.bpm or heart_rate.status have changed since the last
+     *  event. In particular, upon the first activation, unless the device is
+     *  known to not be on the body, the status field of the first event must be
+     *  set to SensorStatus::UNRELIABLE. The event should be generated no faster
+     *  than every period_ns passed to setDelay() or to batch().
+     *  See the definition of the on-change reporting mode for more information.
+     *
+     *  SensorInfo.requiredPermission must be set to
+     *  SENSOR_PERMISSION_BODY_SENSORS.
+     *
+     *  Both wake-up and non wake-up versions are useful.
+     */
+    HEART_RATE = 21,
+
+    /**
+     * WAKE_UP_TILT_DETECTOR
+     * reporting-mode: special (setDelay has no impact)
+     *
+     * A sensor of this type generates an event each time a tilt event is
+     * detected. A tilt event must be generated if the direction of the
+     * 2-seconds window average gravity changed by at least 35 degrees since the
+     * activation or the last trigger of the sensor.
+     *
+     *  reference_estimated_gravity = average of accelerometer measurements over
+     *  the first 1 second after activation or the estimated gravity at the last
+     *  trigger.
+     *
+     *  current_estimated_gravity = average of accelerometer measurements over
+     *  the last 2 seconds.
+     *
+     *  trigger when
+     *     angle(reference_estimated_gravity, current_estimated_gravity)
+     *       > 35 degrees
+     *
+     * Large accelerations without a change in phone orientation must not
+     * trigger a tilt event.
+     * For example, a sharp turn or strong acceleration while driving a car
+     * must not trigger a tilt event, even though the angle of the average
+     * acceleration might vary by more than 35 degrees.
+     *
+     * Typically, this sensor is implemented with the help of only an
+     * accelerometer. Other sensors can be used as well if they do not increase
+     * the power consumption significantly. This is a low power sensor that
+     * must allow the AP to go into suspend mode. Do not emulate this sensor
+     * in the HAL.
+     * Like other wake up sensors, the driver is expected to a hold a wake_lock
+     * with a timeout of 200 ms while reporting this event. The only allowed
+     * return value is 1.0.
+     *
+     * Implement only the wake-up version of this sensor.
+     */
+    TILT_DETECTOR = 22,
+
+    /**
+     * WAKE_GESTURE
+     * reporting-mode: one-shot
+     *
+     * A sensor enabling waking up the device based on a device specific motion.
+     *
+     * When this sensor triggers, the device behaves as if the power button was
+     * pressed, turning the screen on. This behavior (turning on the screen when
+     * this sensor triggers) might be deactivated by the user in the device
+     * settings. Changes in settings do not impact the behavior of the sensor:
+     * only whether the framework turns the screen on when it triggers.
+     *
+     * The actual gesture to be detected is not specified, and can be chosen by
+     * the manufacturer of the device.
+     * This sensor must be low power, as it is likely to be activated 24/7.
+     * The only allowed value to return is 1.0.
+     *
+     * Implement only the wake-up version of this sensor.
+     */
+    WAKE_GESTURE = 23,
+
+    /**
+     * GLANCE_GESTURE
+     * reporting-mode: one-shot
+     *
+     * A sensor enabling briefly turning the screen on to enable the user to
+     * glance content on screen based on a specific motion.  The device must
+     * turn the screen off after a few moments.
+     *
+     * When this sensor triggers, the device turns the screen on momentarily
+     * to allow the user to glance notifications or other content while the
+     * device remains locked in a non-interactive state (dozing). This behavior
+     * (briefly turning on the screen when this sensor triggers) might be
+     * deactivated by the user in the device settings.
+     * Changes in settings do not impact the behavior of the sensor: only
+     * whether the framework briefly turns the screen on when it triggers.
+     *
+     * The actual gesture to be detected is not specified, and can be chosen by
+     * the manufacturer of the device.
+     * This sensor must be low power, as it is likely to be activated 24/7.
+     * The only allowed value to return is 1.0.
+     *
+     * Implement only the wake-up version of this sensor.
+     */
+    GLANCE_GESTURE = 24,
+
+    /**
+     * PICK_UP_GESTURE
+     * reporting-mode: one-shot
+     *
+     * A sensor of this type triggers when the device is picked up regardless of
+     * wherever is was before (desk, pocket, bag). The only allowed return value
+     * is 1.0. This sensor de-activates itself immediately after it triggers.
+     *
+     * Implement only the wake-up version of this sensor.
+     */
+    PICK_UP_GESTURE = 25,
+
+    /**
+     * WRIST_TILT_GESTURE
+     * trigger-mode: special
+     * wake-up sensor: yes
+     *
+     * A sensor of this type triggers an event each time a tilt of the
+     * wrist-worn device is detected.
+     *
+     * This sensor must be low power, as it is likely to be activated 24/7.
+     * The only allowed value to return is 1.0.
+     *
+     * Implement only the wake-up version of this sensor.
+     */
+    WRIST_TILT_GESTURE = 26,
+
+    /**
+     * DEVICE_ORIENTATION
+     * reporting-mode: on-change
+     *
+     * The current orientation of the device. The value is reported in
+     * the "scalar" element of the EventPayload in Event. The
+     * only values that can be reported are (please refer to Android Sensor
+     * Coordinate System to understand the X and Y axis direction with respect
+     * to default orientation):
+     *  - 0: device is in default orientation (Y axis is vertical and points up)
+     *  - 1: device is rotated 90 degrees counter-clockwise from default
+     *       orientation (X axis is vertical and points up)
+     *  - 2: device is rotated 180 degrees from default orientation (Y axis is
+     *       vertical and points down)
+     *  - 3: device is rotated 90 degrees clockwise from default orientation
+     *       (X axis is vertical and points down)
+     *
+     * Moving the device to an orientation where the Z axis is vertical (either
+     * up or down) must not cause a new event to be reported.
+     *
+     * To improve the user experience of this sensor, it is recommended to
+     * implement some physical (i.e., rotation angle) and temporal (i.e., delay)
+     * hysteresis. In other words, minor or transient rotations must not cause
+     * a new event to be reported.
+     *
+     * This is a low power sensor that intended to reduce interrupts of
+     * application processor and thus allow it to go sleep. Use hardware
+     * implementation based on low power consumption sensors, such as
+     * accelerometer. Device must not emulate this sensor in the HAL.
+     *
+     * Both wake-up and non wake-up versions are useful.
+     */
+    DEVICE_ORIENTATION = 27,
+
+    /**
+     * POSE_6DOF
+     * trigger-mode: continuous
+     *
+     * A sensor of this type returns the pose of the device.
+     * Pose of the device is defined as the orientation of the device from a
+     * Earth Centered Earth Fixed frame and the translation from an arbitrary
+     * point at subscription.
+     *
+     * This sensor can be high power. It can use any and all of the following
+     *           . Accelerometer
+     *           . Gyroscope
+     *           . Camera
+     *           . Depth Camera
+     *
+     */
+    POSE_6DOF = 28,
+
+    /**
+     * STATIONARY_DETECT
+     * trigger mode: one shot
+     *
+     * A sensor of this type returns an event if the device is still/stationary
+     * for a while. The period of time to monitor for stationarity must be
+     * greater than 5 seconds. The latency must be less than 10 seconds.
+     *
+     * Stationarity here refers to absolute stationarity. eg: device on desk.
+     *
+     * The only allowed value to return is 1.0.
+     */
+    STATIONARY_DETECT = 29,
+
+    /**
+     * MOTION_DETECT
+     * trigger mode: one shot
+     *
+     * A sensor of this type returns an event if the device is not still for
+     * for a while. The period of time to monitor for stationarity must be
+     * greater than 5 seconds. The latency must be less than 10 seconds.
+     *
+     * Motion here refers to any mechanism in which the device is causes to be
+     * moved in its inertial frame. eg: Pickin up the device and walking with it
+     * to a nearby room may trigger motion wherewas keeping the device on a
+     * table on a smooth train moving at constant velocity may not trigger
+     * motion.
+     *
+     * The only allowed value to return is 1.0.
+     */
+    MOTION_DETECT = 30,
+
+    /**
+     * HEART_BEAT
+     * trigger mode: continuous
+     *
+     * A sensor of this type returns an event everytime a hear beat peak is
+     * detected.
+     *
+     * Peak here ideally corresponds to the positive peak in the QRS complex of
+     * and ECG signal.
+     *
+     * The sensor is not expected to be optimized for latency. As a guide, a
+     * latency of up to 10 seconds is acceptable. However, the timestamp attached
+     * to the event must be accuratly correspond to the time the peak occurred.
+     *
+     * The sensor event contains a parameter for the confidence in the detection
+     * of the peak where 0.0 represent no information at all, and 1.0 represents
+     * certainty.
+     */
+    HEART_BEAT = 31,
+
+    /**
+     * DYNAMIC_SENSOR_META
+     * trigger-mode: special
+     * wake-up sensor: yes
+     *
+     * A sensor event of this type is received when a dynamic sensor is added to
+     * or removed from the system. At most one sensor of this type can be
+     * present in one sensor HAL implementation and presence of a sensor of this
+     * type in sensor HAL implementation indicates that this sensor HAL supports
+     * dynamic sensor feature. Operations, such as batch, activate and setDelay,
+     * to this special purpose sensor must be treated as no-op and return
+     * successful; flush() also has to generate flush complete event as if this
+     * is a sensor that does not support batching.
+     *
+     * A dynamic sensor connection indicates connection of a physical device or
+     * instantiation of a virtual sensor backed by algorithm; and a dynamic
+     * sensor disconnection indicates the opposite. A sensor event of
+     * DYNAMIC_SENSOR_META type should be delivered regardless of
+     * the activation status of the sensor in the event of dynamic sensor
+     * connection and disconnection. In the sensor event, besides the common
+     * data entries, "dynamic_sensor_meta", which includes fields for connection
+     * status, handle of the sensor involved, pointer to sensor_t structure and
+     * a uuid field, must be populated.
+     *
+     * At a dynamic sensor connection event, fields of sensor_t structure
+     * referenced by a pointer in dynamic_sensor_meta must be filled as if it
+     * was regular sensors. Sensor HAL is responsible for recovery of memory if
+     * the corresponding data is dynamicially allocated. However, the
+     * pointer must be valid until the first activate call to the sensor
+     * reported in this connection event. At a dynamic sensor disconnection,
+     * the sensor_t pointer must be NULL.
+     *
+     * The sensor handle assigned to dynamic sensors must never be the same as
+     * that of any regular static sensors, and must be unique until next boot.
+     * In another word, if a handle h is used for a dynamic sensor A, that same
+     * number cannot be used for the same dynamic sensor A or another dynamic
+     * sensor B even after disconnection of A until reboot.
+     *
+     * The UUID field will be used for identifying the sensor in addition to
+     * name, vendor and version and type. For physical sensors of the same
+     * model, all sensors will have the same values in sensor_t, but the UUID
+     * must be unique and persistent for each individual unit. An all zero
+     * UUID indicates it is not possible to differentiate individual sensor
+     * unit.
+     *
+     */
+    DYNAMIC_SENSOR_META = 32,
+
+    /**
+     * ADDITIONAL_INFO
+     * reporting-mode: N/A
+     *
+     * This sensor type is for delivering additional sensor information aside
+     * from sensor event data.
+     * Additional information may include sensor front-end group delay, internal
+     * calibration parameters, noise level metrics, device internal temperature,
+     * etc.
+     *
+     * This type will never bind to a sensor. In other words, no sensor in the
+     * sensor list can have the type SENSOR_TYPE_ADDITIONAL_INFO. If a
+     * sensor HAL supports sensor additional information feature, it reports
+     * sensor_event_t with "sensor" field set to handle of the reporting sensor
+     * and "type" field set to ADDITIONAL_INFO. Delivery of
+     * additional information events is triggered under two conditions: an
+     * enable activate() call or a flush() call to the corresponding sensor.
+     * Besides, time varying parameters can update infrequently without being
+     * triggered. Device is responsible to control update rate. The recommend
+     * update rate is less than 1/1000 of sensor event rate or less than once
+     * per minute in average.
+     *
+     * A single additional information report consists of multiple frames.
+     * Sequences of these frames are ordered using timestamps, which means the
+     * timestamps of sequential frames have to be at least 1 nanosecond apart
+     * from each other. Each frame is a sensor_event_t delivered through the HAL
+     * interface, with related data stored in the "additional_info" field, which
+     * is of type additional_info_event_t.
+     * The "type" field of additional_info_event_t denotes the nature of the
+     * payload data (see additional_info_type_t).
+     * The "serial" field is used to keep the sequence of payload data that
+     * spans multiple frames. The first frame of the entire report is always of
+     * type AINFO_BEGIN, and the last frame is always AINFO_END.
+     *
+     * If flush() was triggering the report, all additional information frames
+     * must be delivered after flush complete event.
+     */
+    ADDITIONAL_INFO = 33,
+
+    /**
+     * LOW_LATENCY_OFFBODY_DETECT
+     * trigger-mode: on-change
+     * wake-up sensor: yes
+     *
+     * A sensor of this type is defined for devices that are supposed to be worn
+     * by the user in the normal use case (such as a watch, wristband, etc) and
+     * is not yet defined for other device.
+     *
+     * A sensor of this type triggers an event each time the wearable device
+     * is removed from the body and each time it's put back onto the body.
+     * It must be low-latency and be able to detect the on-body to off-body
+     * transition within one second (event delivery time included),
+     * and 3-second latency to determine the off-body to on-body transition
+     * (event delivery time included).
+     *
+     * There are only two valid event values for the sensor to return :
+     *    0.0 for off-body
+     *    1.0 for on-body
+     *
+     */
+    LOW_LATENCY_OFFBODY_DETECT = 34,
+
+    /**
+     * ACCELEROMETER_UNCALIBRATED
+     * reporting-mode: continuous
+     *
+     * All values are in SI units (m/s^2) and measure the acceleration of the
+     * device minus the acceleration due to gravity.
+     *
+     * Implement the non-wake-up version of this sensor and implement the
+     * wake-up version if the system possesses a wake up fifo.
+     */
+    ACCELEROMETER_UNCALIBRATED = 35,
+
+    /**
+     * HINGE_ANGLE
+     * reporting-mode: on-change
+     * wake-up sensor: yes
+     *
+     * A sensor of this type measures the angle, in degrees, between two
+     * integral parts of the device. Movement of a hinge measured by this sensor
+     * type is expected to alter the ways in which the user may interact with
+     * the device, for example by unfolding or revealing a display.
+     *
+     * Sensor data is output using EventPayload.scalar.
+     *
+     * Implement wake-up proximity sensor before implementing a non wake-up
+     * proximity sensor.
+     */
+    HINGE_ANGLE = 36,
+
+    /**
+     * HEAD_TRACKER
+     * reporting-mode: continuous
+     *
+     * A sensor of this type measures the orientation of a user's head relative
+     * to an arbitrary reference frame, and the rate of rotation.
+     *
+     * Events produced by this sensor follow a special head-centric coordinate
+     * frame, where:
+     *   - The X axis crosses through the user's ears, with the positive X
+     *     direction extending out of the user's right ear
+     *   - The Y axis crosses from the back of the user's head through their
+     *     nose, with the positive direction extending out of the nose, and the
+     *     X/Y plane being nominally parallel to the ground when the user is
+     *     upright and looking straight ahead
+     *   - The Z axis crosses from the neck through the top of the user's head,
+     *     with the positive direction extending out from the top of the head
+     *
+     * When this sensor type is exposed as a dynamic sensor through a
+     * communications channel that uses HID, such as Bluetooth or USB, as part
+     * of a device with audio output capability (e.g. headphones), then the
+     * DynamicSensorInfo::uuid field shall be set to contents of the HID
+     * Persistent Unique ID to permit association between the sensor and audio
+     * device. Accordingly, the HID Persistent Unique ID (Sensors Page 0x20,
+     * Usage ID 0x302) must be populated as a UUID in binary representation,
+     * following RFC 4122 byte order.
+     */
+    HEAD_TRACKER = 37,
+
+    /**
+     * Base for device manufacturers private sensor types.
+     * These sensor types can't be exposed in the SDK.
+     */
+    DEVICE_PRIVATE_BASE = 0x10000,
+}
diff --git a/sensors/aidl/default/Android.bp b/sensors/aidl/default/Android.bp
new file mode 100644
index 0000000..49841a4
--- /dev/null
+++ b/sensors/aidl/default/Android.bp
@@ -0,0 +1,67 @@
+/*
+ * 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_library_static {
+    name: "libsensorsexampleimpl",
+    vendor: true,
+    shared_libs: [
+        "libbase",
+        "libfmq",
+        "libpower",
+        "libbinder_ndk",
+        "android.hardware.sensors-V1-ndk",
+    ],
+    export_include_dirs: ["include"],
+    srcs: [
+        "Sensors.cpp",
+        "Sensor.cpp",
+    ],
+    visibility: [
+        ":__subpackages__",
+        "//hardware/interfaces/tests/extension/sensors:__subpackages__",
+    ],
+}
+
+cc_binary {
+    name: "android.hardware.sensors-service.example",
+    relative_install_path: "hw",
+    init_rc: ["sensors-default.rc"],
+    vintf_fragments: ["sensors-default.xml"],
+    vendor: true,
+    shared_libs: [
+        "libbase",
+        "libbinder_ndk",
+        "libfmq",
+        "libpower",
+        "libcutils",
+        "liblog",
+        "libutils",
+        "android.hardware.sensors-V1-ndk",
+    ],
+    static_libs: [
+        "libsensorsexampleimpl",
+    ],
+    srcs: ["main.cpp"],
+}
diff --git a/sensors/aidl/default/Sensor.cpp b/sensors/aidl/default/Sensor.cpp
new file mode 100644
index 0000000..50d8841
--- /dev/null
+++ b/sensors/aidl/default/Sensor.cpp
@@ -0,0 +1,434 @@
+/*
+ * 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 "sensors-impl/Sensor.h"
+
+#include "utils/SystemClock.h"
+
+#include <cmath>
+
+using ::ndk::ScopedAStatus;
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace sensors {
+
+static constexpr int32_t kDefaultMaxDelayUs = 10 * 1000 * 1000;
+
+Sensor::Sensor(ISensorsEventCallback* callback)
+    : mIsEnabled(false),
+      mSamplingPeriodNs(0),
+      mLastSampleTimeNs(0),
+      mCallback(callback),
+      mMode(OperationMode::NORMAL) {
+    mRunThread = std::thread(startThread, this);
+}
+
+Sensor::~Sensor() {
+    std::unique_lock<std::mutex> lock(mRunMutex);
+    mStopThread = true;
+    mIsEnabled = false;
+    mWaitCV.notify_all();
+    lock.release();
+    mRunThread.join();
+}
+
+const SensorInfo& Sensor::getSensorInfo() const {
+    return mSensorInfo;
+}
+
+void Sensor::batch(int64_t samplingPeriodNs) {
+    if (samplingPeriodNs < mSensorInfo.minDelayUs * 1000ll) {
+        samplingPeriodNs = mSensorInfo.minDelayUs * 1000ll;
+    } else if (samplingPeriodNs > mSensorInfo.maxDelayUs * 1000ll) {
+        samplingPeriodNs = mSensorInfo.maxDelayUs * 1000ll;
+    }
+
+    if (mSamplingPeriodNs != samplingPeriodNs) {
+        mSamplingPeriodNs = samplingPeriodNs;
+        // Wake up the 'run' thread to check if a new event should be generated now
+        mWaitCV.notify_all();
+    }
+}
+
+void Sensor::activate(bool enable) {
+    if (mIsEnabled != enable) {
+        std::unique_lock<std::mutex> lock(mRunMutex);
+        mIsEnabled = enable;
+        mWaitCV.notify_all();
+    }
+}
+
+ScopedAStatus Sensor::flush() {
+    // Only generate a flush complete event if the sensor is enabled and if the sensor is not a
+    // one-shot sensor.
+    if (!mIsEnabled ||
+        (mSensorInfo.flags & static_cast<uint32_t>(SensorInfo::SENSOR_FLAG_BITS_ONE_SHOT_MODE))) {
+        return ScopedAStatus::fromServiceSpecificError(
+                static_cast<int32_t>(BnSensors::ERROR_BAD_VALUE));
+    }
+
+    // Note: If a sensor supports batching, write all of the currently batched events for the sensor
+    // to the Event FMQ prior to writing the flush complete event.
+    Event ev;
+    ev.sensorHandle = mSensorInfo.sensorHandle;
+    ev.sensorType = SensorType::META_DATA;
+    EventPayload::MetaData meta = {
+            .what = MetaDataEventType::META_DATA_FLUSH_COMPLETE,
+    };
+    ev.payload.set<EventPayload::Tag::meta>(meta);
+    std::vector<Event> evs{ev};
+    mCallback->postEvents(evs, isWakeUpSensor());
+
+    return ScopedAStatus::ok();
+}
+
+void Sensor::startThread(Sensor* sensor) {
+    sensor->run();
+}
+
+void Sensor::run() {
+    std::unique_lock<std::mutex> runLock(mRunMutex);
+    constexpr int64_t kNanosecondsInSeconds = 1000 * 1000 * 1000;
+
+    while (!mStopThread) {
+        if (!mIsEnabled || mMode == OperationMode::DATA_INJECTION) {
+            mWaitCV.wait(runLock, [&] {
+                return ((mIsEnabled && mMode == OperationMode::NORMAL) || mStopThread);
+            });
+        } else {
+            timespec curTime;
+            clock_gettime(CLOCK_BOOTTIME, &curTime);
+            int64_t now = (curTime.tv_sec * kNanosecondsInSeconds) + curTime.tv_nsec;
+            int64_t nextSampleTime = mLastSampleTimeNs + mSamplingPeriodNs;
+
+            if (now >= nextSampleTime) {
+                mLastSampleTimeNs = now;
+                nextSampleTime = mLastSampleTimeNs + mSamplingPeriodNs;
+                mCallback->postEvents(readEvents(), isWakeUpSensor());
+            }
+
+            mWaitCV.wait_for(runLock, std::chrono::nanoseconds(nextSampleTime - now));
+        }
+    }
+}
+
+bool Sensor::isWakeUpSensor() {
+    return mSensorInfo.flags & static_cast<uint32_t>(SensorInfo::SENSOR_FLAG_BITS_WAKE_UP);
+}
+
+std::vector<Event> Sensor::readEvents() {
+    std::vector<Event> events;
+    Event event;
+    event.sensorHandle = mSensorInfo.sensorHandle;
+    event.sensorType = mSensorInfo.type;
+    event.timestamp = ::android::elapsedRealtimeNano();
+    memset(&event.payload, 0, sizeof(event.payload));
+    readEventPayload(event.payload);
+    events.push_back(event);
+    return events;
+}
+
+void Sensor::setOperationMode(OperationMode mode) {
+    if (mMode != mode) {
+        std::unique_lock<std::mutex> lock(mRunMutex);
+        mMode = mode;
+        mWaitCV.notify_all();
+    }
+}
+
+bool Sensor::supportsDataInjection() const {
+    return mSensorInfo.flags & static_cast<uint32_t>(SensorInfo::SENSOR_FLAG_BITS_DATA_INJECTION);
+}
+
+ScopedAStatus Sensor::injectEvent(const Event& event) {
+    if (event.sensorType == SensorType::ADDITIONAL_INFO) {
+        return ScopedAStatus::ok();
+        // When in OperationMode::NORMAL, SensorType::ADDITIONAL_INFO is used to push operation
+        // environment data into the device.
+    }
+
+    if (!supportsDataInjection()) {
+        return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+    }
+
+    if (mMode == OperationMode::DATA_INJECTION) {
+        mCallback->postEvents(std::vector<Event>{event}, isWakeUpSensor());
+        return ScopedAStatus::ok();
+    }
+
+    return ScopedAStatus::fromServiceSpecificError(
+            static_cast<int32_t>(BnSensors::ERROR_BAD_VALUE));
+}
+
+OnChangeSensor::OnChangeSensor(ISensorsEventCallback* callback)
+    : Sensor(callback), mPreviousEventSet(false) {}
+
+void OnChangeSensor::activate(bool enable) {
+    Sensor::activate(enable);
+    if (!enable) {
+        mPreviousEventSet = false;
+    }
+}
+
+std::vector<Event> OnChangeSensor::readEvents() {
+    std::vector<Event> events = Sensor::readEvents();
+    std::vector<Event> outputEvents;
+
+    for (auto iter = events.begin(); iter != events.end(); ++iter) {
+        Event ev = *iter;
+        if (!mPreviousEventSet ||
+            memcmp(&mPreviousEvent.payload, &ev.payload, sizeof(ev.payload)) != 0) {
+            outputEvents.push_back(ev);
+            mPreviousEvent = ev;
+            mPreviousEventSet = true;
+        }
+    }
+    return outputEvents;
+}
+
+AccelSensor::AccelSensor(int32_t sensorHandle, ISensorsEventCallback* callback) : Sensor(callback) {
+    mSensorInfo.sensorHandle = sensorHandle;
+    mSensorInfo.name = "Accel Sensor";
+    mSensorInfo.vendor = "Vendor String";
+    mSensorInfo.version = 1;
+    mSensorInfo.type = SensorType::ACCELEROMETER;
+    mSensorInfo.typeAsString = "";
+    mSensorInfo.maxRange = 78.4f;  // +/- 8g
+    mSensorInfo.resolution = 1.52e-5;
+    mSensorInfo.power = 0.001f;          // mA
+    mSensorInfo.minDelayUs = 10 * 1000;  // microseconds
+    mSensorInfo.maxDelayUs = kDefaultMaxDelayUs;
+    mSensorInfo.fifoReservedEventCount = 0;
+    mSensorInfo.fifoMaxEventCount = 0;
+    mSensorInfo.requiredPermission = "";
+    mSensorInfo.flags = static_cast<uint32_t>(SensorInfo::SENSOR_FLAG_BITS_DATA_INJECTION);
+};
+
+void AccelSensor::readEventPayload(EventPayload& payload) {
+    EventPayload::Vec3 vec3 = {
+            .x = 0,
+            .y = 0,
+            .z = -9.8,
+            .status = SensorStatus::ACCURACY_HIGH,
+    };
+    payload.set<EventPayload::Tag::vec3>(vec3);
+}
+
+PressureSensor::PressureSensor(int32_t sensorHandle, ISensorsEventCallback* callback)
+    : Sensor(callback) {
+    mSensorInfo.sensorHandle = sensorHandle;
+    mSensorInfo.name = "Pressure Sensor";
+    mSensorInfo.vendor = "Vendor String";
+    mSensorInfo.version = 1;
+    mSensorInfo.type = SensorType::PRESSURE;
+    mSensorInfo.typeAsString = "";
+    mSensorInfo.maxRange = 1100.0f;       // hPa
+    mSensorInfo.resolution = 0.005f;      // hPa
+    mSensorInfo.power = 0.001f;           // mA
+    mSensorInfo.minDelayUs = 100 * 1000;  // microseconds
+    mSensorInfo.maxDelayUs = kDefaultMaxDelayUs;
+    mSensorInfo.fifoReservedEventCount = 0;
+    mSensorInfo.fifoMaxEventCount = 0;
+    mSensorInfo.requiredPermission = "";
+    mSensorInfo.flags = 0;
+};
+
+void PressureSensor::readEventPayload(EventPayload& payload) {
+    payload.set<EventPayload::Tag::scalar>(1013.25f);
+}
+
+MagnetometerSensor::MagnetometerSensor(int32_t sensorHandle, ISensorsEventCallback* callback)
+    : Sensor(callback) {
+    mSensorInfo.sensorHandle = sensorHandle;
+    mSensorInfo.name = "Magnetic Field Sensor";
+    mSensorInfo.vendor = "Vendor String";
+    mSensorInfo.version = 1;
+    mSensorInfo.type = SensorType::MAGNETIC_FIELD;
+    mSensorInfo.typeAsString = "";
+    mSensorInfo.maxRange = 1300.0f;
+    mSensorInfo.resolution = 0.01f;
+    mSensorInfo.power = 0.001f;          // mA
+    mSensorInfo.minDelayUs = 20 * 1000;  // microseconds
+    mSensorInfo.maxDelayUs = kDefaultMaxDelayUs;
+    mSensorInfo.fifoReservedEventCount = 0;
+    mSensorInfo.fifoMaxEventCount = 0;
+    mSensorInfo.requiredPermission = "";
+    mSensorInfo.flags = 0;
+};
+
+void MagnetometerSensor::readEventPayload(EventPayload& payload) {
+    EventPayload::Vec3 vec3 = {
+            .x = 100.0,
+            .y = 0,
+            .z = 50.0,
+            .status = SensorStatus::ACCURACY_HIGH,
+    };
+    payload.set<EventPayload::Tag::vec3>(vec3);
+}
+
+LightSensor::LightSensor(int32_t sensorHandle, ISensorsEventCallback* callback)
+    : OnChangeSensor(callback) {
+    mSensorInfo.sensorHandle = sensorHandle;
+    mSensorInfo.name = "Light Sensor";
+    mSensorInfo.vendor = "Vendor String";
+    mSensorInfo.version = 1;
+    mSensorInfo.type = SensorType::LIGHT;
+    mSensorInfo.typeAsString = "";
+    mSensorInfo.maxRange = 43000.0f;
+    mSensorInfo.resolution = 10.0f;
+    mSensorInfo.power = 0.001f;           // mA
+    mSensorInfo.minDelayUs = 200 * 1000;  // microseconds
+    mSensorInfo.maxDelayUs = kDefaultMaxDelayUs;
+    mSensorInfo.fifoReservedEventCount = 0;
+    mSensorInfo.fifoMaxEventCount = 0;
+    mSensorInfo.requiredPermission = "";
+    mSensorInfo.flags = static_cast<uint32_t>(SensorInfo::SENSOR_FLAG_BITS_ON_CHANGE_MODE);
+};
+
+void LightSensor::readEventPayload(EventPayload& payload) {
+    payload.set<EventPayload::Tag::scalar>(80.0f);
+}
+
+ProximitySensor::ProximitySensor(int32_t sensorHandle, ISensorsEventCallback* callback)
+    : OnChangeSensor(callback) {
+    mSensorInfo.sensorHandle = sensorHandle;
+    mSensorInfo.name = "Proximity Sensor";
+    mSensorInfo.vendor = "Vendor String";
+    mSensorInfo.version = 1;
+    mSensorInfo.type = SensorType::PROXIMITY;
+    mSensorInfo.typeAsString = "";
+    mSensorInfo.maxRange = 5.0f;
+    mSensorInfo.resolution = 1.0f;
+    mSensorInfo.power = 0.012f;           // mA
+    mSensorInfo.minDelayUs = 200 * 1000;  // microseconds
+    mSensorInfo.maxDelayUs = kDefaultMaxDelayUs;
+    mSensorInfo.fifoReservedEventCount = 0;
+    mSensorInfo.fifoMaxEventCount = 0;
+    mSensorInfo.requiredPermission = "";
+    mSensorInfo.flags = static_cast<uint32_t>(SensorInfo::SENSOR_FLAG_BITS_ON_CHANGE_MODE |
+                                              SensorInfo::SENSOR_FLAG_BITS_WAKE_UP);
+};
+
+void ProximitySensor::readEventPayload(EventPayload& payload) {
+    payload.set<EventPayload::Tag::scalar>(2.5f);
+}
+
+GyroSensor::GyroSensor(int32_t sensorHandle, ISensorsEventCallback* callback) : Sensor(callback) {
+    mSensorInfo.sensorHandle = sensorHandle;
+    mSensorInfo.name = "Gyro Sensor";
+    mSensorInfo.vendor = "Vendor String";
+    mSensorInfo.version = 1;
+    mSensorInfo.type = SensorType::GYROSCOPE;
+    mSensorInfo.typeAsString = "";
+    mSensorInfo.maxRange = 1000.0f * M_PI / 180.0f;
+    mSensorInfo.resolution = 1000.0f * M_PI / (180.0f * 32768.0f);
+    mSensorInfo.power = 0.001f;
+    mSensorInfo.minDelayUs = 10 * 1000;  // microseconds
+    mSensorInfo.maxDelayUs = kDefaultMaxDelayUs;
+    mSensorInfo.fifoReservedEventCount = 0;
+    mSensorInfo.fifoMaxEventCount = 0;
+    mSensorInfo.requiredPermission = "";
+    mSensorInfo.flags = 0;
+};
+
+void GyroSensor::readEventPayload(EventPayload& payload) {
+    EventPayload::Vec3 vec3 = {
+            .x = 0,
+            .y = 0,
+            .z = 0,
+            .status = SensorStatus::ACCURACY_HIGH,
+    };
+    payload.set<EventPayload::Tag::vec3>(vec3);
+}
+
+AmbientTempSensor::AmbientTempSensor(int32_t sensorHandle, ISensorsEventCallback* callback)
+    : OnChangeSensor(callback) {
+    mSensorInfo.sensorHandle = sensorHandle;
+    mSensorInfo.name = "Ambient Temp Sensor";
+    mSensorInfo.vendor = "Vendor String";
+    mSensorInfo.version = 1;
+    mSensorInfo.type = SensorType::AMBIENT_TEMPERATURE;
+    mSensorInfo.typeAsString = "";
+    mSensorInfo.maxRange = 80.0f;
+    mSensorInfo.resolution = 0.01f;
+    mSensorInfo.power = 0.001f;
+    mSensorInfo.minDelayUs = 40 * 1000;  // microseconds
+    mSensorInfo.maxDelayUs = kDefaultMaxDelayUs;
+    mSensorInfo.fifoReservedEventCount = 0;
+    mSensorInfo.fifoMaxEventCount = 0;
+    mSensorInfo.requiredPermission = "";
+    mSensorInfo.flags = static_cast<uint32_t>(SensorInfo::SENSOR_FLAG_BITS_ON_CHANGE_MODE);
+};
+
+void AmbientTempSensor::readEventPayload(EventPayload& payload) {
+    payload.set<EventPayload::Tag::scalar>(40.0f);
+}
+
+RelativeHumiditySensor::RelativeHumiditySensor(int32_t sensorHandle,
+                                               ISensorsEventCallback* callback)
+    : OnChangeSensor(callback) {
+    mSensorInfo.sensorHandle = sensorHandle;
+    mSensorInfo.name = "Relative Humidity Sensor";
+    mSensorInfo.vendor = "Vendor String";
+    mSensorInfo.version = 1;
+    mSensorInfo.type = SensorType::RELATIVE_HUMIDITY;
+    mSensorInfo.typeAsString = "";
+    mSensorInfo.maxRange = 100.0f;
+    mSensorInfo.resolution = 0.1f;
+    mSensorInfo.power = 0.001f;
+    mSensorInfo.minDelayUs = 40 * 1000;  // microseconds
+    mSensorInfo.maxDelayUs = kDefaultMaxDelayUs;
+    mSensorInfo.fifoReservedEventCount = 0;
+    mSensorInfo.fifoMaxEventCount = 0;
+    mSensorInfo.requiredPermission = "";
+    mSensorInfo.flags = static_cast<uint32_t>(SensorInfo::SENSOR_FLAG_BITS_ON_CHANGE_MODE);
+}
+
+void RelativeHumiditySensor::readEventPayload(EventPayload& payload) {
+    payload.set<EventPayload::Tag::scalar>(50.0f);
+}
+
+HingeAngleSensor::HingeAngleSensor(int32_t sensorHandle, ISensorsEventCallback* callback)
+    : OnChangeSensor(callback) {
+    mSensorInfo.sensorHandle = sensorHandle;
+    mSensorInfo.name = "Hinge Angle Sensor";
+    mSensorInfo.vendor = "Vendor String";
+    mSensorInfo.version = 1;
+    mSensorInfo.type = SensorType::HINGE_ANGLE;
+    mSensorInfo.typeAsString = "";
+    mSensorInfo.maxRange = 360.0f;
+    mSensorInfo.resolution = 1.0f;
+    mSensorInfo.power = 0.001f;
+    mSensorInfo.minDelayUs = 40 * 1000;  // microseconds
+    mSensorInfo.maxDelayUs = kDefaultMaxDelayUs;
+    mSensorInfo.fifoReservedEventCount = 0;
+    mSensorInfo.fifoMaxEventCount = 0;
+    mSensorInfo.requiredPermission = "";
+    mSensorInfo.flags = static_cast<uint32_t>(SensorInfo::SENSOR_FLAG_BITS_ON_CHANGE_MODE |
+                                              SensorInfo::SENSOR_FLAG_BITS_WAKE_UP |
+                                              SensorInfo::SENSOR_FLAG_BITS_DATA_INJECTION);
+}
+
+void HingeAngleSensor::readEventPayload(EventPayload& payload) {
+    payload.set<EventPayload::Tag::scalar>(180.0f);
+}
+
+}  // namespace sensors
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/sensors/aidl/default/Sensors.cpp b/sensors/aidl/default/Sensors.cpp
new file mode 100644
index 0000000..65dd304
--- /dev/null
+++ b/sensors/aidl/default/Sensors.cpp
@@ -0,0 +1,157 @@
+/*
+ * 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 "sensors-impl/Sensors.h"
+
+#include <aidl/android/hardware/common/fmq/SynchronizedReadWrite.h>
+
+using ::aidl::android::hardware::common::fmq::MQDescriptor;
+using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite;
+using ::aidl::android::hardware::sensors::Event;
+using ::aidl::android::hardware::sensors::ISensors;
+using ::aidl::android::hardware::sensors::ISensorsCallback;
+using ::aidl::android::hardware::sensors::SensorInfo;
+using ::ndk::ScopedAStatus;
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace sensors {
+
+ScopedAStatus Sensors::activate(int32_t in_sensorHandle, bool in_enabled) {
+    auto sensor = mSensors.find(in_sensorHandle);
+    if (sensor != mSensors.end()) {
+        sensor->second->activate(in_enabled);
+        return ScopedAStatus::ok();
+    }
+
+    return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+}
+
+ScopedAStatus Sensors::batch(int32_t in_sensorHandle, int64_t in_samplingPeriodNs,
+                             int64_t /* in_maxReportLatencyNs */) {
+    auto sensor = mSensors.find(in_sensorHandle);
+    if (sensor != mSensors.end()) {
+        sensor->second->batch(in_samplingPeriodNs);
+        return ScopedAStatus::ok();
+    }
+
+    return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+}
+
+ScopedAStatus Sensors::configDirectReport(int32_t /* in_sensorHandle */,
+                                          int32_t /* in_channelHandle */,
+                                          ISensors::RateLevel /* in_rate */,
+                                          int32_t* _aidl_return) {
+    *_aidl_return = EX_UNSUPPORTED_OPERATION;
+
+    return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ScopedAStatus Sensors::flush(int32_t in_sensorHandle) {
+    auto sensor = mSensors.find(in_sensorHandle);
+    if (sensor != mSensors.end()) {
+        return sensor->second->flush();
+    }
+
+    return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+}
+
+ScopedAStatus Sensors::getSensorsList(std::vector<SensorInfo>* _aidl_return) {
+    for (const auto& sensor : mSensors) {
+        _aidl_return->push_back(sensor.second->getSensorInfo());
+    }
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus Sensors::initialize(
+        const MQDescriptor<Event, SynchronizedReadWrite>& in_eventQueueDescriptor,
+        const MQDescriptor<int32_t, SynchronizedReadWrite>& in_wakeLockDescriptor,
+        const std::shared_ptr<::aidl::android::hardware::sensors::ISensorsCallback>&
+                in_sensorsCallback) {
+    ScopedAStatus result = ScopedAStatus::ok();
+
+    mEventQueue = std::make_unique<AidlMessageQueue<Event, SynchronizedReadWrite>>(
+            in_eventQueueDescriptor, true /* resetPointers */);
+
+    // Ensure that all sensors are disabled.
+    for (auto sensor : mSensors) {
+        sensor.second->activate(false);
+    }
+
+    // Stop the Wake Lock thread if it is currently running
+    if (mReadWakeLockQueueRun.load()) {
+        mReadWakeLockQueueRun = false;
+        mWakeLockThread.join();
+    }
+
+    // Save a reference to the callback
+    mCallback = in_sensorsCallback;
+
+    // Ensure that any existing EventFlag is properly deleted
+    deleteEventFlag();
+
+    // Create the EventFlag that is used to signal to the framework that sensor events have been
+    // written to the Event FMQ
+    if (EventFlag::createEventFlag(mEventQueue->getEventFlagWord(), &mEventQueueFlag) != OK) {
+        result = ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+
+    // Create the Wake Lock FMQ that is used by the framework to communicate whenever WAKE_UP
+    // events have been successfully read and handled by the framework.
+    mWakeLockQueue = std::make_unique<AidlMessageQueue<int32_t, SynchronizedReadWrite>>(
+            in_wakeLockDescriptor, true /* resetPointers */);
+
+    if (!mCallback || !mEventQueue || !mWakeLockQueue || mEventQueueFlag == nullptr) {
+        result = ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+
+    // Start the thread to read events from the Wake Lock FMQ
+    mReadWakeLockQueueRun = true;
+    mWakeLockThread = std::thread(startReadWakeLockThread, this);
+    return result;
+}
+
+ScopedAStatus Sensors::injectSensorData(const Event& in_event) {
+    auto sensor = mSensors.find(in_event.sensorHandle);
+    if (sensor != mSensors.end()) {
+        return sensor->second->injectEvent(in_event);
+    }
+    return ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(ERROR_BAD_VALUE));
+}
+
+ScopedAStatus Sensors::registerDirectChannel(const ISensors::SharedMemInfo& /* in_mem */,
+                                             int32_t* _aidl_return) {
+    *_aidl_return = EX_UNSUPPORTED_OPERATION;
+
+    return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ScopedAStatus Sensors::setOperationMode(OperationMode in_mode) {
+    for (auto sensor : mSensors) {
+        sensor.second->setOperationMode(in_mode);
+    }
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus Sensors::unregisterDirectChannel(int32_t /* in_channelHandle */) {
+    return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+}  // namespace sensors
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/sensors/aidl/default/include/sensors-impl/Sensor.h b/sensors/aidl/default/include/sensors-impl/Sensor.h
new file mode 100644
index 0000000..e6cd3e6
--- /dev/null
+++ b/sensors/aidl/default/include/sensors-impl/Sensor.h
@@ -0,0 +1,168 @@
+/*
+ * 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 <thread>
+
+#include <aidl/android/hardware/sensors/BnSensors.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace sensors {
+
+class ISensorsEventCallback {
+  public:
+    using Event = ::aidl::android::hardware::sensors::Event;
+
+    virtual ~ISensorsEventCallback(){};
+    virtual void postEvents(const std::vector<Event>& events, bool wakeup) = 0;
+};
+
+class Sensor {
+  public:
+    using OperationMode = ::aidl::android::hardware::sensors::ISensors::OperationMode;
+    using Event = ::aidl::android::hardware::sensors::Event;
+    using EventPayload = ::aidl::android::hardware::sensors::Event::EventPayload;
+    using SensorInfo = ::aidl::android::hardware::sensors::SensorInfo;
+    using SensorType = ::aidl::android::hardware::sensors::SensorType;
+    using MetaDataEventType =
+            ::aidl::android::hardware::sensors::Event::EventPayload::MetaData::MetaDataEventType;
+
+    Sensor(ISensorsEventCallback* callback);
+    virtual ~Sensor();
+
+    const SensorInfo& getSensorInfo() const;
+    void batch(int64_t samplingPeriodNs);
+    virtual void activate(bool enable);
+    ndk::ScopedAStatus flush();
+
+    void setOperationMode(OperationMode mode);
+    bool supportsDataInjection() const;
+    ndk::ScopedAStatus injectEvent(const Event& event);
+
+  protected:
+    void run();
+    virtual std::vector<Event> readEvents();
+    virtual void readEventPayload(EventPayload&) = 0;
+    static void startThread(Sensor* sensor);
+
+    bool isWakeUpSensor();
+
+    bool mIsEnabled;
+    int64_t mSamplingPeriodNs;
+    int64_t mLastSampleTimeNs;
+    SensorInfo mSensorInfo;
+
+    std::atomic_bool mStopThread;
+    std::condition_variable mWaitCV;
+    std::mutex mRunMutex;
+    std::thread mRunThread;
+
+    ISensorsEventCallback* mCallback;
+
+    OperationMode mMode;
+};
+
+class OnChangeSensor : public Sensor {
+  public:
+    OnChangeSensor(ISensorsEventCallback* callback);
+
+    virtual void activate(bool enable) override;
+
+  protected:
+    virtual std::vector<Event> readEvents() override;
+
+  protected:
+    Event mPreviousEvent;
+    bool mPreviousEventSet;
+};
+
+class AccelSensor : public Sensor {
+  public:
+    AccelSensor(int32_t sensorHandle, ISensorsEventCallback* callback);
+
+  protected:
+    virtual void readEventPayload(EventPayload& payload) override;
+};
+
+class GyroSensor : public Sensor {
+  public:
+    GyroSensor(int32_t sensorHandle, ISensorsEventCallback* callback);
+
+  protected:
+    virtual void readEventPayload(EventPayload& payload) override;
+};
+
+class AmbientTempSensor : public OnChangeSensor {
+  public:
+    AmbientTempSensor(int32_t sensorHandle, ISensorsEventCallback* callback);
+
+  protected:
+    virtual void readEventPayload(EventPayload& payload) override;
+};
+
+class PressureSensor : public Sensor {
+  public:
+    PressureSensor(int32_t sensorHandle, ISensorsEventCallback* callback);
+
+  protected:
+    virtual void readEventPayload(EventPayload& payload) override;
+};
+
+class MagnetometerSensor : public Sensor {
+  public:
+    MagnetometerSensor(int32_t sensorHandle, ISensorsEventCallback* callback);
+
+  protected:
+    virtual void readEventPayload(EventPayload& payload) override;
+};
+
+class LightSensor : public OnChangeSensor {
+  public:
+    LightSensor(int32_t sensorHandle, ISensorsEventCallback* callback);
+
+  protected:
+    virtual void readEventPayload(EventPayload& payload) override;
+};
+
+class ProximitySensor : public OnChangeSensor {
+  public:
+    ProximitySensor(int32_t sensorHandle, ISensorsEventCallback* callback);
+
+  protected:
+    virtual void readEventPayload(EventPayload& payload) override;
+};
+
+class RelativeHumiditySensor : public OnChangeSensor {
+  public:
+    RelativeHumiditySensor(int32_t sensorHandle, ISensorsEventCallback* callback);
+
+  protected:
+    virtual void readEventPayload(EventPayload& payload) override;
+};
+
+class HingeAngleSensor : public OnChangeSensor {
+  public:
+    HingeAngleSensor(int32_t sensorHandle, ISensorsEventCallback* callback);
+
+  protected:
+    virtual void readEventPayload(EventPayload& payload) override;
+};
+
+}  // namespace sensors
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/sensors/aidl/default/include/sensors-impl/Sensors.h b/sensors/aidl/default/include/sensors-impl/Sensors.h
new file mode 100644
index 0000000..e270d96
--- /dev/null
+++ b/sensors/aidl/default/include/sensors-impl/Sensors.h
@@ -0,0 +1,216 @@
+/*
+ * 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/common/fmq/SynchronizedReadWrite.h>
+#include <aidl/android/hardware/sensors/BnSensors.h>
+#include <fmq/AidlMessageQueue.h>
+#include <hardware_legacy/power.h>
+#include <map>
+#include "Sensor.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace sensors {
+
+using aidl::android::hardware::common::fmq::SynchronizedReadWrite;
+using ::android::AidlMessageQueue;
+using ::android::OK;
+using ::android::status_t;
+using ::android::hardware::EventFlag;
+
+class Sensors : public BnSensors, public ISensorsEventCallback {
+    static constexpr const char* kWakeLockName = "SensorsHAL_WAKEUP";
+
+  public:
+    Sensors()
+        : mEventQueueFlag(nullptr),
+          mNextHandle(1),
+          mOutstandingWakeUpEvents(0),
+          mReadWakeLockQueueRun(false),
+          mAutoReleaseWakeLockTime(0),
+          mHasWakeLock(false) {
+        AddSensor<AccelSensor>();
+        AddSensor<GyroSensor>();
+        AddSensor<AmbientTempSensor>();
+        AddSensor<PressureSensor>();
+        AddSensor<MagnetometerSensor>();
+        AddSensor<LightSensor>();
+        AddSensor<ProximitySensor>();
+        AddSensor<RelativeHumiditySensor>();
+        AddSensor<HingeAngleSensor>();
+    }
+
+    virtual ~Sensors() {
+        deleteEventFlag();
+        mReadWakeLockQueueRun = false;
+        mWakeLockThread.join();
+    }
+
+    ::ndk::ScopedAStatus activate(int32_t in_sensorHandle, bool in_enabled) override;
+    ::ndk::ScopedAStatus batch(int32_t in_sensorHandle, int64_t in_samplingPeriodNs,
+                               int64_t in_maxReportLatencyNs) override;
+    ::ndk::ScopedAStatus configDirectReport(
+            int32_t in_sensorHandle, int32_t in_channelHandle,
+            ::aidl::android::hardware::sensors::ISensors::RateLevel in_rate,
+            int32_t* _aidl_return) override;
+    ::ndk::ScopedAStatus flush(int32_t in_sensorHandle) override;
+    ::ndk::ScopedAStatus getSensorsList(
+            std::vector<::aidl::android::hardware::sensors::SensorInfo>* _aidl_return) override;
+    ::ndk::ScopedAStatus initialize(
+            const ::aidl::android::hardware::common::fmq::MQDescriptor<
+                    ::aidl::android::hardware::sensors::Event,
+                    ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>&
+                    in_eventQueueDescriptor,
+            const ::aidl::android::hardware::common::fmq::MQDescriptor<
+                    int32_t, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite>&
+                    in_wakeLockDescriptor,
+            const std::shared_ptr<::aidl::android::hardware::sensors::ISensorsCallback>&
+                    in_sensorsCallback) override;
+    ::ndk::ScopedAStatus injectSensorData(
+            const ::aidl::android::hardware::sensors::Event& in_event) override;
+    ::ndk::ScopedAStatus registerDirectChannel(
+            const ::aidl::android::hardware::sensors::ISensors::SharedMemInfo& in_mem,
+            int32_t* _aidl_return) override;
+    ::ndk::ScopedAStatus setOperationMode(
+            ::aidl::android::hardware::sensors::ISensors::OperationMode in_mode) override;
+    ::ndk::ScopedAStatus unregisterDirectChannel(int32_t in_channelHandle) override;
+
+    void postEvents(const std::vector<Event>& events, bool wakeup) override {
+        std::lock_guard<std::mutex> lock(mWriteLock);
+        if (mEventQueue == nullptr) {
+            return;
+        }
+        if (mEventQueue->write(&events.front(), events.size())) {
+            mEventQueueFlag->wake(
+                    static_cast<uint32_t>(BnSensors::EVENT_QUEUE_FLAG_BITS_READ_AND_PROCESS));
+
+            if (wakeup) {
+                // Keep track of the number of outstanding WAKE_UP events in order to properly hold
+                // a wake lock until the framework has secured a wake lock
+                updateWakeLock(events.size(), 0 /* eventsHandled */);
+            }
+        }
+    }
+
+  protected:
+    // Add a new sensor
+    template <class SensorType>
+    void AddSensor() {
+        std::shared_ptr<SensorType> sensor =
+                std::make_shared<SensorType>(mNextHandle++ /* sensorHandle */, this /* callback */);
+        mSensors[sensor->getSensorInfo().sensorHandle] = sensor;
+    }
+
+    // Utility function to delete the Event Flag
+    void deleteEventFlag() {
+        if (mEventQueueFlag != nullptr) {
+            status_t status = EventFlag::deleteEventFlag(&mEventQueueFlag);
+            if (status != OK) {
+                ALOGI("Failed to delete event flag: %d", status);
+            }
+        }
+    }
+
+    static void startReadWakeLockThread(Sensors* sensors) { sensors->readWakeLockFMQ(); }
+
+    // Function to read the Wake Lock FMQ and release the wake lock when appropriate
+    void readWakeLockFMQ() {
+        while (mReadWakeLockQueueRun.load()) {
+            constexpr int64_t kReadTimeoutNs = 500 * 1000 * 1000;  // 500 ms
+            int32_t eventsHandled = 0;
+
+            // Read events from the Wake Lock FMQ. Timeout after a reasonable amount of time to
+            // ensure that any held wake lock is able to be released if it is held for too long.
+            mWakeLockQueue->readBlocking(
+                    &eventsHandled, 1 /* count */, 0 /* readNotification */,
+                    static_cast<uint32_t>(WAKE_LOCK_QUEUE_FLAG_BITS_DATA_WRITTEN), kReadTimeoutNs);
+            updateWakeLock(0 /* eventsWritten */, eventsHandled);
+        }
+    }
+
+    /**
+     * Responsible for acquiring and releasing a wake lock when there are unhandled WAKE_UP events
+     */
+    void updateWakeLock(int32_t eventsWritten, int32_t eventsHandled) {
+        std::lock_guard<std::mutex> lock(mWakeLockLock);
+        int32_t newVal = mOutstandingWakeUpEvents + eventsWritten - eventsHandled;
+        if (newVal < 0) {
+            mOutstandingWakeUpEvents = 0;
+        } else {
+            mOutstandingWakeUpEvents = newVal;
+        }
+
+        if (eventsWritten > 0) {
+            // Update the time at which the last WAKE_UP event was sent
+            mAutoReleaseWakeLockTime = ::android::uptimeMillis() +
+                                       static_cast<uint32_t>(WAKE_LOCK_TIMEOUT_SECONDS) * 1000;
+        }
+
+        if (!mHasWakeLock && mOutstandingWakeUpEvents > 0 &&
+            acquire_wake_lock(PARTIAL_WAKE_LOCK, kWakeLockName) == 0) {
+            mHasWakeLock = true;
+        } else if (mHasWakeLock) {
+            // Check if the wake lock should be released automatically if
+            // SensorTimeout::WAKE_LOCK_SECONDS has elapsed since the last WAKE_UP event was written
+            // to the Wake Lock FMQ.
+            if (::android::uptimeMillis() > mAutoReleaseWakeLockTime) {
+                ALOGD("No events read from wake lock FMQ for %d seconds, auto releasing wake lock",
+                      WAKE_LOCK_TIMEOUT_SECONDS);
+                mOutstandingWakeUpEvents = 0;
+            }
+
+            if (mOutstandingWakeUpEvents == 0 && release_wake_lock(kWakeLockName) == 0) {
+                mHasWakeLock = false;
+            }
+        }
+    }
+
+  private:
+    // The Event FMQ where sensor events are written
+    std::unique_ptr<AidlMessageQueue<Event, SynchronizedReadWrite>> mEventQueue;
+    // The Wake Lock FMQ that is read to determine when the framework has handled WAKE_UP events
+    std::unique_ptr<AidlMessageQueue<int32_t, SynchronizedReadWrite>> mWakeLockQueue;
+    // Event Flag to signal to the framework when sensor events are available to be read
+    EventFlag* mEventQueueFlag;
+    // Callback for asynchronous events, such as dynamic sensor connections.
+    std::shared_ptr<::aidl::android::hardware::sensors::ISensorsCallback> mCallback;
+    // A map of the available sensors.
+    std::map<int32_t, std::shared_ptr<Sensor>> mSensors;
+    // The next available sensor handle.
+    int32_t mNextHandle;
+    // Lock to protect writes to the FMQs.
+    std::mutex mWriteLock;
+    // Lock to protect acquiring and releasing the wake lock
+    std::mutex mWakeLockLock;
+    // Track the number of WAKE_UP events that have not been handled by the framework
+    uint32_t mOutstandingWakeUpEvents;
+    // A thread to read the Wake Lock FMQ
+    std::thread mWakeLockThread;
+    // Flag to indicate that the Wake Lock Thread should continue to run
+    std::atomic_bool mReadWakeLockQueueRun;
+    // Track the time when the wake lock should automatically be released
+    int64_t mAutoReleaseWakeLockTime;
+    // Flag to indicate if a wake lock has been acquired
+    bool mHasWakeLock;
+};
+
+}  // namespace sensors
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/sensors/aidl/default/main.cpp b/sensors/aidl/default/main.cpp
new file mode 100644
index 0000000..8a5a7de
--- /dev/null
+++ b/sensors/aidl/default/main.cpp
@@ -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.
+ */
+
+#include "sensors-impl/Sensors.h"
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+using aidl::android::hardware::sensors::Sensors;
+
+int main() {
+    ABinderProcess_setThreadPoolMaxThreadCount(0);
+
+    // Make a default sensors service
+    auto sensor = ndk::SharedRefBase::make<Sensors>();
+    const std::string sensorName = std::string() + Sensors::descriptor + "/default";
+    binder_status_t status =
+            AServiceManager_addService(sensor->asBinder().get(), sensorName.c_str());
+    CHECK_EQ(status, STATUS_OK);
+
+    ABinderProcess_joinThreadPool();
+    return EXIT_FAILURE;  // should not reach
+}
diff --git a/sensors/aidl/default/sensors-default.rc b/sensors/aidl/default/sensors-default.rc
new file mode 100644
index 0000000..96da85d
--- /dev/null
+++ b/sensors/aidl/default/sensors-default.rc
@@ -0,0 +1,5 @@
+service vendor.sensors-default /vendor/bin/hw/android.hardware.sensors-service.example
+    class hal
+    user system
+    group system
+    rlimit rtprio 10 10
diff --git a/sensors/aidl/default/sensors-default.xml b/sensors/aidl/default/sensors-default.xml
new file mode 100644
index 0000000..7898a6b
--- /dev/null
+++ b/sensors/aidl/default/sensors-default.xml
@@ -0,0 +1,7 @@
+<manifest version="1.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.sensors</name>
+        <version>1</version>
+        <fqname>ISensors/default</fqname>
+    </hal>
+</manifest>
diff --git a/sensors/aidl/vts/Android.bp b/sensors/aidl/vts/Android.bp
new file mode 100644
index 0000000..b5a5f15
--- /dev/null
+++ b/sensors/aidl/vts/Android.bp
@@ -0,0 +1,51 @@
+// 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 {
+    // 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: "VtsAidlHalSensorsTargetTest",
+    defaults: [
+        "VtsHalTargetTestDefaults",
+        "use_libaidlvintf_gtest_helper_static",
+    ],
+    srcs: [
+        "VtsAidlHalSensorsTargetTest.cpp",
+        "SensorsAidlEnvironment.cpp",
+    ],
+    shared_libs: [
+        "libbinder",
+        "libbinder_ndk",
+        "libvndksupport",
+        "libfmq",
+        "android.hardware.common-V2-ndk",
+        "android.hardware.common.fmq-V1-ndk",
+    ],
+    static_libs: [
+        "android.hardware.sensors-V1-ndk",
+        "VtsHalSensorsTargetTestUtils",
+        "libaidlcommonsupport",
+    ],
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
+}
diff --git a/sensors/aidl/vts/OWNERS b/sensors/aidl/vts/OWNERS
new file mode 100644
index 0000000..90c2330
--- /dev/null
+++ b/sensors/aidl/vts/OWNERS
@@ -0,0 +1,3 @@
+arthuri@google.com
+bduddie@google.com
+stange@google.com
diff --git a/sensors/aidl/vts/SensorsAidlEnvironment.cpp b/sensors/aidl/vts/SensorsAidlEnvironment.cpp
new file mode 100644
index 0000000..e71251f
--- /dev/null
+++ b/sensors/aidl/vts/SensorsAidlEnvironment.cpp
@@ -0,0 +1,164 @@
+/*
+ * 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 "SensorsAidlEnvironment.h"
+
+#include <android/binder_manager.h>
+#include <log/log.h>
+
+#include <aidl/android/hardware/sensors/BnSensorsCallback.h>
+
+using aidl::android::hardware::sensors::BnSensorsCallback;
+using aidl::android::hardware::sensors::SensorInfo;
+using android::hardware::EventFlag;
+using ndk::ScopedAStatus;
+using ndk::SpAIBinder;
+
+namespace {
+
+void serviceDied(void* /* cookie */) {
+    ALOGE("Sensors HAL died (likely crashed) during test");
+    FAIL() << "Sensors HAL died during test";
+}
+
+class NoOpSensorsCallback : public BnSensorsCallback {
+  public:
+    ScopedAStatus onDynamicSensorsConnected(
+            const std::vector<SensorInfo>& /* sensorInfos */) override {
+        return ScopedAStatus::ok();
+    }
+
+    ScopedAStatus onDynamicSensorsDisconnected(
+            const std::vector<int32_t>& /* sensorHandles */) override {
+        return ScopedAStatus::ok();
+    }
+};
+
+}  // anonymous namespace
+
+SensorsAidlEnvironment::SensorsAidlEnvironment(const std::string& service_name)
+    : SensorsVtsEnvironmentBase(service_name),
+      mCallback(ndk::SharedRefBase::make<NoOpSensorsCallback>()),
+      mDeathRecipient(AIBinder_DeathRecipient_new(serviceDied)) {}
+
+bool SensorsAidlEnvironment::resetHal() {
+    bool succeed = false;
+    do {
+        mSensors = ISensors::fromBinder(
+                SpAIBinder(AServiceManager_waitForService(mServiceName.c_str())));
+        if (mSensors == nullptr) {
+            break;
+        }
+
+        AIBinder_linkToDeath(mSensors->asBinder().get(), mDeathRecipient.get(), this);
+
+        // Initialize FMQs
+        mWakeLockQueue = std::make_unique<WakeLockQueue>(MAX_RECEIVE_BUFFER_EVENT_COUNT,
+                                                         true /* configureEventFlagWord */);
+        mEventQueue = std::make_unique<EventQueue>(MAX_RECEIVE_BUFFER_EVENT_COUNT,
+                                                   true /* configureEventFlagWord */);
+
+        if (mWakeLockQueue == nullptr || mEventQueue == nullptr) {
+            break;
+        }
+
+        EventFlag::deleteEventFlag(&mEventQueueFlag);
+        EventFlag::createEventFlag(mEventQueue->getEventFlagWord(), &mEventQueueFlag);
+        if (mEventQueueFlag == nullptr) {
+            break;
+        }
+
+        mSensors->initialize(mEventQueue->dupeDesc(), mWakeLockQueue->dupeDesc(), mCallback);
+
+        std::vector<SensorInfo> sensorList;
+        if (!mSensors->getSensorsList(&sensorList).isOk()) {
+            break;
+        }
+
+        // stop each sensor individually
+        bool ok = true;
+        for (const auto& i : sensorList) {
+            if (!mSensors->activate(i.sensorHandle, false).isOk()) {
+                ok = false;
+                break;
+            }
+        }
+
+        if (!ok) {
+            break;
+        }
+
+        // mark it done
+        succeed = true;
+    } while (0);
+
+    if (!succeed) {
+        mSensors = nullptr;
+    }
+
+    return succeed;
+}
+
+void SensorsAidlEnvironment::TearDown() {
+    mStopThread = true;
+
+    if (mEventQueueFlag != nullptr) {
+        // Wake up the event queue so the poll thread can exit
+        mEventQueueFlag->wake(ISensors::EVENT_QUEUE_FLAG_BITS_READ_AND_PROCESS);
+        if (mPollThread.joinable()) {
+            mPollThread.join();
+        }
+
+        EventFlag::deleteEventFlag(&mEventQueueFlag);
+    }
+}
+
+void SensorsAidlEnvironment::startPollingThread() {
+    mStopThread = false;
+    mEvents.reserve(MAX_RECEIVE_BUFFER_EVENT_COUNT);
+    mPollThread = std::thread(pollingThread, this);
+}
+
+void SensorsAidlEnvironment::readEvents() {
+    size_t availableEvents = mEventQueue->availableToRead();
+
+    if (availableEvents == 0) {
+        uint32_t eventFlagState = 0;
+
+        mEventQueueFlag->wait(ISensors::EVENT_QUEUE_FLAG_BITS_READ_AND_PROCESS, &eventFlagState);
+        availableEvents = mEventQueue->availableToRead();
+    }
+
+    size_t eventsToRead = std::min(availableEvents, mEventBuffer.size());
+    if (eventsToRead > 0) {
+        if (mEventQueue->read(mEventBuffer.data(), eventsToRead)) {
+            mEventQueueFlag->wake(ISensors::EVENT_QUEUE_FLAG_BITS_EVENTS_READ);
+            for (size_t i = 0; i < eventsToRead; i++) {
+                addEvent(mEventBuffer[i]);
+            }
+        }
+    }
+}
+
+void SensorsAidlEnvironment::pollingThread(SensorsAidlEnvironment* env) {
+    ALOGD("polling thread start");
+
+    while (!env->mStopThread.load()) {
+        env->readEvents();
+    }
+
+    ALOGD("polling thread end");
+}
diff --git a/sensors/aidl/vts/SensorsAidlEnvironment.h b/sensors/aidl/vts/SensorsAidlEnvironment.h
new file mode 100644
index 0000000..2f5f287
--- /dev/null
+++ b/sensors/aidl/vts/SensorsAidlEnvironment.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_SENSORS_AIDL_ENVIRONMENT_H
+#define ANDROID_SENSORS_AIDL_ENVIRONMENT_H
+
+#include "sensors-vts-utils/SensorsVtsEnvironmentBase.h"
+
+#include <atomic>
+#include <memory>
+#include <mutex>
+#include <thread>
+#include <vector>
+
+#include <aidl/android/hardware/sensors/ISensors.h>
+#include <fmq/AidlMessageQueue.h>
+
+using aidl::android::hardware::common::fmq::SynchronizedReadWrite;
+using aidl::android::hardware::sensors::Event;
+using aidl::android::hardware::sensors::ISensors;
+using aidl::android::hardware::sensors::ISensorsCallback;
+
+static constexpr size_t MAX_RECEIVE_BUFFER_EVENT_COUNT = 256;
+
+class SensorsAidlTest;
+
+class SensorsAidlEnvironment : public SensorsVtsEnvironmentBase<Event> {
+  public:
+    virtual void TearDown() override;
+
+  protected:
+    friend SensorsAidlTest;
+    SensorsAidlEnvironment(const std::string& service_name);
+
+    /**
+     * Resets the HAL with new FMQs and a new Event Flag
+     *
+     * @return bool true if successful, false otherwise
+     */
+    bool resetHal() override;
+
+    /**
+     * Starts the polling thread that reads sensor events from the Event FMQ
+     */
+    void startPollingThread() override;
+
+    /**
+     * Thread responsible for calling functions to read Event FMQ
+     *
+     * @param env SensorEnvironment to being polling for events on
+     */
+    static void pollingThread(SensorsAidlEnvironment* env);
+
+    /**
+     * Reads and saves sensor events from the Event FMQ
+     */
+    void readEvents();
+
+    GTEST_DISALLOW_COPY_AND_ASSIGN_(SensorsAidlEnvironment);
+
+    /**
+     * Pointer to the Sensors HAL Interface that allows the test to call HAL functions.
+     */
+    std::shared_ptr<ISensors> mSensors;
+    std::shared_ptr<ISensorsCallback> mCallback;
+
+    ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
+
+    /**
+     * Type used to simplify the creation of the Wake Lock FMQ
+     */
+    typedef android::AidlMessageQueue<int32_t, SynchronizedReadWrite> WakeLockQueue;
+    typedef android::AidlMessageQueue<Event, SynchronizedReadWrite> EventQueue;
+
+    /**
+     * The Wake Lock FMQ is used by the test to notify the Sensors HAL whenever it has processed
+     * WAKE_UP sensor events.
+     */
+    std::unique_ptr<WakeLockQueue> mWakeLockQueue;
+    std::unique_ptr<EventQueue> mEventQueue;
+
+    /**
+     * The Event Queue Flag notifies the test framework when sensor events have been written to the
+     * Event FMQ by the Sensors HAL.
+     */
+    ::android::hardware::EventFlag* mEventQueueFlag;
+
+    std::atomic_bool mStopThread;
+    std::thread mPollThread;
+
+    /**
+     * An array that is used to store sensor events read from the Event FMQ
+     */
+    std::array<Event, MAX_RECEIVE_BUFFER_EVENT_COUNT> mEventBuffer;
+};
+
+#endif  // ANDROID_SENSORS_AIDL_ENVIRONMENT_H
diff --git a/sensors/aidl/vts/SensorsAidlTestSharedMemory.h b/sensors/aidl/vts/SensorsAidlTestSharedMemory.h
new file mode 100644
index 0000000..4b5916a
--- /dev/null
+++ b/sensors/aidl/vts/SensorsAidlTestSharedMemory.h
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_SENSORS_AIDL_TEST_SHARED_MEMORY_H
+#define ANDROID_SENSORS_AIDL_TEST_SHARED_MEMORY_H
+
+#include "sensors-vts-utils/GrallocWrapper.h"
+
+#include <aidlcommonsupport/NativeHandle.h>
+#include <android-base/macros.h>
+#include <log/log.h>
+
+#include <sys/mman.h>
+#include <cinttypes>
+
+#include <cutils/ashmem.h>
+
+using ::aidl::android::hardware::sensors::BnSensors;
+using ::aidl::android::hardware::sensors::Event;
+using ::aidl::android::hardware::sensors::ISensors;
+using ::aidl::android::hardware::sensors::SensorType;
+
+template <class SensorType, class Event>
+class SensorsAidlTestSharedMemory {
+  public:
+    static SensorsAidlTestSharedMemory* create(ISensors::SharedMemInfo::SharedMemType type,
+                                               size_t size) {
+        constexpr size_t kMaxSize =
+                128 * 1024 * 1024;  // sensor test should not need more than 128M
+        if (size == 0 || size >= kMaxSize) {
+            return nullptr;
+        }
+
+        auto m = new SensorsAidlTestSharedMemory<SensorType, Event>(type, size);
+        if (m->mSize != size || m->mBuffer == nullptr) {
+            delete m;
+            m = nullptr;
+        }
+        return m;
+    }
+
+    ISensors::SharedMemInfo getSharedMemInfo() const {
+        ISensors::SharedMemInfo mem = {
+                .type = mType,
+                .format = ISensors::SharedMemInfo::SharedMemFormat::SENSORS_EVENT,
+                .size = static_cast<int32_t>(mSize),
+                .memoryHandle = android::dupToAidl(mNativeHandle)};
+        return mem;
+    }
+    char* getBuffer() const { return mBuffer; }
+    size_t getSize() const { return mSize; }
+    std::vector<Event> parseEvents(int64_t lastCounter = -1, size_t offset = 0) const {
+        constexpr size_t kEventSize =
+                static_cast<size_t>(BnSensors::DIRECT_REPORT_SENSOR_EVENT_TOTAL_LENGTH);
+        constexpr size_t kOffsetSize =
+                static_cast<size_t>(BnSensors::DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_FIELD);
+        constexpr size_t kOffsetToken =
+                static_cast<size_t>(BnSensors::DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_REPORT_TOKEN);
+        constexpr size_t kOffsetType =
+                static_cast<size_t>(BnSensors::DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_SENSOR_TYPE);
+        constexpr size_t kOffsetAtomicCounter = static_cast<size_t>(
+                BnSensors::DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_ATOMIC_COUNTER);
+        constexpr size_t kOffsetTimestamp =
+                static_cast<size_t>(BnSensors::DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_TIMESTAMP);
+        constexpr size_t kOffsetData =
+                static_cast<size_t>(BnSensors::DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_DATA);
+
+        std::vector<Event> events;
+        std::vector<float> data(16);
+
+        while (offset + kEventSize <= mSize) {
+            int64_t atomicCounter =
+                    *reinterpret_cast<uint32_t*>(mBuffer + offset + kOffsetAtomicCounter);
+            if (atomicCounter <= lastCounter) {
+                ALOGV("atomicCounter = %" PRId64 ", lastCounter = %" PRId64, atomicCounter,
+                      lastCounter);
+                break;
+            }
+
+            int32_t size = *reinterpret_cast<int32_t*>(mBuffer + offset + kOffsetSize);
+            if (size != kEventSize) {
+                // unknown error, events parsed may be wrong, remove all
+                events.clear();
+                break;
+            }
+
+            int32_t token = *reinterpret_cast<int32_t*>(mBuffer + offset + kOffsetToken);
+            int32_t type = *reinterpret_cast<int32_t*>(mBuffer + offset + kOffsetType);
+            int64_t timestamp = *reinterpret_cast<int64_t*>(mBuffer + offset + kOffsetTimestamp);
+
+            ALOGV("offset = %zu, cnt %" PRId64 ", token %" PRId32 ", type %" PRId32
+                  ", timestamp %" PRId64,
+                  offset, atomicCounter, token, type, timestamp);
+
+            Event event = {
+                    .timestamp = timestamp,
+                    .sensorHandle = token,
+                    .sensorType = type,
+            };
+
+            event.set<Event::Data>(reinterpret_cast<float*>(mBuffer + offset + kOffsetData));
+            // event.u.data = android::hardware::hidl_array<float,
+            // 16>(reinterpret_cast<float*>(mBuffer + offset + kOffsetData));
+
+            events.push_back(event);
+
+            lastCounter = atomicCounter;
+            offset += kEventSize;
+        }
+
+        return events;
+    }
+
+    virtual ~SensorsAidlTestSharedMemory() {
+        switch (mType) {
+            case ISensors::SharedMemInfo::SharedMemType::ASHMEM: {
+                if (mSize != 0) {
+                    ::munmap(mBuffer, mSize);
+                    mBuffer = nullptr;
+
+                    ::native_handle_close(mNativeHandle);
+                    ::native_handle_delete(mNativeHandle);
+
+                    mNativeHandle = nullptr;
+                    mSize = 0;
+                }
+                break;
+            }
+            case ISensors::SharedMemInfo::SharedMemType::GRALLOC: {
+                if (mSize != 0) {
+                    mGrallocWrapper->freeBuffer(mNativeHandle);
+                    mNativeHandle = nullptr;
+                    mSize = 0;
+                }
+                break;
+            }
+            default: {
+                if (mNativeHandle != nullptr || mSize != 0 || mBuffer != nullptr) {
+                    ALOGE("SensorsAidlTestSharedMemory %p not properly destructed: "
+                          "type %d, native handle %p, size %zu, buffer %p",
+                          this, static_cast<int>(mType), mNativeHandle, mSize, mBuffer);
+                }
+                break;
+            }
+        }
+    }
+
+  private:
+    SensorsAidlTestSharedMemory(ISensors::SharedMemInfo::SharedMemType type, size_t size)
+        : mType(type), mSize(0), mBuffer(nullptr) {
+        native_handle_t* handle = nullptr;
+        char* buffer = nullptr;
+        switch (type) {
+            case ISensors::SharedMemInfo::SharedMemType::ASHMEM: {
+                int fd;
+                handle = ::native_handle_create(1 /*nFds*/, 0 /*nInts*/);
+                if (handle != nullptr) {
+                    handle->data[0] = fd =
+                            ::ashmem_create_region("SensorsAidlTestSharedMemory", size);
+                    if (handle->data[0] > 0) {
+                        // memory is pinned by default
+                        buffer = static_cast<char*>(
+                                ::mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0));
+                        if (buffer != reinterpret_cast<char*>(MAP_FAILED)) {
+                            break;
+                        }
+                        ::native_handle_close(handle);
+                    }
+                    ::native_handle_delete(handle);
+                    handle = nullptr;
+                }
+                break;
+            }
+            case ISensors::SharedMemInfo::SharedMemType::GRALLOC: {
+                mGrallocWrapper = std::make_unique<::android::GrallocWrapper>();
+                if (!mGrallocWrapper->isInitialized()) {
+                    break;
+                }
+
+                std::pair<native_handle_t*, void*> buf = mGrallocWrapper->allocate(size);
+                handle = buf.first;
+                buffer = static_cast<char*>(buf.second);
+                break;
+            }
+            default:
+                break;
+        }
+
+        if (buffer != nullptr) {
+            mNativeHandle = handle;
+            mSize = size;
+            mBuffer = buffer;
+        }
+    }
+
+    ISensors::SharedMemInfo::SharedMemType mType;
+    native_handle_t* mNativeHandle;
+    size_t mSize;
+    char* mBuffer;
+    std::unique_ptr<::android::GrallocWrapper> mGrallocWrapper;
+
+    DISALLOW_COPY_AND_ASSIGN(SensorsAidlTestSharedMemory);
+};
+
+#endif  // ANDROID_SENSORS_TEST_SHARED_MEMORY_H
diff --git a/sensors/aidl/vts/VtsAidlHalSensorsTargetTest.cpp b/sensors/aidl/vts/VtsAidlHalSensorsTargetTest.cpp
new file mode 100644
index 0000000..608a4b0
--- /dev/null
+++ b/sensors/aidl/vts/VtsAidlHalSensorsTargetTest.cpp
@@ -0,0 +1,1065 @@
+/*
+ * 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/sensors/BnSensors.h>
+#include <aidl/android/hardware/sensors/ISensors.h>
+#include <android/binder_manager.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+#include <hardware/sensors.h>
+#include <log/log.h>
+#include <utils/SystemClock.h>
+
+#include "SensorsAidlEnvironment.h"
+#include "SensorsAidlTestSharedMemory.h"
+#include "sensors-vts-utils/SensorsVtsEnvironmentBase.h"
+
+#include <cinttypes>
+#include <condition_variable>
+#include <map>
+#include <unordered_map>
+#include <unordered_set>
+#include <vector>
+
+using aidl::android::hardware::sensors::Event;
+using aidl::android::hardware::sensors::ISensors;
+using aidl::android::hardware::sensors::SensorInfo;
+using aidl::android::hardware::sensors::SensorStatus;
+using aidl::android::hardware::sensors::SensorType;
+using android::ProcessState;
+using std::chrono::duration_cast;
+
+constexpr size_t kEventSize =
+        static_cast<size_t>(ISensors::DIRECT_REPORT_SENSOR_EVENT_TOTAL_LENGTH);
+
+namespace {
+
+static void assertTypeMatchStringType(SensorType type, const std::string& stringType) {
+    if (type >= SensorType::DEVICE_PRIVATE_BASE) {
+        return;
+    }
+
+    switch (type) {
+#define CHECK_TYPE_STRING_FOR_SENSOR_TYPE(type)                      \
+    case SensorType::type:                                           \
+        ASSERT_STREQ(SENSOR_STRING_TYPE_##type, stringType.c_str()); \
+        break;
+        CHECK_TYPE_STRING_FOR_SENSOR_TYPE(ACCELEROMETER);
+        CHECK_TYPE_STRING_FOR_SENSOR_TYPE(ACCELEROMETER_UNCALIBRATED);
+        CHECK_TYPE_STRING_FOR_SENSOR_TYPE(ADDITIONAL_INFO);
+        CHECK_TYPE_STRING_FOR_SENSOR_TYPE(AMBIENT_TEMPERATURE);
+        CHECK_TYPE_STRING_FOR_SENSOR_TYPE(DEVICE_ORIENTATION);
+        CHECK_TYPE_STRING_FOR_SENSOR_TYPE(DYNAMIC_SENSOR_META);
+        CHECK_TYPE_STRING_FOR_SENSOR_TYPE(GAME_ROTATION_VECTOR);
+        CHECK_TYPE_STRING_FOR_SENSOR_TYPE(GEOMAGNETIC_ROTATION_VECTOR);
+        CHECK_TYPE_STRING_FOR_SENSOR_TYPE(GLANCE_GESTURE);
+        CHECK_TYPE_STRING_FOR_SENSOR_TYPE(GRAVITY);
+        CHECK_TYPE_STRING_FOR_SENSOR_TYPE(GYROSCOPE);
+        CHECK_TYPE_STRING_FOR_SENSOR_TYPE(GYROSCOPE_UNCALIBRATED);
+        CHECK_TYPE_STRING_FOR_SENSOR_TYPE(HEART_BEAT);
+        CHECK_TYPE_STRING_FOR_SENSOR_TYPE(HEART_RATE);
+        CHECK_TYPE_STRING_FOR_SENSOR_TYPE(LIGHT);
+        CHECK_TYPE_STRING_FOR_SENSOR_TYPE(LINEAR_ACCELERATION);
+        CHECK_TYPE_STRING_FOR_SENSOR_TYPE(LOW_LATENCY_OFFBODY_DETECT);
+        CHECK_TYPE_STRING_FOR_SENSOR_TYPE(MAGNETIC_FIELD);
+        CHECK_TYPE_STRING_FOR_SENSOR_TYPE(MAGNETIC_FIELD_UNCALIBRATED);
+        CHECK_TYPE_STRING_FOR_SENSOR_TYPE(MOTION_DETECT);
+        CHECK_TYPE_STRING_FOR_SENSOR_TYPE(ORIENTATION);
+        CHECK_TYPE_STRING_FOR_SENSOR_TYPE(PICK_UP_GESTURE);
+        CHECK_TYPE_STRING_FOR_SENSOR_TYPE(POSE_6DOF);
+        CHECK_TYPE_STRING_FOR_SENSOR_TYPE(PRESSURE);
+        CHECK_TYPE_STRING_FOR_SENSOR_TYPE(PROXIMITY);
+        CHECK_TYPE_STRING_FOR_SENSOR_TYPE(RELATIVE_HUMIDITY);
+        CHECK_TYPE_STRING_FOR_SENSOR_TYPE(ROTATION_VECTOR);
+        CHECK_TYPE_STRING_FOR_SENSOR_TYPE(SIGNIFICANT_MOTION);
+        CHECK_TYPE_STRING_FOR_SENSOR_TYPE(STATIONARY_DETECT);
+        CHECK_TYPE_STRING_FOR_SENSOR_TYPE(STEP_COUNTER);
+        CHECK_TYPE_STRING_FOR_SENSOR_TYPE(STEP_DETECTOR);
+        CHECK_TYPE_STRING_FOR_SENSOR_TYPE(TILT_DETECTOR);
+        CHECK_TYPE_STRING_FOR_SENSOR_TYPE(WAKE_GESTURE);
+        CHECK_TYPE_STRING_FOR_SENSOR_TYPE(WRIST_TILT_GESTURE);
+        default:
+            FAIL() << "Type " << static_cast<int>(type)
+                   << " in android defined range is not checked, "
+                   << "stringType = " << stringType;
+#undef CHECK_TYPE_STRING_FOR_SENSOR_TYPE
+    }
+}
+
+bool isDirectChannelTypeSupported(SensorInfo sensor, ISensors::SharedMemInfo::SharedMemType type) {
+    switch (type) {
+        case ISensors::SharedMemInfo::SharedMemType::ASHMEM:
+            return (sensor.flags & SensorInfo::SENSOR_FLAG_BITS_DIRECT_CHANNEL_ASHMEM) != 0;
+        case ISensors::SharedMemInfo::SharedMemType::GRALLOC:
+            return (sensor.flags & SensorInfo::SENSOR_FLAG_BITS_DIRECT_CHANNEL_GRALLOC) != 0;
+        default:
+            return false;
+    }
+}
+
+bool isDirectReportRateSupported(SensorInfo sensor, ISensors::RateLevel rate) {
+    unsigned int r = static_cast<unsigned int>(sensor.flags &
+                                               SensorInfo::SENSOR_FLAG_BITS_MASK_DIRECT_REPORT) >>
+                     static_cast<unsigned int>(SensorInfo::SENSOR_FLAG_SHIFT_DIRECT_REPORT);
+    return r >= static_cast<unsigned int>(rate);
+}
+
+int expectedReportModeForType(SensorType type) {
+    switch (type) {
+        case SensorType::ACCELEROMETER:
+        case SensorType::ACCELEROMETER_UNCALIBRATED:
+        case SensorType::GYROSCOPE:
+        case SensorType::MAGNETIC_FIELD:
+        case SensorType::ORIENTATION:
+        case SensorType::PRESSURE:
+        case SensorType::GRAVITY:
+        case SensorType::LINEAR_ACCELERATION:
+        case SensorType::ROTATION_VECTOR:
+        case SensorType::MAGNETIC_FIELD_UNCALIBRATED:
+        case SensorType::GAME_ROTATION_VECTOR:
+        case SensorType::GYROSCOPE_UNCALIBRATED:
+        case SensorType::GEOMAGNETIC_ROTATION_VECTOR:
+        case SensorType::POSE_6DOF:
+        case SensorType::HEART_BEAT:
+            return SensorInfo::SENSOR_FLAG_BITS_CONTINUOUS_MODE;
+
+        case SensorType::LIGHT:
+        case SensorType::PROXIMITY:
+        case SensorType::RELATIVE_HUMIDITY:
+        case SensorType::AMBIENT_TEMPERATURE:
+        case SensorType::HEART_RATE:
+        case SensorType::DEVICE_ORIENTATION:
+        case SensorType::STEP_COUNTER:
+        case SensorType::LOW_LATENCY_OFFBODY_DETECT:
+            return SensorInfo::SENSOR_FLAG_BITS_ON_CHANGE_MODE;
+
+        case SensorType::SIGNIFICANT_MOTION:
+        case SensorType::WAKE_GESTURE:
+        case SensorType::GLANCE_GESTURE:
+        case SensorType::PICK_UP_GESTURE:
+        case SensorType::MOTION_DETECT:
+        case SensorType::STATIONARY_DETECT:
+            return SensorInfo::SENSOR_FLAG_BITS_ONE_SHOT_MODE;
+
+        case SensorType::STEP_DETECTOR:
+        case SensorType::TILT_DETECTOR:
+        case SensorType::WRIST_TILT_GESTURE:
+        case SensorType::DYNAMIC_SENSOR_META:
+            return SensorInfo::SENSOR_FLAG_BITS_SPECIAL_REPORTING_MODE;
+
+        default:
+            ALOGW("Type %d is not implemented in expectedReportModeForType", (int)type);
+            return INT32_MAX;
+    }
+}
+
+void assertTypeMatchReportMode(SensorType type, int reportMode) {
+    if (type >= SensorType::DEVICE_PRIVATE_BASE) {
+        return;
+    }
+
+    int expected = expectedReportModeForType(type);
+
+    ASSERT_TRUE(expected == INT32_MAX || expected == reportMode)
+            << "reportMode=" << static_cast<int>(reportMode)
+            << "expected=" << static_cast<int>(expected);
+}
+
+void assertDelayMatchReportMode(int32_t minDelayUs, int32_t maxDelayUs, int reportMode) {
+    switch (reportMode) {
+        case SensorInfo::SENSOR_FLAG_BITS_CONTINUOUS_MODE:
+            ASSERT_LT(0, minDelayUs);
+            ASSERT_LE(0, maxDelayUs);
+            break;
+        case SensorInfo::SENSOR_FLAG_BITS_ON_CHANGE_MODE:
+            ASSERT_LE(0, minDelayUs);
+            ASSERT_LE(0, maxDelayUs);
+            break;
+        case SensorInfo::SENSOR_FLAG_BITS_ONE_SHOT_MODE:
+            ASSERT_EQ(-1, minDelayUs);
+            ASSERT_EQ(0, maxDelayUs);
+            break;
+        case SensorInfo::SENSOR_FLAG_BITS_SPECIAL_REPORTING_MODE:
+            // do not enforce anything for special reporting mode
+            break;
+        default:
+            FAIL() << "Report mode " << static_cast<int>(reportMode) << " not checked";
+    }
+}
+
+void checkIsOk(ndk::ScopedAStatus status) {
+    ASSERT_TRUE(status.isOk());
+}
+
+}  // namespace
+
+class EventCallback : public IEventCallback<Event> {
+  public:
+    void reset() {
+        mFlushMap.clear();
+        mEventMap.clear();
+    }
+
+    void onEvent(const Event& event) override {
+        if (event.sensorType == SensorType::META_DATA &&
+            event.payload.get<Event::EventPayload::Tag::meta>().what ==
+                    Event::EventPayload::MetaData::MetaDataEventType::META_DATA_FLUSH_COMPLETE) {
+            std::unique_lock<std::recursive_mutex> lock(mFlushMutex);
+            mFlushMap[event.sensorHandle]++;
+            mFlushCV.notify_all();
+        } else if (event.sensorType != SensorType::ADDITIONAL_INFO) {
+            std::unique_lock<std::recursive_mutex> lock(mEventMutex);
+            mEventMap[event.sensorHandle].push_back(event);
+            mEventCV.notify_all();
+        }
+    }
+
+    int32_t getFlushCount(int32_t sensorHandle) {
+        std::unique_lock<std::recursive_mutex> lock(mFlushMutex);
+        return mFlushMap[sensorHandle];
+    }
+
+    void waitForFlushEvents(const std::vector<SensorInfo>& sensorsToWaitFor,
+                            int32_t numCallsToFlush, std::chrono::milliseconds timeout) {
+        std::unique_lock<std::recursive_mutex> lock(mFlushMutex);
+        mFlushCV.wait_for(lock, timeout,
+                          [&] { return flushesReceived(sensorsToWaitFor, numCallsToFlush); });
+    }
+
+    const std::vector<Event> getEvents(int32_t sensorHandle) {
+        std::unique_lock<std::recursive_mutex> lock(mEventMutex);
+        return mEventMap[sensorHandle];
+    }
+
+    void waitForEvents(const std::vector<SensorInfo>& sensorsToWaitFor,
+                       std::chrono::milliseconds timeout) {
+        std::unique_lock<std::recursive_mutex> lock(mEventMutex);
+        mEventCV.wait_for(lock, timeout, [&] { return eventsReceived(sensorsToWaitFor); });
+    }
+
+  protected:
+    bool flushesReceived(const std::vector<SensorInfo>& sensorsToWaitFor, int32_t numCallsToFlush) {
+        for (const SensorInfo& sensor : sensorsToWaitFor) {
+            if (getFlushCount(sensor.sensorHandle) < numCallsToFlush) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    bool eventsReceived(const std::vector<SensorInfo>& sensorsToWaitFor) {
+        for (const SensorInfo& sensor : sensorsToWaitFor) {
+            if (getEvents(sensor.sensorHandle).size() == 0) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    std::map<int32_t, int32_t> mFlushMap;
+    std::recursive_mutex mFlushMutex;
+    std::condition_variable_any mFlushCV;
+
+    std::map<int32_t, std::vector<Event>> mEventMap;
+    std::recursive_mutex mEventMutex;
+    std::condition_variable_any mEventCV;
+};
+
+class SensorsAidlTest : public testing::TestWithParam<std::string> {
+  public:
+    virtual void SetUp() override {
+        mEnvironment = new SensorsAidlEnvironment(GetParam());
+        mEnvironment->SetUp();
+
+        // Ensure that we have a valid environment before performing tests
+        ASSERT_NE(getSensors(), nullptr);
+    }
+
+    virtual void TearDown() override {
+        for (int32_t handle : mSensorHandles) {
+            activate(handle, false);
+        }
+        mSensorHandles.clear();
+
+        mEnvironment->TearDown();
+        delete mEnvironment;
+        mEnvironment = nullptr;
+    }
+
+  protected:
+    std::vector<SensorInfo> getNonOneShotSensors();
+    std::vector<SensorInfo> getNonOneShotAndNonSpecialSensors();
+    std::vector<SensorInfo> getNonOneShotAndNonOnChangeAndNonSpecialSensors();
+    std::vector<SensorInfo> getOneShotSensors();
+    std::vector<SensorInfo> getInjectEventSensors();
+
+    void verifyDirectChannel(ISensors::SharedMemInfo::SharedMemType memType);
+
+    void verifyRegisterDirectChannel(
+            std::shared_ptr<SensorsAidlTestSharedMemory<SensorType, Event>> mem,
+            int32_t* directChannelHandle, bool supportsSharedMemType,
+            bool supportsAnyDirectChannel);
+
+    void verifyConfigure(const SensorInfo& sensor, ISensors::SharedMemInfo::SharedMemType memType,
+                         int32_t directChannelHandle, bool directChannelSupported);
+
+    void queryDirectChannelSupport(ISensors::SharedMemInfo::SharedMemType memType,
+                                   bool* supportsSharedMemType, bool* supportsAnyDirectChannel);
+
+    void verifyUnregisterDirectChannel(int32_t* directChannelHandle, bool supportsAnyDirectChannel);
+
+    void checkRateLevel(const SensorInfo& sensor, int32_t directChannelHandle,
+                        ISensors::RateLevel rateLevel, int32_t* reportToken);
+
+    inline std::shared_ptr<ISensors>& getSensors() { return mEnvironment->mSensors; }
+
+    inline SensorsAidlEnvironment* getEnvironment() { return mEnvironment; }
+
+    inline bool isValidType(SensorType sensorType) { return (int)sensorType > 0; }
+
+    std::vector<SensorInfo> getSensorsList();
+
+    int32_t getInvalidSensorHandle() {
+        // Find a sensor handle that does not exist in the sensor list
+        int32_t maxHandle = 0;
+        for (const SensorInfo& sensor : getSensorsList()) {
+            maxHandle = std::max(maxHandle, sensor.sensorHandle);
+        }
+        return maxHandle + 1;
+    }
+
+    ndk::ScopedAStatus activate(int32_t sensorHandle, bool enable);
+    void activateAllSensors(bool enable);
+
+    ndk::ScopedAStatus batch(int32_t sensorHandle, int64_t samplingPeriodNs,
+                             int64_t maxReportLatencyNs) {
+        return getSensors()->batch(sensorHandle, samplingPeriodNs, maxReportLatencyNs);
+    }
+
+    ndk::ScopedAStatus flush(int32_t sensorHandle) { return getSensors()->flush(sensorHandle); }
+
+    ndk::ScopedAStatus registerDirectChannel(const ISensors::SharedMemInfo& mem,
+                                             int32_t* aidlReturn);
+
+    ndk::ScopedAStatus unregisterDirectChannel(int32_t* channelHandle) {
+        return getSensors()->unregisterDirectChannel(*channelHandle);
+    }
+
+    ndk::ScopedAStatus configDirectReport(int32_t sensorHandle, int32_t channelHandle,
+                                          ISensors::RateLevel rate, int32_t* reportToken) {
+        return getSensors()->configDirectReport(sensorHandle, channelHandle, rate, reportToken);
+    }
+
+    void runSingleFlushTest(const std::vector<SensorInfo>& sensors, bool activateSensor,
+                            int32_t expectedFlushCount, bool expectedResult);
+
+    void runFlushTest(const std::vector<SensorInfo>& sensors, bool activateSensor,
+                      int32_t flushCalls, int32_t expectedFlushCount, bool expectedResult);
+
+    inline static int32_t extractReportMode(int32_t flag) {
+        return (flag & (SensorInfo::SENSOR_FLAG_BITS_CONTINUOUS_MODE |
+                        SensorInfo::SENSOR_FLAG_BITS_ON_CHANGE_MODE |
+                        SensorInfo::SENSOR_FLAG_BITS_ONE_SHOT_MODE |
+                        SensorInfo::SENSOR_FLAG_BITS_SPECIAL_REPORTING_MODE));
+    }
+
+    // All sensors and direct channnels used
+    std::unordered_set<int32_t> mSensorHandles;
+    std::unordered_set<int32_t> mDirectChannelHandles;
+
+  private:
+    SensorsAidlEnvironment* mEnvironment;
+};
+
+ndk::ScopedAStatus SensorsAidlTest::registerDirectChannel(const ISensors::SharedMemInfo& mem,
+                                                          int32_t* aidlReturn) {
+    // If registeration of a channel succeeds, add the handle of channel to a set so that it can be
+    // unregistered when test fails. Unregister a channel does not remove the handle on purpose.
+    // Unregistering a channel more than once should not have negative effect.
+
+    ndk::ScopedAStatus status = getSensors()->registerDirectChannel(mem, aidlReturn);
+    if (status.isOk()) {
+        mDirectChannelHandles.insert(*aidlReturn);
+    }
+    return status;
+}
+
+std::vector<SensorInfo> SensorsAidlTest::getSensorsList() {
+    std::vector<SensorInfo> sensorInfoList;
+    checkIsOk(getSensors()->getSensorsList(&sensorInfoList));
+    return sensorInfoList;
+}
+
+ndk::ScopedAStatus SensorsAidlTest::activate(int32_t sensorHandle, bool enable) {
+    // If activating a sensor, add the handle in a set so that when test fails it can be turned off.
+    // The handle is not removed when it is deactivating on purpose so that it is not necessary to
+    // check the return value of deactivation. Deactivating a sensor more than once does not have
+    // negative effect.
+    if (enable) {
+        mSensorHandles.insert(sensorHandle);
+    }
+    return getSensors()->activate(sensorHandle, enable);
+}
+
+void SensorsAidlTest::activateAllSensors(bool enable) {
+    for (const SensorInfo& sensorInfo : getSensorsList()) {
+        if (isValidType(sensorInfo.type)) {
+            checkIsOk(batch(sensorInfo.sensorHandle, sensorInfo.minDelayUs,
+                            0 /* maxReportLatencyNs */));
+            checkIsOk(activate(sensorInfo.sensorHandle, enable));
+        }
+    }
+}
+
+std::vector<SensorInfo> SensorsAidlTest::getNonOneShotSensors() {
+    std::vector<SensorInfo> sensors;
+    for (const SensorInfo& info : getSensorsList()) {
+        if (extractReportMode(info.flags) != SensorInfo::SENSOR_FLAG_BITS_ONE_SHOT_MODE) {
+            sensors.push_back(info);
+        }
+    }
+    return sensors;
+}
+
+std::vector<SensorInfo> SensorsAidlTest::getNonOneShotAndNonSpecialSensors() {
+    std::vector<SensorInfo> sensors;
+    for (const SensorInfo& info : getSensorsList()) {
+        int reportMode = extractReportMode(info.flags);
+        if (reportMode != SensorInfo::SENSOR_FLAG_BITS_ONE_SHOT_MODE &&
+            reportMode != SensorInfo::SENSOR_FLAG_BITS_SPECIAL_REPORTING_MODE) {
+            sensors.push_back(info);
+        }
+    }
+    return sensors;
+}
+
+std::vector<SensorInfo> SensorsAidlTest::getNonOneShotAndNonOnChangeAndNonSpecialSensors() {
+    std::vector<SensorInfo> sensors;
+    for (const SensorInfo& info : getSensorsList()) {
+        int reportMode = extractReportMode(info.flags);
+        if (reportMode != SensorInfo::SENSOR_FLAG_BITS_ONE_SHOT_MODE &&
+            reportMode != SensorInfo::SENSOR_FLAG_BITS_ON_CHANGE_MODE &&
+            reportMode != SensorInfo::SENSOR_FLAG_BITS_SPECIAL_REPORTING_MODE) {
+            sensors.push_back(info);
+        }
+    }
+    return sensors;
+}
+
+std::vector<SensorInfo> SensorsAidlTest::getOneShotSensors() {
+    std::vector<SensorInfo> sensors;
+    for (const SensorInfo& info : getSensorsList()) {
+        if (extractReportMode(info.flags) == SensorInfo::SENSOR_FLAG_BITS_ONE_SHOT_MODE) {
+            sensors.push_back(info);
+        }
+    }
+    return sensors;
+}
+
+std::vector<SensorInfo> SensorsAidlTest::getInjectEventSensors() {
+    std::vector<SensorInfo> out;
+    std::vector<SensorInfo> sensorInfoList = getSensorsList();
+    for (const SensorInfo& info : sensorInfoList) {
+        if (info.flags & SensorInfo::SENSOR_FLAG_BITS_DATA_INJECTION) {
+            out.push_back(info);
+        }
+    }
+    return out;
+}
+
+void SensorsAidlTest::runSingleFlushTest(const std::vector<SensorInfo>& sensors,
+                                         bool activateSensor, int32_t expectedFlushCount,
+                                         bool expectedResult) {
+    runFlushTest(sensors, activateSensor, 1 /* flushCalls */, expectedFlushCount, expectedResult);
+}
+
+void SensorsAidlTest::runFlushTest(const std::vector<SensorInfo>& sensors, bool activateSensor,
+                                   int32_t flushCalls, int32_t expectedFlushCount,
+                                   bool expectedResult) {
+    EventCallback callback;
+    getEnvironment()->registerCallback(&callback);
+
+    for (const SensorInfo& sensor : sensors) {
+        // Configure and activate the sensor
+        batch(sensor.sensorHandle, sensor.maxDelayUs, 0 /* maxReportLatencyNs */);
+        activate(sensor.sensorHandle, activateSensor);
+
+        // Flush the sensor
+        for (int32_t i = 0; i < flushCalls; i++) {
+            SCOPED_TRACE(::testing::Message()
+                         << "Flush " << i << "/" << flushCalls << ": "
+                         << " handle=0x" << std::hex << std::setw(8) << std::setfill('0')
+                         << sensor.sensorHandle << std::dec
+                         << " type=" << static_cast<int>(sensor.type) << " name=" << sensor.name);
+
+            EXPECT_EQ(flush(sensor.sensorHandle).isOk(), expectedResult);
+        }
+    }
+
+    // Wait up to one second for the flush events
+    callback.waitForFlushEvents(sensors, flushCalls, std::chrono::milliseconds(1000) /* timeout */);
+
+    // Deactivate all sensors after waiting for flush events so pending flush events are not
+    // abandoned by the HAL.
+    for (const SensorInfo& sensor : sensors) {
+        activate(sensor.sensorHandle, false);
+    }
+    getEnvironment()->unregisterCallback();
+
+    // Check that the correct number of flushes are present for each sensor
+    for (const SensorInfo& sensor : sensors) {
+        SCOPED_TRACE(::testing::Message()
+                     << " handle=0x" << std::hex << std::setw(8) << std::setfill('0')
+                     << sensor.sensorHandle << std::dec << " type=" << static_cast<int>(sensor.type)
+                     << " name=" << sensor.name);
+        ASSERT_EQ(callback.getFlushCount(sensor.sensorHandle), expectedFlushCount);
+    }
+}
+
+TEST_P(SensorsAidlTest, SensorListValid) {
+    std::vector<SensorInfo> sensorInfoList = getSensorsList();
+    std::unordered_map<int32_t, std::vector<std::string>> sensorTypeNameMap;
+    for (size_t i = 0; i < sensorInfoList.size(); ++i) {
+        const SensorInfo& info = sensorInfoList[i];
+        SCOPED_TRACE(::testing::Message()
+                     << i << "/" << sensorInfoList.size() << ": "
+                     << " handle=0x" << std::hex << std::setw(8) << std::setfill('0')
+                     << info.sensorHandle << std::dec << " type=" << static_cast<int>(info.type)
+                     << " name=" << info.name);
+
+        // Test type string non-empty only for private sensor typeinfo.
+        if (info.type >= SensorType::DEVICE_PRIVATE_BASE) {
+            EXPECT_FALSE(info.typeAsString.empty());
+        } else if (!info.typeAsString.empty()) {
+            // Test type string matches framework string if specified for non-private typeinfo.
+            EXPECT_NO_FATAL_FAILURE(assertTypeMatchStringType(info.type, info.typeAsString));
+        }
+
+        // Test if all sensor has name and vendor
+        EXPECT_FALSE(info.name.empty());
+        EXPECT_FALSE(info.vendor.empty());
+
+        // Make sure that sensors of the same type have a unique name.
+        std::vector<std::string>& v = sensorTypeNameMap[static_cast<int32_t>(info.type)];
+        bool isUniqueName = std::find(v.begin(), v.end(), info.name) == v.end();
+        EXPECT_TRUE(isUniqueName) << "Duplicate sensor Name: " << info.name;
+        if (isUniqueName) {
+            v.push_back(info.name);
+        }
+
+        EXPECT_LE(0, info.power);
+        EXPECT_LT(0, info.maxRange);
+
+        // Info type, should have no sensor
+        EXPECT_FALSE(info.type == SensorType::ADDITIONAL_INFO ||
+                     info.type == SensorType::META_DATA);
+
+        EXPECT_GE(info.fifoMaxEventCount, info.fifoReservedEventCount);
+
+        // Test Reporting mode valid
+        EXPECT_NO_FATAL_FAILURE(
+                assertTypeMatchReportMode(info.type, extractReportMode(info.flags)));
+
+        // Test min max are in the right order
+        EXPECT_LE(info.minDelayUs, info.maxDelayUs);
+        // Test min/max delay matches reporting mode
+        EXPECT_NO_FATAL_FAILURE(assertDelayMatchReportMode(info.minDelayUs, info.maxDelayUs,
+                                                           extractReportMode(info.flags)));
+    }
+}
+
+TEST_P(SensorsAidlTest, SetOperationMode) {
+    if (getInjectEventSensors().size() > 0) {
+        ASSERT_TRUE(getSensors()->setOperationMode(ISensors::OperationMode::NORMAL).isOk());
+        ASSERT_TRUE(getSensors()->setOperationMode(ISensors::OperationMode::DATA_INJECTION).isOk());
+        ASSERT_TRUE(getSensors()->setOperationMode(ISensors::OperationMode::NORMAL).isOk());
+    } else {
+        ASSERT_EQ(getSensors()
+                          ->setOperationMode(ISensors::OperationMode::DATA_INJECTION)
+                          .getExceptionCode(),
+                  EX_UNSUPPORTED_OPERATION);
+    }
+}
+
+TEST_P(SensorsAidlTest, InjectSensorEventData) {
+    std::vector<SensorInfo> sensors = getInjectEventSensors();
+    if (sensors.size() == 0) {
+        return;
+    }
+
+    ASSERT_TRUE(getSensors()->setOperationMode(ISensors::OperationMode::DATA_INJECTION).isOk());
+
+    EventCallback callback;
+    getEnvironment()->registerCallback(&callback);
+
+    // AdditionalInfo event should not be sent to Event FMQ
+    Event additionalInfoEvent;
+    additionalInfoEvent.sensorType = SensorType::ADDITIONAL_INFO;
+    additionalInfoEvent.timestamp = android::elapsedRealtimeNano();
+
+    Event injectedEvent;
+    injectedEvent.timestamp = android::elapsedRealtimeNano();
+    Event::EventPayload::Vec3 data = {1, 2, 3, SensorStatus::ACCURACY_HIGH};
+    injectedEvent.payload.set<Event::EventPayload::Tag::vec3>(data);
+
+    for (const auto& s : sensors) {
+        additionalInfoEvent.sensorHandle = s.sensorHandle;
+        ASSERT_TRUE(getSensors()->injectSensorData(additionalInfoEvent).isOk());
+
+        injectedEvent.sensorType = s.type;
+        injectedEvent.sensorHandle = s.sensorHandle;
+        ASSERT_TRUE(getSensors()->injectSensorData(injectedEvent).isOk());
+    }
+
+    // Wait for events to be written back to the Event FMQ
+    callback.waitForEvents(sensors, std::chrono::milliseconds(1000) /* timeout */);
+    getEnvironment()->unregisterCallback();
+
+    for (const auto& s : sensors) {
+        auto events = callback.getEvents(s.sensorHandle);
+        if (events.empty()) {
+            FAIL() << "Received no events";
+        } else {
+            auto lastEvent = events.back();
+            SCOPED_TRACE(::testing::Message()
+                         << " handle=0x" << std::hex << std::setw(8) << std::setfill('0')
+                         << s.sensorHandle << std::dec << " type=" << static_cast<int>(s.type)
+                         << " name=" << s.name);
+
+            // Verify that only a single event has been received
+            ASSERT_EQ(events.size(), 1);
+
+            // Verify that the event received matches the event injected and is not the additional
+            // info event
+            ASSERT_EQ(lastEvent.sensorType, s.type);
+            ASSERT_EQ(lastEvent.timestamp, injectedEvent.timestamp);
+            ASSERT_EQ(lastEvent.payload.get<Event::EventPayload::Tag::vec3>().x,
+                      injectedEvent.payload.get<Event::EventPayload::Tag::vec3>().x);
+            ASSERT_EQ(lastEvent.payload.get<Event::EventPayload::Tag::vec3>().y,
+                      injectedEvent.payload.get<Event::EventPayload::Tag::vec3>().y);
+            ASSERT_EQ(lastEvent.payload.get<Event::EventPayload::Tag::vec3>().z,
+                      injectedEvent.payload.get<Event::EventPayload::Tag::vec3>().z);
+            ASSERT_EQ(lastEvent.payload.get<Event::EventPayload::Tag::vec3>().status,
+                      injectedEvent.payload.get<Event::EventPayload::Tag::vec3>().status);
+        }
+    }
+
+    ASSERT_TRUE(getSensors()->setOperationMode(ISensors::OperationMode::NORMAL).isOk());
+}
+
+TEST_P(SensorsAidlTest, CallInitializeTwice) {
+    // Create a helper class so that a second environment is able to be instantiated
+    class SensorsAidlEnvironmentTest : public SensorsAidlEnvironment {
+      public:
+        SensorsAidlEnvironmentTest(const std::string& service_name)
+            : SensorsAidlEnvironment(service_name) {}
+    };
+
+    if (getSensorsList().size() == 0) {
+        // No sensors
+        return;
+    }
+
+    constexpr useconds_t kCollectionTimeoutUs = 1000 * 1000;  // 1s
+    constexpr int32_t kNumEvents = 1;
+
+    // Create a new environment that calls initialize()
+    std::unique_ptr<SensorsAidlEnvironmentTest> newEnv =
+            std::make_unique<SensorsAidlEnvironmentTest>(GetParam());
+    newEnv->SetUp();
+    if (HasFatalFailure()) {
+        return;  // Exit early if setting up the new environment failed
+    }
+
+    activateAllSensors(true);
+    // Verify that the old environment does not receive any events
+    EXPECT_EQ(getEnvironment()->collectEvents(kCollectionTimeoutUs, kNumEvents).size(), 0);
+    // Verify that the new event queue receives sensor events
+    EXPECT_GE(newEnv.get()->collectEvents(kCollectionTimeoutUs, kNumEvents).size(), kNumEvents);
+    activateAllSensors(false);
+
+    // Cleanup the test environment
+    newEnv->TearDown();
+
+    // Restore the test environment for future tests
+    getEnvironment()->TearDown();
+    getEnvironment()->SetUp();
+    if (HasFatalFailure()) {
+        return;  // Exit early if resetting the environment failed
+    }
+
+    // Ensure that the original environment is receiving events
+    activateAllSensors(true);
+    EXPECT_GE(getEnvironment()->collectEvents(kCollectionTimeoutUs, kNumEvents).size(), kNumEvents);
+    activateAllSensors(false);
+}
+
+TEST_P(SensorsAidlTest, CleanupConnectionsOnInitialize) {
+    activateAllSensors(true);
+
+    // Verify that events are received
+    constexpr useconds_t kCollectionTimeoutUs = 1000 * 1000;  // 1s
+    constexpr int32_t kNumEvents = 1;
+    ASSERT_GE(getEnvironment()->collectEvents(kCollectionTimeoutUs, kNumEvents).size(), kNumEvents);
+
+    // Clear the active sensor handles so they are not disabled during TearDown
+    auto handles = mSensorHandles;
+    mSensorHandles.clear();
+    getEnvironment()->TearDown();
+    getEnvironment()->SetUp();
+    if (HasFatalFailure()) {
+        return;  // Exit early if resetting the environment failed
+    }
+
+    // Verify no events are received until sensors are re-activated
+    ASSERT_EQ(getEnvironment()->collectEvents(kCollectionTimeoutUs, kNumEvents).size(), 0);
+    activateAllSensors(true);
+    ASSERT_GE(getEnvironment()->collectEvents(kCollectionTimeoutUs, kNumEvents).size(), kNumEvents);
+
+    // Disable sensors
+    activateAllSensors(false);
+
+    // Restore active sensors prior to clearing the environment
+    mSensorHandles = handles;
+}
+
+TEST_P(SensorsAidlTest, FlushSensor) {
+    std::vector<SensorInfo> sensors = getNonOneShotSensors();
+    if (sensors.size() == 0) {
+        return;
+    }
+
+    constexpr int32_t kFlushes = 5;
+    runSingleFlushTest(sensors, true /* activateSensor */, 1 /* expectedFlushCount */,
+                       true /* expectedResult */);
+    runFlushTest(sensors, true /* activateSensor */, kFlushes, kFlushes, true /* expectedResult */);
+}
+
+TEST_P(SensorsAidlTest, FlushOneShotSensor) {
+    // Find a sensor that is a one-shot sensor
+    std::vector<SensorInfo> sensors = getOneShotSensors();
+    if (sensors.size() == 0) {
+        return;
+    }
+
+    runSingleFlushTest(sensors, true /* activateSensor */, 0 /* expectedFlushCount */,
+                       false /* expectedResult */);
+}
+
+TEST_P(SensorsAidlTest, FlushInactiveSensor) {
+    // Attempt to find a non-one shot sensor, then a one-shot sensor if necessary
+    std::vector<SensorInfo> sensors = getNonOneShotSensors();
+    if (sensors.size() == 0) {
+        sensors = getOneShotSensors();
+        if (sensors.size() == 0) {
+            return;
+        }
+    }
+
+    runSingleFlushTest(sensors, false /* activateSensor */, 0 /* expectedFlushCount */,
+                       false /* expectedResult */);
+}
+
+TEST_P(SensorsAidlTest, Batch) {
+    if (getSensorsList().size() == 0) {
+        return;
+    }
+
+    activateAllSensors(false /* enable */);
+    for (const SensorInfo& sensor : getSensorsList()) {
+        SCOPED_TRACE(::testing::Message()
+                     << " handle=0x" << std::hex << std::setw(8) << std::setfill('0')
+                     << sensor.sensorHandle << std::dec << " type=" << static_cast<int>(sensor.type)
+                     << " name=" << sensor.name);
+
+        // Call batch on inactive sensor
+        // One shot sensors have minDelay set to -1 which is an invalid
+        // parameter. Use 0 instead to avoid errors.
+        int64_t samplingPeriodNs =
+                extractReportMode(sensor.flags) == SensorInfo::SENSOR_FLAG_BITS_ONE_SHOT_MODE
+                        ? 0
+                        : sensor.minDelayUs;
+        checkIsOk(batch(sensor.sensorHandle, samplingPeriodNs, 0 /* maxReportLatencyNs */));
+
+        // Activate the sensor
+        activate(sensor.sensorHandle, true /* enabled */);
+
+        // Call batch on an active sensor
+        checkIsOk(batch(sensor.sensorHandle, sensor.maxDelayUs, 0 /* maxReportLatencyNs */));
+    }
+    activateAllSensors(false /* enable */);
+
+    // Call batch on an invalid sensor
+    SensorInfo sensor = getSensorsList().front();
+    sensor.sensorHandle = getInvalidSensorHandle();
+    ASSERT_EQ(batch(sensor.sensorHandle, sensor.minDelayUs, 0 /* maxReportLatencyNs */)
+                      .getExceptionCode(),
+              EX_ILLEGAL_ARGUMENT);
+}
+
+TEST_P(SensorsAidlTest, Activate) {
+    if (getSensorsList().size() == 0) {
+        return;
+    }
+
+    // Verify that sensor events are generated when activate is called
+    for (const SensorInfo& sensor : getSensorsList()) {
+        SCOPED_TRACE(::testing::Message()
+                     << " handle=0x" << std::hex << std::setw(8) << std::setfill('0')
+                     << sensor.sensorHandle << std::dec << " type=" << static_cast<int>(sensor.type)
+                     << " name=" << sensor.name);
+
+        checkIsOk(batch(sensor.sensorHandle, sensor.minDelayUs, 0 /* maxReportLatencyNs */));
+        checkIsOk(activate(sensor.sensorHandle, true));
+
+        // Call activate on a sensor that is already activated
+        checkIsOk(activate(sensor.sensorHandle, true));
+
+        // Deactivate the sensor
+        checkIsOk(activate(sensor.sensorHandle, false));
+
+        // Call deactivate on a sensor that is already deactivated
+        checkIsOk(activate(sensor.sensorHandle, false));
+    }
+
+    // Attempt to activate an invalid sensor
+    int32_t invalidHandle = getInvalidSensorHandle();
+    ASSERT_EQ(activate(invalidHandle, true).getExceptionCode(), EX_ILLEGAL_ARGUMENT);
+    ASSERT_EQ(activate(invalidHandle, false).getExceptionCode(), EX_ILLEGAL_ARGUMENT);
+}
+
+TEST_P(SensorsAidlTest, NoStaleEvents) {
+    constexpr std::chrono::milliseconds kFiveHundredMs(500);
+    constexpr std::chrono::milliseconds kOneSecond(1000);
+
+    // Register the callback to receive sensor events
+    EventCallback callback;
+    getEnvironment()->registerCallback(&callback);
+
+    // This test is not valid for one-shot, on-change or special-report-mode sensors
+    const std::vector<SensorInfo> sensors = getNonOneShotAndNonOnChangeAndNonSpecialSensors();
+    std::chrono::milliseconds maxMinDelay(0);
+    for (const SensorInfo& sensor : sensors) {
+        std::chrono::milliseconds minDelay = duration_cast<std::chrono::milliseconds>(
+                std::chrono::microseconds(sensor.minDelayUs));
+        maxMinDelay = std::chrono::milliseconds(std::max(maxMinDelay.count(), minDelay.count()));
+    }
+
+    // Activate the sensors so that they start generating events
+    activateAllSensors(true);
+
+    // According to the CDD, the first sample must be generated within 400ms + 2 * sample_time
+    // and the maximum reporting latency is 100ms + 2 * sample_time. Wait a sufficient amount
+    // of time to guarantee that a sample has arrived.
+    callback.waitForEvents(sensors, kFiveHundredMs + (5 * maxMinDelay));
+    activateAllSensors(false);
+
+    // Save the last received event for each sensor
+    std::map<int32_t, int64_t> lastEventTimestampMap;
+    for (const SensorInfo& sensor : sensors) {
+        SCOPED_TRACE(::testing::Message()
+                     << " handle=0x" << std::hex << std::setw(8) << std::setfill('0')
+                     << sensor.sensorHandle << std::dec << " type=" << static_cast<int>(sensor.type)
+                     << " name=" << sensor.name);
+
+        if (callback.getEvents(sensor.sensorHandle).size() >= 1) {
+            lastEventTimestampMap[sensor.sensorHandle] =
+                    callback.getEvents(sensor.sensorHandle).back().timestamp;
+        }
+    }
+
+    // Allow some time to pass, reset the callback, then reactivate the sensors
+    usleep(duration_cast<std::chrono::microseconds>(kOneSecond + (5 * maxMinDelay)).count());
+    callback.reset();
+    activateAllSensors(true);
+    callback.waitForEvents(sensors, kFiveHundredMs + (5 * maxMinDelay));
+    activateAllSensors(false);
+
+    getEnvironment()->unregisterCallback();
+
+    for (const SensorInfo& sensor : sensors) {
+        SCOPED_TRACE(::testing::Message()
+                     << " handle=0x" << std::hex << std::setw(8) << std::setfill('0')
+                     << sensor.sensorHandle << std::dec << " type=" << static_cast<int>(sensor.type)
+                     << " name=" << sensor.name);
+
+        // Skip sensors that did not previously report an event
+        if (lastEventTimestampMap.find(sensor.sensorHandle) == lastEventTimestampMap.end()) {
+            continue;
+        }
+
+        // Ensure that the first event received is not stale by ensuring that its timestamp is
+        // sufficiently different from the previous event
+        const Event newEvent = callback.getEvents(sensor.sensorHandle).front();
+        std::chrono::milliseconds delta =
+                duration_cast<std::chrono::milliseconds>(std::chrono::nanoseconds(
+                        newEvent.timestamp - lastEventTimestampMap[sensor.sensorHandle]));
+        std::chrono::milliseconds sensorMinDelay = duration_cast<std::chrono::milliseconds>(
+                std::chrono::microseconds(sensor.minDelayUs));
+        ASSERT_GE(delta, kFiveHundredMs + (3 * sensorMinDelay));
+    }
+}
+
+void SensorsAidlTest::checkRateLevel(const SensorInfo& sensor, int32_t directChannelHandle,
+                                     ISensors::RateLevel rateLevel, int32_t* reportToken) {
+    ndk::ScopedAStatus status =
+            configDirectReport(sensor.sensorHandle, directChannelHandle, rateLevel, reportToken);
+
+    SCOPED_TRACE(::testing::Message()
+                 << " handle=0x" << std::hex << std::setw(8) << std::setfill('0')
+                 << sensor.sensorHandle << std::dec << " type=" << static_cast<int>(sensor.type)
+                 << " name=" << sensor.name);
+
+    if (isDirectReportRateSupported(sensor, rateLevel)) {
+        ASSERT_TRUE(status.isOk());
+        if (rateLevel != ISensors::RateLevel::STOP) {
+            ASSERT_GT(*reportToken, 0);
+        } else {
+            ASSERT_EQ(status.getExceptionCode(), EX_ILLEGAL_ARGUMENT);
+        }
+    }
+}
+
+void SensorsAidlTest::queryDirectChannelSupport(ISensors::SharedMemInfo::SharedMemType memType,
+                                                bool* supportsSharedMemType,
+                                                bool* supportsAnyDirectChannel) {
+    *supportsSharedMemType = false;
+    *supportsAnyDirectChannel = false;
+    for (const SensorInfo& curSensor : getSensorsList()) {
+        if (isDirectChannelTypeSupported(curSensor, memType)) {
+            *supportsSharedMemType = true;
+        }
+        if (isDirectChannelTypeSupported(curSensor,
+                                         ISensors::SharedMemInfo::SharedMemType::ASHMEM) ||
+            isDirectChannelTypeSupported(curSensor,
+                                         ISensors::SharedMemInfo::SharedMemType::GRALLOC)) {
+            *supportsAnyDirectChannel = true;
+        }
+
+        if (*supportsSharedMemType && *supportsAnyDirectChannel) {
+            break;
+        }
+    }
+}
+
+void SensorsAidlTest::verifyRegisterDirectChannel(
+        std::shared_ptr<SensorsAidlTestSharedMemory<SensorType, Event>> mem,
+        int32_t* directChannelHandle, bool supportsSharedMemType, bool supportsAnyDirectChannel) {
+    char* buffer = mem->getBuffer();
+    size_t size = mem->getSize();
+
+    if (supportsSharedMemType) {
+        memset(buffer, 0xff, size);
+    }
+
+    int32_t channelHandle;
+
+    ::ndk::ScopedAStatus status = registerDirectChannel(mem->getSharedMemInfo(), &channelHandle);
+    if (supportsSharedMemType) {
+        ASSERT_TRUE(status.isOk());
+        ASSERT_EQ(channelHandle, 0);
+    } else {
+        int32_t error = supportsAnyDirectChannel ? EX_ILLEGAL_ARGUMENT : EX_UNSUPPORTED_OPERATION;
+        ASSERT_EQ(status.getExceptionCode(), error);
+        ASSERT_EQ(channelHandle, -1);
+    }
+    directChannelHandle = &channelHandle;
+}
+
+void SensorsAidlTest::verifyUnregisterDirectChannel(int32_t* channelHandle,
+                                                    bool supportsAnyDirectChannel) {
+    int result = supportsAnyDirectChannel ? EX_NONE : EX_UNSUPPORTED_OPERATION;
+    ndk::ScopedAStatus status = unregisterDirectChannel(channelHandle);
+    ASSERT_EQ(status.getExceptionCode(), result);
+}
+
+void SensorsAidlTest::verifyDirectChannel(ISensors::SharedMemInfo::SharedMemType memType) {
+    constexpr size_t kNumEvents = 1;
+    constexpr size_t kMemSize = kNumEvents * kEventSize;
+
+    std::shared_ptr<SensorsAidlTestSharedMemory<SensorType, Event>> mem(
+            SensorsAidlTestSharedMemory<SensorType, Event>::create(memType, kMemSize));
+    ASSERT_NE(mem, nullptr);
+
+    bool supportsSharedMemType;
+    bool supportsAnyDirectChannel;
+    queryDirectChannelSupport(memType, &supportsSharedMemType, &supportsAnyDirectChannel);
+
+    for (const SensorInfo& sensor : getSensorsList()) {
+        int32_t directChannelHandle = 0;
+        verifyRegisterDirectChannel(mem, &directChannelHandle, supportsSharedMemType,
+                                    supportsAnyDirectChannel);
+        verifyConfigure(sensor, memType, directChannelHandle, supportsAnyDirectChannel);
+        verifyUnregisterDirectChannel(&directChannelHandle, supportsAnyDirectChannel);
+    }
+}
+
+void SensorsAidlTest::verifyConfigure(const SensorInfo& sensor,
+                                      ISensors::SharedMemInfo::SharedMemType memType,
+                                      int32_t directChannelHandle, bool supportsAnyDirectChannel) {
+    SCOPED_TRACE(::testing::Message()
+                 << " handle=0x" << std::hex << std::setw(8) << std::setfill('0')
+                 << sensor.sensorHandle << std::dec << " type=" << static_cast<int>(sensor.type)
+                 << " name=" << sensor.name);
+
+    int32_t reportToken = 0;
+    if (isDirectChannelTypeSupported(sensor, memType)) {
+        // Verify that each rate level is properly supported
+        checkRateLevel(sensor, directChannelHandle, ISensors::RateLevel::NORMAL, &reportToken);
+        checkRateLevel(sensor, directChannelHandle, ISensors::RateLevel::FAST, &reportToken);
+        checkRateLevel(sensor, directChannelHandle, ISensors::RateLevel::VERY_FAST, &reportToken);
+        checkRateLevel(sensor, directChannelHandle, ISensors::RateLevel::STOP, &reportToken);
+
+        // Verify that a sensor handle of -1 is only acceptable when using RateLevel::STOP
+        ndk::ScopedAStatus status = configDirectReport(-1 /* sensorHandle */, directChannelHandle,
+                                                       ISensors::RateLevel::NORMAL, &reportToken);
+        ASSERT_EQ(status.getServiceSpecificError(), android::BAD_VALUE);
+
+        status = configDirectReport(-1 /* sensorHandle */, directChannelHandle,
+                                    ISensors::RateLevel::STOP, &reportToken);
+        ASSERT_TRUE(status.isOk());
+    } else {
+        // directChannelHandle will be -1 here, HAL should either reject it as a bad value if there
+        // is some level of direct channel report, otherwise return INVALID_OPERATION if direct
+        // channel is not supported at all
+        int error = supportsAnyDirectChannel ? EX_ILLEGAL_ARGUMENT : EX_UNSUPPORTED_OPERATION;
+        ndk::ScopedAStatus status = configDirectReport(sensor.sensorHandle, directChannelHandle,
+                                                       ISensors::RateLevel::NORMAL, &reportToken);
+        ASSERT_EQ(status.getExceptionCode(), error);
+    }
+}
+
+TEST_P(SensorsAidlTest, DirectChannelAshmem) {
+    verifyDirectChannel(ISensors::SharedMemInfo::SharedMemType::ASHMEM);
+}
+
+TEST_P(SensorsAidlTest, DirectChannelGralloc) {
+    verifyDirectChannel(ISensors::SharedMemInfo::SharedMemType::GRALLOC);
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SensorsAidlTest);
+INSTANTIATE_TEST_SUITE_P(Sensors, SensorsAidlTest,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(ISensors::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/tv/tuner/1.0/vts/functional/FrontendTests.cpp b/tv/tuner/1.0/vts/functional/FrontendTests.cpp
old mode 100644
new mode 100755
index 4a642a0..acc524b
--- a/tv/tuner/1.0/vts/functional/FrontendTests.cpp
+++ b/tv/tuner/1.0/vts/functional/FrontendTests.cpp
@@ -377,6 +377,7 @@
         result &= getDvrTests()->getDvrPlaybackMQDescriptor() == success();
         getDvrTests()->startPlaybackInputThread(mDvrConfig.playbackInputFile,
                                                 mDvrConfig.settings.playback());
+        getDvrTests()->startDvrPlayback();
         if (!result) {
             ALOGW("[vts] Software frontend dvr configure failed.");
             return failure();
@@ -400,6 +401,7 @@
     status = mFrontend->stopTune();
     if (mIsSoftwareFe && testWithDemux) {
         getDvrTests()->stopPlaybackThread();
+        getDvrTests()->stopDvrPlayback();
         getDvrTests()->closeDvrPlayback();
     }
     return AssertionResult(status == Result::SUCCESS);
diff --git a/tv/tuner/1.1/default/Frontend.cpp b/tv/tuner/1.1/default/Frontend.cpp
index f5463a9..919c956 100644
--- a/tv/tuner/1.1/default/Frontend.cpp
+++ b/tv/tuner/1.1/default/Frontend.cpp
@@ -88,46 +88,60 @@
 
 Return<Result> Frontend::scan(const FrontendSettings& settings, FrontendScanType type) {
     ALOGV("%s", __FUNCTION__);
+
+    // If it's in middle of scanning, stop it first.
+    if (mScanThread.joinable()) {
+        mScanThread.join();
+    }
+
+    mFrontendSettings = settings;
+    mFrontendScanType = type;
+    mScanThread = std::thread(&Frontend::scanThreadLoop, this);
+
+    return Result::SUCCESS;
+}
+
+void Frontend::scanThreadLoop() {
     FrontendScanMessage msg;
 
     if (mIsLocked) {
         msg.isEnd(true);
         mCallback->onScanMessage(FrontendScanMessageType::END, msg);
-        return Result::SUCCESS;
+        return;
     }
 
     uint32_t frequency;
-    switch (settings.getDiscriminator()) {
+    switch (mFrontendSettings.getDiscriminator()) {
         case FrontendSettings::hidl_discriminator::analog:
-            frequency = settings.analog().frequency;
+            frequency = mFrontendSettings.analog().frequency;
             break;
         case FrontendSettings::hidl_discriminator::atsc:
-            frequency = settings.atsc().frequency;
+            frequency = mFrontendSettings.atsc().frequency;
             break;
         case FrontendSettings::hidl_discriminator::atsc3:
-            frequency = settings.atsc3().frequency;
+            frequency = mFrontendSettings.atsc3().frequency;
             break;
         case FrontendSettings::hidl_discriminator::dvbs:
-            frequency = settings.dvbs().frequency;
+            frequency = mFrontendSettings.dvbs().frequency;
             break;
         case FrontendSettings::hidl_discriminator::dvbc:
-            frequency = settings.dvbc().frequency;
+            frequency = mFrontendSettings.dvbc().frequency;
             break;
         case FrontendSettings::hidl_discriminator::dvbt:
-            frequency = settings.dvbt().frequency;
+            frequency = mFrontendSettings.dvbt().frequency;
             break;
         case FrontendSettings::hidl_discriminator::isdbs:
-            frequency = settings.isdbs().frequency;
+            frequency = mFrontendSettings.isdbs().frequency;
             break;
         case FrontendSettings::hidl_discriminator::isdbs3:
-            frequency = settings.isdbs3().frequency;
+            frequency = mFrontendSettings.isdbs3().frequency;
             break;
         case FrontendSettings::hidl_discriminator::isdbt:
-            frequency = settings.isdbt().frequency;
+            frequency = mFrontendSettings.isdbt().frequency;
             break;
     }
 
-    if (type == FrontendScanType::SCAN_BLIND) {
+    if (mFrontendScanType == FrontendScanType::SCAN_BLIND) {
         frequency += 100 * 1000;
     }
 
@@ -204,8 +218,6 @@
     msg.isLocked(true);
     mCallback->onScanMessage(FrontendScanMessageType::LOCKED, msg);
     mIsLocked = true;
-
-    return Result::SUCCESS;
 }
 
 Return<Result> Frontend::scan_1_1(const FrontendSettings& settings, FrontendScanType type,
@@ -218,6 +230,10 @@
 Return<Result> Frontend::stopScan() {
     ALOGV("%s", __FUNCTION__);
 
+    if (mScanThread.joinable()) {
+        mScanThread.join();
+    }
+
     mIsLocked = false;
     return Result::SUCCESS;
 }
diff --git a/tv/tuner/1.1/default/Frontend.h b/tv/tuner/1.1/default/Frontend.h
index a28fb64..bf739a8 100644
--- a/tv/tuner/1.1/default/Frontend.h
+++ b/tv/tuner/1.1/default/Frontend.h
@@ -20,6 +20,7 @@
 #include <android/hardware/tv/tuner/1.1/IFrontend.h>
 #include <fstream>
 #include <iostream>
+#include <thread>
 #include "Tuner.h"
 
 using namespace std;
@@ -81,13 +82,17 @@
   private:
     virtual ~Frontend();
     bool supportsSatellite();
+    void scanThreadLoop();
+
     sp<IFrontendCallback> mCallback;
     sp<Tuner> mTunerService;
     FrontendType mType = FrontendType::UNDEFINED;
     FrontendId mId = 0;
     bool mIsLocked = false;
     uint32_t mCiCamId;
-
+    std::thread mScanThread;
+    FrontendSettings mFrontendSettings;
+    FrontendScanType mFrontendScanType;
     std::ifstream mFrontendData;
 };
 
diff --git a/tv/tuner/1.1/vts/functional/FrontendTests.cpp b/tv/tuner/1.1/vts/functional/FrontendTests.cpp
index a595a93..9f0f30d 100644
--- a/tv/tuner/1.1/vts/functional/FrontendTests.cpp
+++ b/tv/tuner/1.1/vts/functional/FrontendTests.cpp
@@ -444,6 +444,7 @@
         result &= getDvrTests()->getDvrPlaybackMQDescriptor() == success();
         getDvrTests()->startPlaybackInputThread(mDvrConfig.playbackInputFile,
                                                 mDvrConfig.settings.playback());
+        getDvrTests()->startDvrPlayback();
         if (!result) {
             ALOGW("[vts] Software frontend dvr configure failed.");
             return failure();
@@ -459,6 +460,7 @@
     status = mFrontend->stopTune();
     if (mIsSoftwareFe && testWithDemux) {
         getDvrTests()->stopPlaybackThread();
+        getDvrTests()->stopDvrPlayback();
         getDvrTests()->closeDvrPlayback();
     }
     return AssertionResult(status == Result::SUCCESS);
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/AudioStreamType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/AudioStreamType.aidl
index bfd2aa8..6c538ea 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/AudioStreamType.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/AudioStreamType.aidl
@@ -51,4 +51,8 @@
   OPUS = 13,
   VORBIS = 14,
   DRA = 15,
+  AAC_ADTS = 16,
+  AAC_LATM = 17,
+  AAC_HE_ADTS = 18,
+  AAC_HE_LATM = 19,
 }
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..61a9555 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;
@@ -46,4 +48,5 @@
   int mpuSequenceNumber;
   boolean isPesPrivateData;
   android.hardware.tv.tuner.DemuxFilterMediaEventExtraMetaData extraMetaData;
+  android.hardware.tv.tuner.DemuxFilterScIndexMask scIndexMask;
 }
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/DemuxFilterSectionSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterSectionSettings.aidl
index 2858565..7936e59 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterSectionSettings.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterSectionSettings.aidl
@@ -39,4 +39,5 @@
   boolean isCheckCrc;
   boolean isRepeat;
   boolean isRaw;
+  int bitWidthOfLengthField;
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendScanMessage.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendScanMessage.aidl
index 2c6cc00..e763cfb 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendScanMessage.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendScanMessage.aidl
@@ -50,4 +50,5 @@
   android.hardware.tv.tuner.FrontendModulation modulation;
   android.hardware.tv.tuner.FrontendDvbcAnnex annex;
   boolean isHighPriority;
+  int[] dvbtCellIds;
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendScanMessageType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendScanMessageType.aidl
index b121c85..6976ecd 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendScanMessageType.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendScanMessageType.aidl
@@ -50,4 +50,5 @@
   MODULATION = 12,
   DVBC_ANNEX = 13,
   HIGH_PRIORITY = 14,
+  DVBT_CELL_IDS = 15,
 }
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..fc0efc9 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,6 @@
   boolean isShortFrames;
   android.hardware.tv.tuner.FrontendIsdbtMode isdbtMode;
   android.hardware.tv.tuner.FrontendIsdbtPartialReceptionFlag partialReceptionFlag;
+  int[] streamIdList;
+  int[] dvbtCellIds;
 }
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..2cc62d5 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,6 @@
   IS_SHORT_FRAMES = 36,
   ISDBT_MODE = 37,
   ISDBT_PARTIAL_RECEPTION_FLAG = 38,
+  STREAM_ID_LIST = 39,
+  DVBT_CELL_IDS = 40,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/IFrontend.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/IFrontend.aidl
index ed5b0c0..e7aa070 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/IFrontend.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/IFrontend.aidl
@@ -43,7 +43,7 @@
   void stopScan();
   android.hardware.tv.tuner.FrontendStatus[] getStatus(in android.hardware.tv.tuner.FrontendStatusType[] statusTypes);
   void setLnb(in int lnbId);
-  void setLna(in boolean bEnable);
   int linkCiCam(in int ciCamId);
   void unlinkCiCam(in int ciCamId);
+  String getHardwareInfo();
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/ITuner.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/ITuner.aidl
index 0e903d8..0ff2da9 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/ITuner.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/ITuner.aidl
@@ -44,4 +44,7 @@
   int[] getLnbIds();
   android.hardware.tv.tuner.ILnb openLnbById(in int lnbId);
   android.hardware.tv.tuner.ILnb openLnbByName(in String lnbName, out int[] lnbId);
+  void setLna(in boolean bEnable);
+  void setMaxNumberOfFrontends(in android.hardware.tv.tuner.FrontendType frontendType, in int maxNumber);
+  int getMaxNumberOfFrontends(in android.hardware.tv.tuner.FrontendType frontendType);
 }
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/AudioStreamType.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/AudioStreamType.aidl
index 1bb5c68f..9e9a8cf 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/AudioStreamType.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/AudioStreamType.aidl
@@ -99,4 +99,24 @@
      * SJ/T 11368-2006
      */
     DRA,
+
+    /*
+     * AAC with ADTS (Audio Data Transport Format).
+     */
+    AAC_ADTS,
+
+    /*
+     * AAC with ADTS with LATM (Low-overhead MPEG-4 Audio Transport Multiplex).
+     */
+    AAC_LATM,
+
+    /*
+     * High-Efficiency AAC (HE-AAC) with ADTS (Audio Data Transport Format).
+     */
+    AAC_HE_ADTS,
+
+    /*
+     * High-Efficiency AAC (HE-AAC) with LATM (Low-overhead MPEG-4 Audio Transport Multiplex).
+     */
+    AAC_HE_LATM,
 }
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..32f0cb2 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterMediaEvent.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterMediaEvent.aidl
@@ -19,6 +19,7 @@
 import android.hardware.common.NativeHandle;
 
 import android.hardware.tv.tuner.DemuxFilterMediaEventExtraMetaData;
+import android.hardware.tv.tuner.DemuxFilterScIndexMask;
 
 /**
  * Filter Event for Audio or Video Filter.
@@ -40,6 +41,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;
@@ -74,4 +85,10 @@
     boolean isPesPrivateData;
 
     DemuxFilterMediaEventExtraMetaData extraMetaData;
+
+    /**
+     * DemuxFilterScIndexMask for the key frame info. It's optional to hardware which can only
+     * access unit framing at decode stage.
+     */
+    DemuxFilterScIndexMask scIndexMask;
 }
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/DemuxFilterSectionSettings.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterSectionSettings.aidl
index 2102aa0..aa30175 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterSectionSettings.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterSectionSettings.aidl
@@ -19,7 +19,7 @@
 import android.hardware.tv.tuner.DemuxFilterSectionSettingsCondition;
 
 /**
- * Filter Settings for Section data according to ISO/IEC 13818-1.
+ * Filter Settings for Section data according to ISO/IEC 13818-1 and ISO/IEC 23008-1.
  * @hide
  */
 @VintfStability
@@ -32,7 +32,16 @@
     boolean isCheckCrc;
 
     /**
-     * true if the filter repeats the data with the same version
+     * true if the filter repeats the data.
+     *
+     * If false, for DemuxFilterSectionSettingsConditionTableInfo, HAL filters out all sections
+     * based on tableId and version, and stops filtering data. For DemuxFilterSectionBits, HAL
+     * filters out first section which matches the DemuxFilterSectionBits configuration, and stops
+     * filtering data.
+     *
+     * If true, for DemuxFilterSectionSettingsConditionTableInfo, HAL filters out all sections based
+     * on tableId and version, and repeats. For DemuxFilterSectionBits, HAL filters out sections
+     * which match the DemuxFilterSectionBits configuration, and repeats.
      */
     boolean isRepeat;
 
@@ -40,4 +49,12 @@
      * true if the filter send onFilterStatus instead of onFilterEvent.
      */
     boolean isRaw;
+
+    /**
+     * The bit width of the MMTP (MPEG Media Transport Protocol) section message's length field
+     * according to ISO/IEC 23008-1.
+     *
+     * The filter uses this for CRC checking when isCheckCrc is true.
+     */
+    int bitWidthOfLengthField;
 }
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/FrontendScanMessage.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendScanMessage.aidl
index 19c6766..a941066 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendScanMessage.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendScanMessage.aidl
@@ -70,4 +70,10 @@
     FrontendDvbcAnnex annex;
 
     boolean isHighPriority;
+
+    /**
+     * DVB-T Cell Ids.
+     */
+    int[] dvbtCellIds;
+
 }
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendScanMessageType.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendScanMessageType.aidl
index 2b91216..f4d2ee0 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendScanMessageType.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendScanMessageType.aidl
@@ -86,4 +86,10 @@
     DVBC_ANNEX,
 
     HIGH_PRIORITY,
+
+    /**
+     * DVB-T CELL ID.
+     */
+    DVBT_CELL_IDS,
+
 }
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatus.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatus.aidl
index 9302b76..ae6e46f 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,16 @@
      * ISDB-T Partial Reception Flag.
      */
     FrontendIsdbtPartialReceptionFlag partialReceptionFlag;
+
+    /**
+     * Stream ID list included in a transponder.
+     */
+    int[] streamIdList;
+
+    /**
+     * DVB-T Cell Id.
+     */
+    int[] dvbtCellIds;
+
+
 }
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatusType.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatusType.aidl
index 103a4ab..e7da517 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatusType.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatusType.aidl
@@ -218,4 +218,14 @@
      * ISDB-T Partial Reception Flag.
      */
     ISDBT_PARTIAL_RECEPTION_FLAG,
+
+    /**
+     * Stream ID list included in a transponder.
+     */
+   STREAM_ID_LIST,
+
+   /**
+    * DVB-T Cell Id.
+    */
+   DVBT_CELL_IDS,
 }
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/IFrontend.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/IFrontend.aidl
index b2717db..5b3ce39 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/IFrontend.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/IFrontend.aidl
@@ -117,13 +117,6 @@
     void setLnb(in int lnbId);
 
     /**
-     * Enable or Disable Low Noise Amplifier (LNA).
-     *
-     * @param bEnable true if activate LNA module; false if deactivate LNA
-     */
-    void setLna(in boolean bEnable);
-
-    /**
      * Link Conditional Access Modules (CAM) to Frontend support Common
      * Interface (CI) bypass mode.
      *
@@ -143,4 +136,14 @@
      * @param ciCamId specify CI-CAM Id to unlink.
      */
     void unlinkCiCam(in int ciCamId);
+
+    /**
+     * Request Hardware information about the frontend.
+     *
+     * The client may use this to collect vendor specific hardware information, e.g. RF
+     * chip version, Demod chip version, detailed status of dvbs blind scan, etc.
+     *
+     * @return the frontend hardware information.
+     */
+    String getHardwareInfo();
 }
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/ITuner.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/ITuner.aidl
index ab8b0b8..03def33 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/ITuner.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/ITuner.aidl
@@ -18,6 +18,7 @@
 
 import android.hardware.tv.tuner.DemuxCapabilities;
 import android.hardware.tv.tuner.FrontendInfo;
+import android.hardware.tv.tuner.FrontendType;
 import android.hardware.tv.tuner.IDemux;
 import android.hardware.tv.tuner.IDescrambler;
 import android.hardware.tv.tuner.IFrontend;
@@ -120,4 +121,31 @@
      * @return the newly opened Lnb iterface.
      */
     ILnb openLnbByName(in String lnbName, out int[] lnbId);
+
+    /**
+     * Enable or Disable Low Noise Amplifier (LNA).
+     *
+     * @param bEnable true if activate LNA module; false if deactivate LNA
+     */
+    void setLna(in boolean bEnable);
+
+    /**
+     * Set the maximum usable frontends number of a given frontend type.
+     *
+     * It is used by the client to enable or disable frontends when cable connection status
+     * is changed by user.
+     *
+     * @param frontendType the frontend type which the maximum usable number will be set.
+     * @param maxNumber the new maximum usable number.
+     */
+    void setMaxNumberOfFrontends(in FrontendType frontendType, in int maxNumber);
+
+    /**
+     * Get the maximum usable frontends number of a given frontend type.
+     *
+     * @param frontendType the frontend type which the maximum usable number will be queried.
+     *
+     * @return the maximum usable number of the queried frontend type.
+     */
+    int getMaxNumberOfFrontends(in FrontendType frontendType);
 }
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..714612d 100644
--- a/tv/tuner/aidl/default/Frontend.cpp
+++ b/tv/tuner/aidl/default/Frontend.cpp
@@ -87,47 +87,60 @@
 ::ndk::ScopedAStatus Frontend::scan(const FrontendSettings& in_settings, FrontendScanType in_type) {
     ALOGV("%s", __FUNCTION__);
 
+    // If it's in middle of scanning, stop it first.
+    if (mScanThread.joinable()) {
+        mScanThread.join();
+    }
+
+    mFrontendSettings = in_settings;
+    mFrontendScanType = in_type;
+    mScanThread = std::thread(&Frontend::scanThreadLoop, this);
+
+    return ::ndk::ScopedAStatus::ok();
+}
+
+void Frontend::scanThreadLoop() {
     if (mIsLocked) {
         FrontendScanMessage msg;
         msg.set<FrontendScanMessage::Tag::isEnd>(true);
         mCallback->onScanMessage(FrontendScanMessageType::END, msg);
-        return ::ndk::ScopedAStatus::ok();
+        return;
     }
 
     int64_t frequency = 0;
-    switch (in_settings.getTag()) {
+    switch (mFrontendSettings.getTag()) {
         case FrontendSettings::Tag::analog:
-            frequency = in_settings.get<FrontendSettings::Tag::analog>().frequency;
+            frequency = mFrontendSettings.get<FrontendSettings::Tag::analog>().frequency;
             break;
         case FrontendSettings::Tag::atsc:
-            frequency = in_settings.get<FrontendSettings::Tag::atsc>().frequency;
+            frequency = mFrontendSettings.get<FrontendSettings::Tag::atsc>().frequency;
             break;
         case FrontendSettings::Tag::atsc3:
-            frequency = in_settings.get<FrontendSettings::Tag::atsc3>().frequency;
+            frequency = mFrontendSettings.get<FrontendSettings::Tag::atsc3>().frequency;
             break;
         case FrontendSettings::Tag::dvbs:
-            frequency = in_settings.get<FrontendSettings::Tag::dvbs>().frequency;
+            frequency = mFrontendSettings.get<FrontendSettings::Tag::dvbs>().frequency;
             break;
         case FrontendSettings::Tag::dvbc:
-            frequency = in_settings.get<FrontendSettings::Tag::dvbc>().frequency;
+            frequency = mFrontendSettings.get<FrontendSettings::Tag::dvbc>().frequency;
             break;
         case FrontendSettings::Tag::dvbt:
-            frequency = in_settings.get<FrontendSettings::Tag::dvbt>().frequency;
+            frequency = mFrontendSettings.get<FrontendSettings::Tag::dvbt>().frequency;
             break;
         case FrontendSettings::Tag::isdbs:
-            frequency = in_settings.get<FrontendSettings::Tag::isdbs>().frequency;
+            frequency = mFrontendSettings.get<FrontendSettings::Tag::isdbs>().frequency;
             break;
         case FrontendSettings::Tag::isdbs3:
-            frequency = in_settings.get<FrontendSettings::Tag::isdbs3>().frequency;
+            frequency = mFrontendSettings.get<FrontendSettings::Tag::isdbs3>().frequency;
             break;
         case FrontendSettings::Tag::isdbt:
-            frequency = in_settings.get<FrontendSettings::Tag::isdbt>().frequency;
+            frequency = mFrontendSettings.get<FrontendSettings::Tag::isdbt>().frequency;
             break;
         default:
             break;
     }
 
-    if (in_type == FrontendScanType::SCAN_BLIND) {
+    if (mFrontendScanType == FrontendScanType::SCAN_BLIND) {
         frequency += 100 * 1000;
     }
 
@@ -237,19 +250,28 @@
         mCallback->onScanMessage(FrontendScanMessageType::HIGH_PRIORITY, msg);
     }
 
+    if (mType == FrontendType::DVBT) {
+        FrontendScanMessage msg;
+        vector<int32_t> dvbtCellIds = {0, 1};
+        msg.set<FrontendScanMessage::Tag::dvbtCellIds>(dvbtCellIds);
+        mCallback->onScanMessage(FrontendScanMessageType::DVBT_CELL_IDS, msg);
+    }
+
     {
         FrontendScanMessage msg;
         msg.set<FrontendScanMessage::Tag::isLocked>(true);
         mCallback->onScanMessage(FrontendScanMessageType::LOCKED, msg);
         mIsLocked = true;
     }
-
-    return ::ndk::ScopedAStatus::ok();
 }
 
 ::ndk::ScopedAStatus Frontend::stopScan() {
     ALOGV("%s", __FUNCTION__);
 
+    if (mScanThread.joinable()) {
+        mScanThread.join();
+    }
+
     mIsLocked = false;
     return ::ndk::ScopedAStatus::ok();
 }
@@ -676,6 +698,16 @@
                         FrontendIsdbtPartialReceptionFlag::AUTO);
                 break;
             }
+            case FrontendStatusType::STREAM_ID_LIST: {
+                vector<int32_t> streamIds = {0, 1};
+                status.set<FrontendStatus::streamIdList>(streamIds);
+                break;
+            }
+            case FrontendStatusType::DVBT_CELL_IDS: {
+                vector<int32_t> dvbtCellIds = {0, 1};
+                status.set<FrontendStatus::dvbtCellIds>(dvbtCellIds);
+                break;
+            }
             default: {
                 continue;
             }
@@ -686,12 +718,6 @@
     return ::ndk::ScopedAStatus::ok();
 }
 
-::ndk::ScopedAStatus Frontend::setLna(bool /* in_bEnable */) {
-    ALOGV("%s", __FUNCTION__);
-
-    return ::ndk::ScopedAStatus::ok();
-}
-
 ::ndk::ScopedAStatus Frontend::setLnb(int32_t /* in_lnbId */) {
     ALOGV("%s", __FUNCTION__);
     if (!supportsSatellite()) {
@@ -718,6 +744,21 @@
     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;
+}
+
+::ndk::ScopedAStatus Frontend::getHardwareInfo(std::string* _aidl_return) {
+    ALOGV("%s", __FUNCTION__);
+
+    *_aidl_return = "Sample Frontend";
+    return ::ndk::ScopedAStatus::ok();
+}
+
 FrontendType Frontend::getFrontendType() {
     return mType;
 }
diff --git a/tv/tuner/aidl/default/Frontend.h b/tv/tuner/aidl/default/Frontend.h
index 3c602cf..fdedf1e 100644
--- a/tv/tuner/aidl/default/Frontend.h
+++ b/tv/tuner/aidl/default/Frontend.h
@@ -19,6 +19,7 @@
 #include <aidl/android/hardware/tv/tuner/BnFrontend.h>
 #include <fstream>
 #include <iostream>
+#include <thread>
 #include "Tuner.h"
 
 using namespace std;
@@ -46,9 +47,11 @@
     ::ndk::ScopedAStatus getStatus(const std::vector<FrontendStatusType>& in_statusTypes,
                                    std::vector<FrontendStatus>* _aidl_return) override;
     ::ndk::ScopedAStatus setLnb(int32_t in_lnbId) override;
-    ::ndk::ScopedAStatus setLna(bool in_bEnable) override;
     ::ndk::ScopedAStatus linkCiCam(int32_t in_ciCamId, int32_t* _aidl_return) override;
     ::ndk::ScopedAStatus unlinkCiCam(int32_t in_ciCamId) override;
+    ::ndk::ScopedAStatus getHardwareInfo(std::string* _aidl_return) override;
+
+    binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
 
     FrontendType getFrontendType();
     int32_t getFrontendId();
@@ -58,13 +61,17 @@
   private:
     virtual ~Frontend();
     bool supportsSatellite();
+    void scanThreadLoop();
+
     std::shared_ptr<IFrontendCallback> mCallback;
     std::shared_ptr<Tuner> mTuner;
     FrontendType mType = FrontendType::UNDEFINED;
     int32_t mId = 0;
     bool mIsLocked = false;
     int32_t mCiCamId;
-
+    std::thread mScanThread;
+    FrontendSettings mFrontendSettings;
+    FrontendScanType mFrontendScanType;
     std::ifstream mFrontendData;
 };
 
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..48c1b66 100644
--- a/tv/tuner/aidl/default/Tuner.cpp
+++ b/tv/tuner/aidl/default/Tuner.cpp
@@ -55,11 +55,16 @@
     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;
+    mMaxUsableFrontends[FrontendType::ISDBS] = 1;
 
     FrontendCapabilities capsAtsc3;
     capsAtsc3.set<FrontendCapabilities::Tag::atsc3Caps>(FrontendAtsc3Capabilities());
@@ -74,6 +79,7 @@
             FrontendStatusType::BANDWIDTH,
     };
     mFrontendStatusCaps[1] = statusCaps;
+    mMaxUsableFrontends[FrontendType::ATSC3] = 1;
 
     FrontendCapabilities capsDvbc;
     capsDvbc.set<FrontendCapabilities::Tag::dvbcCaps>(FrontendDvbcCapabilities());
@@ -85,6 +91,7 @@
             FrontendStatusType::INTERLEAVINGS, FrontendStatusType::BANDWIDTH,
     };
     mFrontendStatusCaps[2] = statusCaps;
+    mMaxUsableFrontends[FrontendType::DVBC] = 1;
 
     FrontendCapabilities capsDvbs;
     capsDvbs.set<FrontendCapabilities::Tag::dvbsCaps>(FrontendDvbsCapabilities());
@@ -95,6 +102,7 @@
             FrontendStatusType::ROLL_OFF,        FrontendStatusType::IS_MISO,
     };
     mFrontendStatusCaps[3] = statusCaps;
+    mMaxUsableFrontends[FrontendType::DVBS] = 1;
 
     FrontendCapabilities capsDvbt;
     capsDvbt.set<FrontendCapabilities::Tag::dvbtCaps>(FrontendDvbtCapabilities());
@@ -108,8 +116,10 @@
             FrontendStatusType::GUARD_INTERVAL,
             FrontendStatusType::TRANSMISSION_MODE,
             FrontendStatusType::T2_SYSTEM_ID,
+            FrontendStatusType::DVBT_CELL_IDS,
     };
     mFrontendStatusCaps[4] = statusCaps;
+    mMaxUsableFrontends[FrontendType::DVBT] = 1;
 
     FrontendCapabilities capsIsdbt;
     FrontendIsdbtCapabilities isdbtCaps{
@@ -140,6 +150,7 @@
             FrontendStatusType::INTERLEAVINGS,
     };
     mFrontendStatusCaps[5] = statusCaps;
+    mMaxUsableFrontends[FrontendType::ISDBT] = 1;
 
     FrontendCapabilities capsAnalog;
     capsAnalog.set<FrontendCapabilities::Tag::analogCaps>(FrontendAnalogCapabilities());
@@ -151,6 +162,7 @@
             FrontendStatusType::TS_DATA_RATES,
     };
     mFrontendStatusCaps[6] = statusCaps;
+    mMaxUsableFrontends[FrontendType::ANALOG] = 1;
 
     FrontendCapabilities capsAtsc;
     capsAtsc.set<FrontendCapabilities::Tag::atscCaps>(FrontendAtscCapabilities());
@@ -162,6 +174,7 @@
             FrontendStatusType::IS_LINEAR,
     };
     mFrontendStatusCaps[7] = statusCaps;
+    mMaxUsableFrontends[FrontendType::ATSC] = 1;
 
     FrontendCapabilities capsIsdbs3;
     capsIsdbs3.set<FrontendCapabilities::Tag::isdbs3Caps>(FrontendIsdbs3Capabilities());
@@ -169,9 +182,10 @@
     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;
+    mMaxUsableFrontends[FrontendType::ISDBS3] = 1;
 
     FrontendCapabilities capsDtmb;
     capsDtmb.set<FrontendCapabilities::Tag::dtmbCaps>(FrontendDtmbCapabilities());
@@ -182,6 +196,7 @@
             FrontendStatusType::TRANSMISSION_MODE,
     };
     mFrontendStatusCaps[9] = statusCaps;
+    mMaxUsableFrontends[FrontendType::DTMB] = 1;
 
     mLnbs.resize(2);
     mLnbs[0] = ndk::SharedRefBase::make<Lnb>(0);
@@ -313,6 +328,58 @@
     return ::ndk::ScopedAStatus::ok();
 }
 
+::ndk::ScopedAStatus Tuner::setLna(bool /* in_bEnable */) {
+    ALOGV("%s", __FUNCTION__);
+
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Tuner::setMaxNumberOfFrontends(FrontendType in_frontendType,
+                                                    int32_t in_maxNumber) {
+    ALOGV("%s", __FUNCTION__);
+
+    // In the default implementation, every type only has one frontend.
+    if (in_maxNumber < 0 || in_maxNumber > 1) {
+        return ::ndk::ScopedAStatus::fromServiceSpecificError(
+                static_cast<int32_t>(Result::INVALID_ARGUMENT));
+    }
+    mMaxUsableFrontends[in_frontendType] = in_maxNumber;
+    return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Tuner::getMaxNumberOfFrontends(FrontendType in_frontendType,
+                                                    int32_t* _aidl_return) {
+    *_aidl_return = mMaxUsableFrontends[in_frontendType];
+    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 +399,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..216a2b6 100644
--- a/tv/tuner/aidl/default/Tuner.h
+++ b/tv/tuner/aidl/default/Tuner.h
@@ -56,6 +56,13 @@
     ::ndk::ScopedAStatus openLnbByName(const std::string& in_lnbName,
                                        std::vector<int32_t>* out_lnbId,
                                        std::shared_ptr<ILnb>* _aidl_return) override;
+    ::ndk::ScopedAStatus setLna(bool in_bEnable) override;
+    ::ndk::ScopedAStatus setMaxNumberOfFrontends(FrontendType in_frontendType,
+                                                 int32_t in_maxNumber) override;
+    ::ndk::ScopedAStatus getMaxNumberOfFrontends(FrontendType in_frontendType,
+                                                 int32_t* _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);
@@ -78,6 +85,7 @@
     // First used id will be 0.
     int32_t mLastUsedId = -1;
     vector<std::shared_ptr<Lnb>> mLnbs;
+    map<FrontendType, int32_t> mMaxUsableFrontends;
 };
 
 }  // namespace tuner
diff --git a/tv/tuner/aidl/vts/functional/FrontendTests.cpp b/tv/tuner/aidl/vts/functional/FrontendTests.cpp
index 6204803..41e98ea 100644
--- a/tv/tuner/aidl/vts/functional/FrontendTests.cpp
+++ b/tv/tuner/aidl/vts/functional/FrontendTests.cpp
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#include <aidl/android/hardware/tv/tuner/Result.h>
+
 #include "FrontendTests.h"
 
 ndk::ScopedAStatus FrontendCallback::onEvent(FrontendEventType frontendEventType) {
@@ -398,6 +400,20 @@
                             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;
+            }
+            case FrontendStatusType::DVBT_CELL_IDS: {
+                ASSERT_TRUE(std::equal(
+                        realStatuses[i].get<FrontendStatus::Tag::dvbtCellIds>().begin(),
+                        realStatuses[i].get<FrontendStatus::Tag::dvbtCellIds>().end(),
+                        expectStatuses[i].get<FrontendStatus::Tag::dvbtCellIds>().begin()));
+                break;
+            }
             default: {
                 continue;
             }
@@ -430,6 +446,7 @@
         getDvrTests()->startPlaybackInputThread(
                 mDvrConfig.playbackInputFile,
                 mDvrConfig.settings.get<DvrSettings::Tag::playback>());
+        getDvrTests()->startDvrPlayback();
     }
     mFrontendCallback->tuneTestOnLock(mFrontend, config.settings);
     return AssertionResult(true);
@@ -441,6 +458,7 @@
     status = mFrontend->stopTune();
     if (mIsSoftwareFe && testWithDemux) {
         getDvrTests()->stopPlaybackThread();
+        getDvrTests()->stopDvrPlayback();
         getDvrTests()->closeDvrPlayback();
     }
     return AssertionResult(status.isOk());
@@ -468,6 +486,13 @@
     feId = INVALID_ID;
 }
 
+AssertionResult FrontendTests::verifyHardwareInfo() {
+    EXPECT_TRUE(mFrontend) << "Test with openFrontendById first.";
+    std::string info;
+    ndk::ScopedAStatus status = mFrontend->getHardwareInfo(&info);
+    return AssertionResult(status.isOk() && !info.empty());
+}
+
 void FrontendTests::tuneTest(FrontendConfig frontendConf) {
     int32_t feId;
     getFrontendIdByType(frontendConf.type, feId);
@@ -484,6 +509,53 @@
     ASSERT_TRUE(closeFrontend());
 }
 
+void FrontendTests::debugInfoTest(FrontendConfig frontendConf) {
+    int32_t feId;
+    getFrontendIdByType(frontendConf.type, feId);
+    ASSERT_TRUE(feId != INVALID_ID);
+    ASSERT_TRUE(openFrontendById(feId));
+    ASSERT_TRUE(setFrontendCallback());
+    ASSERT_TRUE(tuneFrontend(frontendConf, false /*testWithDemux*/));
+    ASSERT_TRUE(verifyHardwareInfo());
+    ASSERT_TRUE(stopTuneFrontend(false /*testWithDemux*/));
+    ASSERT_TRUE(closeFrontend());
+}
+
+void FrontendTests::maxNumberOfFrontendsTest() {
+    ASSERT_TRUE(getFrontendIds());
+    for (size_t i = 0; i < mFeIds.size(); i++) {
+        ASSERT_TRUE(getFrontendInfo(mFeIds[i]));
+        int32_t defaultMax = -1;
+        ndk::ScopedAStatus status;
+        // Check default value
+        status = mService->getMaxNumberOfFrontends(mFrontendInfo.type, &defaultMax);
+        ASSERT_TRUE(status.isOk());
+        ASSERT_TRUE(defaultMax > 0);
+        // Set to -1
+        status = mService->setMaxNumberOfFrontends(mFrontendInfo.type, -1);
+        ASSERT_TRUE(status.getServiceSpecificError() ==
+                    static_cast<int32_t>(Result::INVALID_ARGUMENT));
+        // Set to defaultMax + 1
+        status = mService->setMaxNumberOfFrontends(mFrontendInfo.type, defaultMax + 1);
+        ASSERT_TRUE(status.getServiceSpecificError() ==
+                    static_cast<int32_t>(Result::INVALID_ARGUMENT));
+        // Set to 0
+        status = mService->setMaxNumberOfFrontends(mFrontendInfo.type, 0);
+        ASSERT_TRUE(status.isOk());
+        // Check after set
+        int32_t currentMax = -1;
+        status = mService->getMaxNumberOfFrontends(mFrontendInfo.type, &currentMax);
+        ASSERT_TRUE(status.isOk());
+        ASSERT_TRUE(currentMax == 0);
+        // Reset to default
+        status = mService->setMaxNumberOfFrontends(mFrontendInfo.type, defaultMax);
+        ASSERT_TRUE(status.isOk());
+        status = mService->getMaxNumberOfFrontends(mFrontendInfo.type, &currentMax);
+        ASSERT_TRUE(status.isOk());
+        ASSERT_TRUE(defaultMax == currentMax);
+    }
+}
+
 void FrontendTests::scanTest(FrontendConfig frontendConf, FrontendScanType scanType) {
     int32_t feId;
     getFrontendIdByType(frontendConf.type, feId);
diff --git a/tv/tuner/aidl/vts/functional/FrontendTests.h b/tv/tuner/aidl/vts/functional/FrontendTests.h
index e5a9cd3..1745f76 100644
--- a/tv/tuner/aidl/vts/functional/FrontendTests.h
+++ b/tv/tuner/aidl/vts/functional/FrontendTests.h
@@ -94,10 +94,13 @@
 
     AssertionResult linkCiCam(int32_t ciCamId);
     AssertionResult unlinkCiCam(int32_t ciCamId);
+    AssertionResult verifyHardwareInfo();
 
     void getFrontendIdByType(FrontendType feType, int32_t& feId);
     void tuneTest(FrontendConfig frontendConf);
     void scanTest(FrontendConfig frontend, FrontendScanType type);
+    void debugInfoTest(FrontendConfig frontendConf);
+    void maxNumberOfFrontendsTest();
 
     void setDvrTests(DvrTests* dvrTests) { mExternalDvrTests = dvrTests; }
     void setDemux(std::shared_ptr<IDemux> demux) { getDvrTests()->setDemux(demux); }
diff --git a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp
index 89e42df..0566089 100644
--- a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp
+++ b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp
@@ -704,6 +704,9 @@
     bool mediaFilter = isMediaFilter(filterConf);
     auto filter = mFilterTests.getFilterById(filterId);
 
+    // startTime needs to be set before calling setDelayHint.
+    auto startTime = std::chrono::steady_clock::now();
+
     auto timeDelayInMs = std::chrono::milliseconds(filterConf.timeDelayInMs);
     if (timeDelayInMs.count() > 0) {
         FilterDelayHint delayHint;
@@ -724,15 +727,22 @@
         ASSERT_EQ(filter->setDelayHint(delayHint).isOk(), !mediaFilter);
     }
 
-    // start and stop filter in order to circumvent callback scheduler race
-    // conditions after adjusting filter delays.
+    // start and stop filter (and wait for first callback) in order to
+    // circumvent callback scheduler race conditions after adjusting filter
+    // delays.
+    auto cb = mFilterTests.getFilterCallbacks().at(filterId);
+    auto future =
+            cb->verifyFilterCallback([](const std::vector<DemuxFilterEvent>&) { return true; });
     mFilterTests.startFilter(filterId);
+
+    auto timeout = std::chrono::seconds(30);
+    ASSERT_EQ(future.wait_for(timeout), std::future_status::ready);
+
     mFilterTests.stopFilter(filterId);
 
     if (!mediaFilter) {
-        auto cb = mFilterTests.getFilterCallbacks().at(filterId);
         int callbackSize = 0;
-        auto future = cb->verifyFilterCallback(
+        future = cb->verifyFilterCallback(
                 [&callbackSize](const std::vector<DemuxFilterEvent>& events) {
                     for (const auto& event : events) {
                         callbackSize += getDemuxFilterEventDataLength(event);
@@ -744,11 +754,9 @@
         // 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;
 
@@ -883,6 +891,22 @@
     mFrontendTests.tuneTest(frontendMap[live.frontendId]);
 }
 
+TEST_P(TunerFrontendAidlTest, getHardwareInfo) {
+    description("Test Frontend get hardware info");
+    if (!live.hasFrontendConnection) {
+        return;
+    }
+    mFrontendTests.debugInfoTest(frontendMap[live.frontendId]);
+}
+
+TEST_P(TunerFrontendAidlTest, maxNumberOfFrontends) {
+    description("Test Max Frontend number");
+    if (!live.hasFrontendConnection) {
+        return;
+    }
+    mFrontendTests.maxNumberOfFrontendsTest();
+}
+
 TEST_P(TunerBroadcastAidlTest, BroadcastDataFlowVideoFilterTest) {
     description("Test Video Filter functionality in Broadcast use case.");
     if (!live.hasFrontendConnection) {
diff --git a/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h b/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h
index b6cc5f8..b73d594 100644
--- a/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h
+++ b/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h
@@ -954,6 +954,7 @@
         settings.isCheckCrc = section->getIsCheckCrc();
         settings.isRepeat = section->getIsRepeat();
         settings.isRaw = section->getIsRaw();
+        settings.bitWidthOfLengthField = section->getBitWidthOfLengthField();
         return settings;
     }
 
diff --git a/tv/tuner/config/api/current.txt b/tv/tuner/config/api/current.txt
index db1d076..4d519d7 100644
--- a/tv/tuner/config/api/current.txt
+++ b/tv/tuner/config/api/current.txt
@@ -477,9 +477,11 @@
 
   public class SectionFilterSettings {
     ctor public SectionFilterSettings();
+    method @Nullable public java.math.BigInteger getBitWidthOfLengthField();
     method @Nullable public boolean getIsCheckCrc();
     method @Nullable public boolean getIsRaw();
     method @Nullable public boolean getIsRepeat();
+    method public void setBitWidthOfLengthField(@Nullable java.math.BigInteger);
     method public void setIsCheckCrc(@Nullable boolean);
     method public void setIsRaw(@Nullable boolean);
     method public void setIsRepeat(@Nullable boolean);
diff --git a/tv/tuner/config/tuner_testing_dynamic_configuration.xsd b/tv/tuner/config/tuner_testing_dynamic_configuration.xsd
index 54cedfc..94f108b 100644
--- a/tv/tuner/config/tuner_testing_dynamic_configuration.xsd
+++ b/tv/tuner/config/tuner_testing_dynamic_configuration.xsd
@@ -226,6 +226,7 @@
         <xs:attribute name="isCheckCrc" type="xs:boolean" use="required"/>
         <xs:attribute name="isRepeat" type="xs:boolean" use="required"/>
         <xs:attribute name="isRaw" type="xs:boolean" use="required"/>
+        <xs:attribute name="bitWidthOfLengthField" type="xs:nonNegativeInteger" use="required"/>
     </xs:complexType>
     <xs:complexType name="recordFilterSettings">
         <xs:attribute name="tsIndexMask" type="tsIndexMask" use="required"/>
diff --git a/usb/gadget/1.1/default/lib/UsbGadgetUtils.cpp b/usb/gadget/1.1/default/lib/UsbGadgetUtils.cpp
index 8402853..4c40bf8 100644
--- a/usb/gadget/1.1/default/lib/UsbGadgetUtils.cpp
+++ b/usb/gadget/1.1/default/lib/UsbGadgetUtils.cpp
@@ -178,6 +178,9 @@
 
 Status addAdb(MonitorFfs* monitorFfs, int* functionCount) {
     ALOGI("setCurrentUsbFunctions Adb");
+    if (!WriteStringToFile("1", DESC_USE_PATH))
+        return Status::ERROR;
+
     if (!monitorFfs->addInotifyFd("/dev/usb-ffs/adb/")) return Status::ERROR;
 
     if (linkFunction("ffs.adb", (*functionCount)++)) return Status::ERROR;
diff --git a/usb/gadget/1.2/default/lib/UsbGadgetUtils.cpp b/usb/gadget/1.2/default/lib/UsbGadgetUtils.cpp
index 8986556..fa50821 100644
--- a/usb/gadget/1.2/default/lib/UsbGadgetUtils.cpp
+++ b/usb/gadget/1.2/default/lib/UsbGadgetUtils.cpp
@@ -190,6 +190,9 @@
 
 Status addAdb(MonitorFfs* monitorFfs, int* functionCount) {
     ALOGI("setCurrentUsbFunctions Adb");
+    if (!WriteStringToFile("1", DESC_USE_PATH))
+        return Status::ERROR;
+
     if (!monitorFfs->addInotifyFd("/dev/usb-ffs/adb/")) return Status::ERROR;
 
     if (linkFunction("ffs.adb", (*functionCount)++)) return Status::ERROR;
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/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/1.5/default/Android.bp b/wifi/1.5/default/Android.bp
new file mode 100644
index 0000000..6333b6e
--- /dev/null
+++ b/wifi/1.5/default/Android.bp
@@ -0,0 +1,105 @@
+// 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"],
+}
+
+filegroup {
+    name: "android.hardware.wifi@1.0-service_srcs",
+    srcs: ["service.cpp"],
+}
+
+cc_defaults {
+    name: "android.hardware.wifi@1.0-service_default",
+    srcs: [":android.hardware.wifi@1.0-service_srcs"],
+    relative_install_path: "hw",
+    soc_specific: true,
+    shared_libs: [
+        "android.hardware.wifi@1.0",
+        "android.hardware.wifi@1.1",
+        "android.hardware.wifi@1.2",
+        "android.hardware.wifi@1.3",
+        "android.hardware.wifi@1.4",
+        "android.hardware.wifi@1.5",
+        "libbase",
+        "libcutils",
+        "libhidlbase",
+        "liblog",
+        "libnl",
+        "libutils",
+        "libwifi-system-iface",
+        "libxml2",
+    ],
+    cppflags: [
+        "-Wall",
+        "-Werror",
+        "-Wextra",
+    ],
+}
+
+filegroup {
+    name: "android.hardware.wifi@1.0-service-lib_srcs",
+    srcs: [
+        "hidl_struct_util.cpp",
+        "hidl_sync_util.cpp",
+        "ringbuffer.cpp",
+        "wifi.cpp",
+        "wifi_ap_iface.cpp",
+        "wifi_chip.cpp",
+        "wifi_feature_flags.cpp",
+        "wifi_iface_util.cpp",
+        "wifi_legacy_hal.cpp",
+        "wifi_legacy_hal_factory.cpp",
+        "wifi_legacy_hal_stubs.cpp",
+        "wifi_mode_controller.cpp",
+        "wifi_nan_iface.cpp",
+        "wifi_p2p_iface.cpp",
+        "wifi_rtt_controller.cpp",
+        "wifi_sta_iface.cpp",
+        "wifi_status_util.cpp",
+    ],
+}
+
+cc_defaults {
+    name: "android.hardware.wifi@1.0-service-lib_defaults",
+    srcs: [":android.hardware.wifi@1.0-service-lib_srcs"],
+    relative_install_path: "hw",
+    soc_specific: true,
+    shared_libs: [
+        "android.hardware.wifi@1.0",
+        "android.hardware.wifi@1.1",
+        "android.hardware.wifi@1.2",
+        "android.hardware.wifi@1.3",
+        "android.hardware.wifi@1.4",
+        "android.hardware.wifi@1.5",
+        "libbase",
+        "libcutils",
+        "libhidlbase",
+        "liblog",
+        "libnl",
+        "libutils",
+        "libwifi-system-iface",
+        "libxml2",
+    ],
+    // Generated by building android.hardware.wifi@1.0-service-lib and printing LOCAL_CPPFLAGS.
+    cppflags: [
+        "-Wall",
+        "-Werror",
+        "-Wextra",
+        "-DWIFI_HIDL_FEATURE_DUAL_INTERFACE",
+    ],
+    export_include_dirs: ["."],
+    include_dirs: ["external/libxml2/include"],
+}
diff --git a/wifi/1.5/default/wifi_feature_flags.cpp b/wifi/1.5/default/wifi_feature_flags.cpp
index 124ba32..70ce55a 100644
--- a/wifi/1.5/default/wifi_feature_flags.cpp
+++ b/wifi/1.5/default/wifi_feature_flags.cpp
@@ -157,43 +157,42 @@
 // List of pre-defined interface combinations that can be enabled at runtime via
 // setting the property: "kDebugPresetInterfaceCombinationIdxProperty" to the
 // corresponding index value.
-static const std::vector<
-    std::pair<std::string, std::vector<IWifiChip::ChipMode>>>
-    kDebugChipModes{
+static const std::vector<std::pair<std::string, std::vector<IWifiChip::ChipMode>>> kDebugChipModes{
         // Legacy combination - No STA/AP concurrencies.
         // 0 - (1 AP) or (1 STA + 1 of (P2P or NAN))
         {"No STA/AP Concurrency",
          {{kMainModeId,
-           ChipIfaceCombination::make_vec(
-               {{{{AP}, 1}}, {{{STA}, 1}, {{P2P, NAN}, 1}}})}}},
+           ChipIfaceCombination::make_vec({{{{AP}, 1}}, {{{STA}, 1}, {{P2P, NAN}, 1}}})}}},
 
         // STA + AP concurrency
         // 1 - (1 STA + 1 AP) or (1 STA + 1 of (P2P or NAN))
         {"STA + AP Concurrency",
-         {{kMainModeId,
-           ChipIfaceCombination::make_vec(
-               {{{{STA}, 1}, {{AP}, 1}}, {{{STA}, 1}, {{P2P, NAN}, 1}}})}}},
+         {{kMainModeId, ChipIfaceCombination::make_vec(
+                                {{{{STA}, 1}, {{AP}, 1}}, {{{STA}, 1}, {{P2P, NAN}, 1}}})}}},
 
         // STA + STA concurrency
         // 2 - (1 STA + 1 AP) or (2 STA + 1 of (P2P or NAN))
         {"Dual STA Concurrency",
-         {{kMainModeId,
-           ChipIfaceCombination::make_vec(
-               {{{{STA}, 1}, {{AP}, 1}}, {{{STA}, 2}, {{P2P, NAN}, 1}}})}}},
+         {{kMainModeId, ChipIfaceCombination::make_vec(
+                                {{{{STA}, 1}, {{AP}, 1}}, {{{STA}, 2}, {{P2P, NAN}, 1}}})}}},
 
         // AP + AP + STA concurrency
         // 3 - (1 STA + 2 AP) or (1 STA + 1 of (P2P or NAN))
         {"Dual AP Concurrency",
-         {{kMainModeId,
-           ChipIfaceCombination::make_vec(
-               {{{{STA}, 1}, {{AP}, 2}}, {{{STA}, 1}, {{P2P, NAN}, 1}}})}}},
+         {{kMainModeId, ChipIfaceCombination::make_vec(
+                                {{{{STA}, 1}, {{AP}, 2}}, {{{STA}, 1}, {{P2P, NAN}, 1}}})}}},
 
         // STA + STA concurrency and AP + AP + STA concurrency
         // 4 - (1 STA + 2 AP) or (2 STA + 1 of (P2P or NAN))
         {"Dual STA & Dual AP Concurrency",
+         {{kMainModeId, ChipIfaceCombination::make_vec(
+                                {{{{STA}, 1}, {{AP}, 2}}, {{{STA}, 2}, {{P2P, NAN}, 1}}})}}},
+
+        // STA + STA concurrency
+        // 5 - (1 STA + 1 AP (bridged or single) | P2P | NAN), or (2 STA))
+        {"Dual STA or STA plus single other interface",
          {{kMainModeId,
-           ChipIfaceCombination::make_vec(
-               {{{{STA}, 1}, {{AP}, 2}}, {{{STA}, 2}, {{P2P, NAN}, 1}}})}}}};
+           ChipIfaceCombination::make_vec({{{{STA}, 1}, {{P2P, NAN, AP}, 1}}, {{{STA}, 2}}})}}}};
 
 #undef STA
 #undef AP
diff --git a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/IHostapdCallback.aidl b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/IHostapdCallback.aidl
index 36d2104..9dd062a 100644
--- a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/IHostapdCallback.aidl
+++ b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/IHostapdCallback.aidl
@@ -36,5 +36,5 @@
 interface IHostapdCallback {
   oneway void onApInstanceInfoChanged(in android.hardware.wifi.hostapd.ApInfo apInfo);
   oneway void onConnectedClientsChanged(in android.hardware.wifi.hostapd.ClientInfo clientInfo);
-  oneway void onFailure(in String ifaceName);
+  oneway void onFailure(in String ifaceName, in String instanceName);
 }
diff --git a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/NetworkParams.aidl b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/NetworkParams.aidl
index ffe2f33..4554223 100644
--- a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/NetworkParams.aidl
+++ b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/NetworkParams.aidl
@@ -39,4 +39,5 @@
   android.hardware.wifi.hostapd.EncryptionType encryptionType;
   String passphrase;
   boolean isMetered;
+  byte[] vendorElements;
 }
diff --git a/wifi/hostapd/aidl/android/hardware/wifi/hostapd/IHostapdCallback.aidl b/wifi/hostapd/aidl/android/hardware/wifi/hostapd/IHostapdCallback.aidl
index 7b04944..456f46a 100644
--- a/wifi/hostapd/aidl/android/hardware/wifi/hostapd/IHostapdCallback.aidl
+++ b/wifi/hostapd/aidl/android/hardware/wifi/hostapd/IHostapdCallback.aidl
@@ -41,7 +41,10 @@
      * Invoked when an asynchronous failure is encountered in one of the access
      * points added via |IHostapd.addAccessPoint|.
      *
-     * @param ifaceName Name of the interface.
+     * @param ifaceName Name of the interface which was added via
+     *                  |IHostapd.addAccessPoint|.
+     * @param instanceName Name of the AP instance which is associated with
+     *                     the interface.
      */
-    oneway void onFailure(in String ifaceName);
+    oneway void onFailure(in String ifaceName, in String instanceName);
 }
diff --git a/wifi/hostapd/aidl/android/hardware/wifi/hostapd/NetworkParams.aidl b/wifi/hostapd/aidl/android/hardware/wifi/hostapd/NetworkParams.aidl
index df84eca..47d9e6f 100644
--- a/wifi/hostapd/aidl/android/hardware/wifi/hostapd/NetworkParams.aidl
+++ b/wifi/hostapd/aidl/android/hardware/wifi/hostapd/NetworkParams.aidl
@@ -44,4 +44,12 @@
      * CHARGEABLE_PUBLIC_NETWORK when set to true.
      */
     boolean isMetered;
+    /**
+     * Additional vendor specific elements for Beacon and Probe Response frames
+     * This parameter can be used to add additional vendor specific element(s) into
+     * the end of the Beacon and Probe Response frames. The format for these
+     * element(s) is a binary dump of the raw information elements (id+len+payload for
+     * one or more elements). Example: byte[]{ 221, 4, 17, 34, 51, 1 }
+     */
+    byte[] vendorElements;
 }
diff --git a/wifi/hostapd/aidl/vts/functional/VtsHalHostapdTargetTest.cpp b/wifi/hostapd/aidl/vts/functional/VtsHalHostapdTargetTest.cpp
index 41c54b3..dad7085 100644
--- a/wifi/hostapd/aidl/vts/functional/VtsHalHostapdTargetTest.cpp
+++ b/wifi/hostapd/aidl/vts/functional/VtsHalHostapdTargetTest.cpp
@@ -232,7 +232,7 @@
         const ::aidl::android::hardware::wifi::hostapd::ClientInfo &) override {
         return ndk::ScopedAStatus::ok();
     }
-    ::ndk::ScopedAStatus onFailure(const std::string &) override {
+    ::ndk::ScopedAStatus onFailure(const std::string&, const std::string&) override {
         return ndk::ScopedAStatus::ok();
     }
 };
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..d00dd21
--- /dev/null
+++ b/wifi/supplicant/aidl/Android.bp
@@ -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 {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_interfaces_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+aidl_interface {
+    name: "android.hardware.wifi.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/ColorTransformPayload.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/ColorTransformPayload.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/AnqpData.aidl
index df07c9c..d8e49d7 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.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,9 +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 ColorTransformPayload {
-  float[] matrix;
-  android.hardware.graphics.common.ColorTransform hint;
+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/HandleIndex.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/HandleIndex.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/AnqpInfoId.aidl
index b87870d..cc32360 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.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,9 +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 HandleIndex {
-  EMPTY = -1,
-  CACHED = -2,
+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/ColorTransformPayload.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/ColorTransformPayload.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/AssociationRejectionData.aidl
index df07c9c..f6830dc 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.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,9 +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;
 @VintfStability
-parcelable ColorTransformPayload {
-  float[] matrix;
-  android.hardware.graphics.common.ColorTransform hint;
+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/HandleIndex.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/HandleIndex.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/AuthAlgMask.aidl
index b87870d..9cd178d 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.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,9 +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 HandleIndex {
-  EMPTY = -1,
-  CACHED = -2,
+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/ColorTransformPayload.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/ColorTransformPayload.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/BssTmData.aidl
index df07c9c..34d894d 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.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,9 +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 ColorTransformPayload {
-  float[] matrix;
-  android.hardware.graphics.common.ColorTransform hint;
+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/HandleIndex.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/HandleIndex.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/BssTmDataFlagsMask.aidl
index b87870d..f215f05 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.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,9 +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 HandleIndex {
-  EMPTY = -1,
-  CACHED = -2,
+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/ColorTransformPayload.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/ColorTransformPayload.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/BssTmStatusCode.aidl
index df07c9c..c95825f 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.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,9 +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;
-@VintfStability
-parcelable ColorTransformPayload {
-  float[] matrix;
-  android.hardware.graphics.common.ColorTransform hint;
+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/ColorTransformPayload.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/ColorTransformPayload.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/BssidChangeReason.aidl
index df07c9c..1d24579 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.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,9 +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;
-@VintfStability
-parcelable ColorTransformPayload {
-  float[] matrix;
-  android.hardware.graphics.common.ColorTransform hint;
+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/FloatColor.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/FloatColor.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/BtCoexistenceMode.aidl
index faadf57..bdc1b4a 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FloatColor.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,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;
-@VintfStability
-parcelable FloatColor {
-  float r;
-  float g;
-  float b;
-  float a;
+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/ColorTransformPayload.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/ColorTransformPayload.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ConnectionCapabilities.aidl
index df07c9c..433b3d80 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.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,9 +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 ColorTransformPayload {
-  float[] matrix;
-  android.hardware.graphics.common.ColorTransform hint;
+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/HandleIndex.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/HandleIndex.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/DebugLevel.aidl
index b87870d..fbfb5b3 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.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,9 +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 HandleIndex {
-  EMPTY = -1,
-  CACHED = -2,
+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/HandleIndex.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/HandleIndex.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/DppAkm.aidl
index b87870d..df2aef8 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.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,9 +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 HandleIndex {
-  EMPTY = -1,
-  CACHED = -2,
+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/HandleIndex.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/HandleIndex.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/DppCurve.aidl
index b87870d..e69da44 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.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,9 +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 HandleIndex {
-  EMPTY = -1,
-  CACHED = -2,
+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/HandleIndex.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/HandleIndex.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/DppEventType.aidl
index b87870d..9e394fc 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.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,9 +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 HandleIndex {
-  EMPTY = -1,
-  CACHED = -2,
+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/HandleIndex.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/HandleIndex.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/DppFailureCode.aidl
index b87870d..7e7c806 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.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,9 +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 HandleIndex {
-  EMPTY = -1,
-  CACHED = -2,
+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/HandleIndex.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/HandleIndex.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/DppNetRole.aidl
index b87870d..c6d3522 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.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,9 +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 HandleIndex {
-  EMPTY = -1,
-  CACHED = -2,
+enum DppNetRole {
+  STA = 0,
+  AP = 1,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.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/HandleIndex.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/DppProgressCode.aidl
index b87870d..f0618a5 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.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,9 +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 HandleIndex {
-  EMPTY = -1,
-  CACHED = -2,
+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/FloatColor.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/DppResponderBootstrapInfo.aidl
similarity index 86%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FloatColor.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/DppResponderBootstrapInfo.aidl
index faadf57..8b6492b 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FloatColor.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,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;
 @VintfStability
-parcelable FloatColor {
-  float r;
-  float g;
-  float b;
-  float a;
+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/HandleIndex.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/HandleIndex.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/EapErrorCode.aidl
index b87870d..2cf81d9 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.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,9 +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 HandleIndex {
-  EMPTY = -1,
-  CACHED = -2,
+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/HandleIndex.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/HandleIndex.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/EapMethod.aidl
index b87870d..4ab23af 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.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,9 +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 HandleIndex {
-  EMPTY = -1,
-  CACHED = -2,
+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/HandleIndex.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/HandleIndex.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/EapPhase2Method.aidl
index b87870d..4bd93a0 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.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,9 +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 HandleIndex {
-  EMPTY = -1,
-  CACHED = -2,
+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/HandleIndex.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/HandleIndex.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ExtRadioWorkDefaults.aidl
index b87870d..cbf1a3e 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.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,9 +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 HandleIndex {
-  EMPTY = -1,
-  CACHED = -2,
+enum ExtRadioWorkDefaults {
+  TIMEOUT_IN_SECS = 10,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/WhitePointNits.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/FreqRange.aidl
similarity index 88%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/WhitePointNits.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/FreqRange.aidl
index c3925d2..0971d51 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/WhitePointNits.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;
+package android.hardware.wifi.supplicant;
 @VintfStability
-parcelable WhitePointNits {
-  float nits;
+parcelable FreqRange {
+  int min;
+  int max;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.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/HandleIndex.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/GroupCipherMask.aidl
index b87870d..f2da925 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.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,9 +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 HandleIndex {
-  EMPTY = -1,
-  CACHED = -2,
+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/HandleIndex.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/HandleIndex.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/GroupMgmtCipherMask.aidl
index b87870d..c24d6cc 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.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,9 +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 HandleIndex {
-  EMPTY = -1,
-  CACHED = -2,
+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/WhitePointNits.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/GsmRand.aidl
similarity index 88%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/WhitePointNits.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/GsmRand.aidl
index c3925d2..599a683 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/WhitePointNits.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;
+package android.hardware.wifi.supplicant;
 @VintfStability
-parcelable WhitePointNits {
-  float nits;
+parcelable GsmRand {
+  byte[] data;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.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/ColorTransformPayload.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/Hs20AnqpData.aidl
index df07c9c..43b182a 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.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,9 +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 ColorTransformPayload {
-  float[] matrix;
-  android.hardware.graphics.common.ColorTransform hint;
+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/HandleIndex.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/HandleIndex.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/Hs20AnqpSubtypes.aidl
index b87870d..270d43b 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.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,9 +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 HandleIndex {
-  EMPTY = -1,
-  CACHED = -2,
+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/ColorTransformPayload.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/ColorTransformPayload.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantCallback.aidl
index df07c9c..72ab3b9 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.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,9 +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 ColorTransformPayload {
-  float[] matrix;
-  android.hardware.graphics.common.ColorTransform hint;
+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..826d916
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl
@@ -0,0 +1,54 @@
+/*
+ * 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);
+  oneway void onGroupFrequencyChanged(in String groupIfname, in int frequency);
+}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.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/ColorTransformPayload.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pNetwork.aidl
index df07c9c..ef72724 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.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,9 +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 ColorTransformPayload {
-  float[] matrix;
-  android.hardware.graphics.common.ColorTransform hint;
+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/ColorTransformPayload.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/ColorTransformPayload.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.aidl
index df07c9c..4f7584d 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.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,9 +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 ColorTransformPayload {
-  float[] matrix;
-  android.hardware.graphics.common.ColorTransform hint;
+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/LayerGenericMetadataKey.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/IfaceInfo.aidl
similarity index 87%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerGenericMetadataKey.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/IfaceInfo.aidl
index 73385d4..6706c8c 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerGenericMetadataKey.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,9 +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;
 @VintfStability
-parcelable LayerGenericMetadataKey {
+parcelable IfaceInfo {
+  android.hardware.wifi.supplicant.IfaceType type;
   String name;
-  boolean mandatory;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.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/HandleIndex.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/IfaceType.aidl
index b87870d..557dbd7 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.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,9 +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 HandleIndex {
-  EMPTY = -1,
-  CACHED = -2,
+enum IfaceType {
+  STA = 0,
+  P2P = 1,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.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/HandleIndex.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/KeyMgmtMask.aidl
index b87870d..7228480 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.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,9 +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 HandleIndex {
-  EMPTY = -1,
-  CACHED = -2,
+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/HandleIndex.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/HandleIndex.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/LegacyMode.aidl
index b87870d..6896d75 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.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,9 +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 HandleIndex {
-  EMPTY = -1,
-  CACHED = -2,
+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/WhitePointNits.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MacAddress.aidl
similarity index 88%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/WhitePointNits.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MacAddress.aidl
index c3925d2..d17930a 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/WhitePointNits.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;
+package android.hardware.wifi.supplicant;
 @VintfStability
-parcelable WhitePointNits {
-  float nits;
+parcelable MacAddress {
+  byte[] data;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.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/ColorTransformPayload.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MboAssocDisallowedReasonCode.aidl
index df07c9c..661165d 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.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,9 +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;
-@VintfStability
-parcelable ColorTransformPayload {
-  float[] matrix;
-  android.hardware.graphics.common.ColorTransform hint;
+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/HandleIndex.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/HandleIndex.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MboCellularDataConnectionPrefValue.aidl
index b87870d..c4024d0 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.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,9 +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 HandleIndex {
-  EMPTY = -1,
-  CACHED = -2,
+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/ColorTransformPayload.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/ColorTransformPayload.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MboTransitionReasonCode.aidl
index df07c9c..caed095 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.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,9 +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;
-@VintfStability
-parcelable ColorTransformPayload {
-  float[] matrix;
-  android.hardware.graphics.common.ColorTransform hint;
+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/FloatColor.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/FloatColor.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MiracastMode.aidl
index faadf57..6bc9e4d 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FloatColor.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,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;
-@VintfStability
-parcelable FloatColor {
-  float r;
-  float g;
-  float b;
-  float a;
+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/ColorTransformPayload.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/NetworkRequestEapSimGsmAuthParams.aidl
similarity index 85%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/NetworkRequestEapSimGsmAuthParams.aidl
index df07c9c..1f03bb8 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.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,9 +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;
 @VintfStability
-parcelable ColorTransformPayload {
-  float[] matrix;
-  android.hardware.graphics.common.ColorTransform hint;
+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/FloatColor.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/NetworkRequestEapSimUmtsAuthParams.aidl
similarity index 86%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FloatColor.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/NetworkRequestEapSimUmtsAuthParams.aidl
index faadf57..956a799 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FloatColor.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,11 +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;
 @VintfStability
-parcelable FloatColor {
-  float r;
-  float g;
-  float b;
-  float a;
+parcelable NetworkRequestEapSimUmtsAuthParams {
+  byte[] rand;
+  byte[] autn;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FloatColor.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/FloatColor.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/NetworkResponseEapSimGsmAuthParams.aidl
index faadf57..29415b7 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FloatColor.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,11 +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;
 @VintfStability
-parcelable FloatColor {
-  float r;
-  float g;
-  float b;
-  float a;
+parcelable NetworkResponseEapSimGsmAuthParams {
+  byte[] kc;
+  byte[] sres;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FloatColor.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/NetworkResponseEapSimUmtsAuthParams.aidl
similarity index 86%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FloatColor.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/NetworkResponseEapSimUmtsAuthParams.aidl
index faadf57..4e58dd8 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FloatColor.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,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;
 @VintfStability
-parcelable FloatColor {
-  float r;
-  float g;
-  float b;
-  float a;
+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/FloatColor.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/FloatColor.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/OceRssiBasedAssocRejectAttr.aidl
index faadf57..95a95bc 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FloatColor.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,11 +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;
 @VintfStability
-parcelable FloatColor {
-  float r;
-  float g;
-  float b;
-  float a;
+parcelable OceRssiBasedAssocRejectAttr {
+  int deltaRssi;
+  int retryDelayS;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.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/HandleIndex.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/OcspType.aidl
index b87870d..89de811 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.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,9 +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 HandleIndex {
-  EMPTY = -1,
-  CACHED = -2,
+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/FloatColor.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/FloatColor.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/OsuMethod.aidl
index faadf57..1b99e2f 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FloatColor.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,11 +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;
-@VintfStability
-parcelable FloatColor {
-  float r;
-  float g;
-  float b;
-  float a;
+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/HandleIndex.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/HandleIndex.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pGroupCapabilityMask.aidl
index b87870d..ffee12c 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.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,9 +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 HandleIndex {
-  EMPTY = -1,
-  CACHED = -2,
+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/ColorTransformPayload.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/ColorTransformPayload.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pProvDiscStatusCode.aidl
index df07c9c..c8e53b9 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ColorTransformPayload.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,9 +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;
-@VintfStability
-parcelable ColorTransformPayload {
-  float[] matrix;
-  android.hardware.graphics.common.ColorTransform hint;
+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/HandleIndex.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/HandleIndex.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pStatusCode.aidl
index b87870d..c7ad383 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.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,9 +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 HandleIndex {
-  EMPTY = -1,
-  CACHED = -2,
+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/HandleIndex.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/PairwiseCipherMask.aidl
similarity index 85%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/PairwiseCipherMask.aidl
index b87870d..d9b00e1 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.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,9 +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 HandleIndex {
-  EMPTY = -1,
-  CACHED = -2,
+enum PairwiseCipherMask {
+  NONE = 1,
+  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/HandleIndex.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/HandleIndex.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ProtoMask.aidl
index b87870d..de92428 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.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,9 +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 HandleIndex {
-  EMPTY = -1,
-  CACHED = -2,
+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/FloatColor.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/FloatColor.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/RxFilterType.aidl
index faadf57..63f5bf2 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FloatColor.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,11 +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;
-@VintfStability
-parcelable FloatColor {
-  float r;
-  float g;
-  float b;
-  float a;
+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/FloatColor.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/FloatColor.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/SaeH2eMode.aidl
index faadf57..978c337 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FloatColor.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,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;
-@VintfStability
-parcelable FloatColor {
-  float r;
-  float g;
-  float b;
-  float a;
+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/HandleIndex.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/HandleIndex.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/StaIfaceCallbackState.aidl
index b87870d..d78cfa2 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.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,9 +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 HandleIndex {
-  EMPTY = -1,
-  CACHED = -2,
+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/HandleIndex.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/HandleIndex.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/SupplicantStatusCode.aidl
index b87870d..32d71a3 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.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,9 +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 HandleIndex {
-  EMPTY = -1,
-  CACHED = -2,
+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/HandleIndex.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/HandleIndex.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/TransitionDisableIndication.aidl
index b87870d..7c63217 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.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,9 +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 HandleIndex {
-  EMPTY = -1,
-  CACHED = -2,
+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/HandleIndex.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/HandleIndex.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WifiTechnology.aidl
index b87870d..ad36e68 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.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,9 +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 HandleIndex {
-  EMPTY = -1,
-  CACHED = -2,
+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/HandleIndex.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/HandleIndex.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WpaDriverCapabilitiesMask.aidl
index b87870d..43772af 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.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,9 +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 HandleIndex {
-  EMPTY = -1,
-  CACHED = -2,
+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/HandleIndex.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/HandleIndex.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WpsConfigError.aidl
index b87870d..c48b282 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.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,9 +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 HandleIndex {
-  EMPTY = -1,
-  CACHED = -2,
+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/HandleIndex.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/HandleIndex.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WpsConfigMethods.aidl
index b87870d..c98c479 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.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,9 +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 HandleIndex {
-  EMPTY = -1,
-  CACHED = -2,
+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/HandleIndex.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/HandleIndex.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WpsDevPasswordId.aidl
index b87870d..975f1ab 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.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,9 +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 HandleIndex {
-  EMPTY = -1,
-  CACHED = -2,
+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/HandleIndex.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/HandleIndex.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WpsErrorIndication.aidl
index b87870d..50e69ff 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.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,9 +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 HandleIndex {
-  EMPTY = -1,
-  CACHED = -2,
+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/HandleIndex.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/HandleIndex.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WpsProvisionMethod.aidl
index b87870d..f6dba23 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/HandleIndex.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,9 +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 HandleIndex {
-  EMPTY = -1,
-  CACHED = -2,
+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/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/BtCoexistenceMode.aidl
similarity index 61%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
copy to wifi/supplicant/aidl/android/hardware/wifi/supplicant/BtCoexistenceMode.aidl
index a0a1d4b..4972744 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
+++ b/wifi/supplicant/aidl/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,
@@ -14,16 +14,16 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
+package android.hardware.wifi.supplicant;
 
 /**
- * Color representation as a floating point number in the range [0.0 - 1.0]
+ * Enum describing the modes of BT coexistence supported
+ * via driver commands.
  */
-
 @VintfStability
-parcelable FloatColor {
-    float r;
-    float g;
-    float b;
-    float a;
+@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/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/DppAkm.aidl
similarity index 63%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
copy to wifi/supplicant/aidl/android/hardware/wifi/supplicant/DppAkm.aidl
index a0a1d4b..63fff54 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
+++ b/wifi/supplicant/aidl/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,
@@ -14,16 +14,16 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
+package android.hardware.wifi.supplicant;
 
 /**
- * Color representation as a floating point number in the range [0.0 - 1.0]
+ * DppAkm: The various AKMs that can be provisioned using DPP.
  */
-
 @VintfStability
-parcelable FloatColor {
-    float r;
-    float g;
-    float b;
-    float a;
+@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/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/DppEventType.aidl
similarity index 63%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
copy to wifi/supplicant/aidl/android/hardware/wifi/supplicant/DppEventType.aidl
index a0a1d4b..4b9b38b 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
+++ b/wifi/supplicant/aidl/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,
@@ -14,16 +14,14 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
+package android.hardware.wifi.supplicant;
 
 /**
- * Color representation as a floating point number in the range [0.0 - 1.0]
+ * DppEventType: Major events for DPP (Easy Connect) Configurator
  */
-
 @VintfStability
-parcelable FloatColor {
-    float r;
-    float g;
-    float b;
-    float a;
+@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/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/DppNetRole.aidl
similarity index 63%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
copy to wifi/supplicant/aidl/android/hardware/wifi/supplicant/DppNetRole.aidl
index a0a1d4b..d92cfa3 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
+++ b/wifi/supplicant/aidl/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,
@@ -14,16 +14,14 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
+package android.hardware.wifi.supplicant;
 
 /**
- * Color representation as a floating point number in the range [0.0 - 1.0]
+ * DppNetRole: The network role that the configurator offers the enrollee.
  */
-
 @VintfStability
-parcelable FloatColor {
-    float r;
-    float g;
-    float b;
-    float a;
+@Backing(type="int")
+enum DppNetRole {
+    STA,
+    AP,
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/HandleIndex.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/DppProgressCode.aidl
similarity index 61%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/HandleIndex.aidl
copy to wifi/supplicant/aidl/android/hardware/wifi/supplicant/DppProgressCode.aidl
index 0a93c9e..f8b35c0 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/HandleIndex.aidl
+++ b/wifi/supplicant/aidl/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,
@@ -14,20 +14,16 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
+package android.hardware.wifi.supplicant;
 
 /**
- * Special index values (always negative) for command queue commands.
+ * DppProgressCode: Progress codes for DPP (Easy Connect)
  */
 @VintfStability
 @Backing(type="int")
-enum HandleIndex {
-    /**
-     * No handle
-     */
-    EMPTY = -1,
-    /**
-     * Use cached handle
-     */
-    CACHED = -2,
+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/graphics/composer/aidl/android/hardware/graphics/composer3/HandleIndex.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/EapMethod.aidl
similarity index 61%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/HandleIndex.aidl
copy to wifi/supplicant/aidl/android/hardware/wifi/supplicant/EapMethod.aidl
index 0a93c9e..351fb6c 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/HandleIndex.aidl
+++ b/wifi/supplicant/aidl/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,
@@ -14,20 +14,20 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
+package android.hardware.wifi.supplicant;
 
 /**
- * Special index values (always negative) for command queue commands.
+ * Possble values for EapMethod param.
  */
 @VintfStability
 @Backing(type="int")
-enum HandleIndex {
-    /**
-     * No handle
-     */
-    EMPTY = -1,
-    /**
-     * Use cached handle
-     */
-    CACHED = -2,
+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/android/hardware/graphics/composer3/HandleIndex.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/EapPhase2Method.aidl
similarity index 61%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/HandleIndex.aidl
copy to wifi/supplicant/aidl/android/hardware/wifi/supplicant/EapPhase2Method.aidl
index 0a93c9e..a7eeca8 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/HandleIndex.aidl
+++ b/wifi/supplicant/aidl/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,
@@ -14,20 +14,20 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
+package android.hardware.wifi.supplicant;
 
 /**
- * Special index values (always negative) for command queue commands.
+ * Possble values for Phase2Method param.
  */
 @VintfStability
 @Backing(type="int")
-enum HandleIndex {
-    /**
-     * No handle
-     */
-    EMPTY = -1,
-    /**
-     * Use cached handle
-     */
-    CACHED = -2,
+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/android/hardware/graphics/composer3/FloatColor.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ExtRadioWorkDefaults.aidl
similarity index 62%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
copy to wifi/supplicant/aidl/android/hardware/wifi/supplicant/ExtRadioWorkDefaults.aidl
index a0a1d4b..7325ba2 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
+++ b/wifi/supplicant/aidl/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,
@@ -14,16 +14,10 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
-
-/**
- * Color representation as a floating point number in the range [0.0 - 1.0]
- */
+package android.hardware.wifi.supplicant;
 
 @VintfStability
-parcelable FloatColor {
-    float r;
-    float g;
-    float b;
-    float a;
+@Backing(type="int")
+enum ExtRadioWorkDefaults {
+    TIMEOUT_IN_SECS = 10,
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/FreqRange.aidl
similarity index 63%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
copy to wifi/supplicant/aidl/android/hardware/wifi/supplicant/FreqRange.aidl
index a0a1d4b..a88c011 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
+++ b/wifi/supplicant/aidl/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,
@@ -14,16 +14,14 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
+package android.hardware.wifi.supplicant;
 
 /**
- * Color representation as a floating point number in the range [0.0 - 1.0]
+ * Use to specify a range of frequencies.
+ * For example: 2412-2432,2462,5000-6000, etc.
  */
-
 @VintfStability
-parcelable FloatColor {
-    float r;
-    float g;
-    float b;
-    float a;
+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/graphics/composer/aidl/android/hardware/graphics/composer3/HandleIndex.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/Hs20AnqpSubtypes.aidl
similarity index 60%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/HandleIndex.aidl
copy to wifi/supplicant/aidl/android/hardware/wifi/supplicant/Hs20AnqpSubtypes.aidl
index 0a93c9e..e08411d 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/HandleIndex.aidl
+++ b/wifi/supplicant/aidl/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,
@@ -14,20 +14,17 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
+package android.hardware.wifi.supplicant;
 
 /**
- * Special index values (always negative) for command queue commands.
+ * Access Network Query Protocol subtype elements
+ * for Hotspot 2.0.
  */
 @VintfStability
 @Backing(type="int")
-enum HandleIndex {
-    /**
-     * No handle
-     */
-    EMPTY = -1,
-    /**
-     * Use cached handle
-     */
-    CACHED = -2,
+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..2b58cc2
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl
@@ -0,0 +1,216 @@
+/*
+ * 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);
+
+    /**
+     * Used to indicate that operating frequency has changed for this P2P group interface.
+     *
+     * @param groupIfName Interface name of the group. (For ex: p2p-p2p0-1)
+     * @param frequency New operating frequency in MHz.
+     */
+    oneway void onGroupFrequencyChanged(in String groupIfname, in int frequency);
+}
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/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/IfaceType.aidl
similarity index 63%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
copy to wifi/supplicant/aidl/android/hardware/wifi/supplicant/IfaceType.aidl
index a0a1d4b..e39dcd1 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
+++ b/wifi/supplicant/aidl/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,
@@ -14,16 +14,14 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
+package android.hardware.wifi.supplicant;
 
 /**
- * Color representation as a floating point number in the range [0.0 - 1.0]
+ * List of Iface types supported.
  */
-
 @VintfStability
-parcelable FloatColor {
-    float r;
-    float g;
-    float b;
-    float a;
+@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/graphics/composer/aidl/android/hardware/graphics/composer3/HandleIndex.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/LegacyMode.aidl
similarity index 62%
rename from graphics/composer/aidl/android/hardware/graphics/composer3/HandleIndex.aidl
rename to wifi/supplicant/aidl/android/hardware/wifi/supplicant/LegacyMode.aidl
index 0a93c9e..f933f6c 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/HandleIndex.aidl
+++ b/wifi/supplicant/aidl/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,
@@ -14,20 +14,25 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
+package android.hardware.wifi.supplicant;
 
 /**
- * Special index values (always negative) for command queue commands.
+ * Detailed network mode for legacy network
  */
 @VintfStability
 @Backing(type="int")
-enum HandleIndex {
+enum LegacyMode {
+    UNKNOWN = 0,
     /**
-     * No handle
+     * For 802.11a
      */
-    EMPTY = -1,
+    A_MODE = 1,
     /**
-     * Use cached handle
+     * For 802.11b
      */
-    CACHED = -2,
+    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/graphics/composer/aidl/android/hardware/graphics/composer3/HandleIndex.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/MiracastMode.aidl
similarity index 60%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/HandleIndex.aidl
copy to wifi/supplicant/aidl/android/hardware/wifi/supplicant/MiracastMode.aidl
index 0a93c9e..4eaaf1d 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/HandleIndex.aidl
+++ b/wifi/supplicant/aidl/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,
@@ -14,20 +14,22 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
+package android.hardware.wifi.supplicant;
 
 /**
- * Special index values (always negative) for command queue commands.
+ * Enum describing the modes of Miracast supported
+ * via driver commands.
  */
 @VintfStability
-@Backing(type="int")
-enum HandleIndex {
+@Backing(type="byte")
+enum MiracastMode {
+    DISABLED = 0,
     /**
-     * No handle
+     * Operating as source.
      */
-    EMPTY = -1,
+    SOURCE = 1,
     /**
-     * Use cached handle
+     * Operating as sink.
      */
-    CACHED = -2,
+    SINK = 2,
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/NetworkRequestEapSimGsmAuthParams.aidl
similarity index 60%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
copy to wifi/supplicant/aidl/android/hardware/wifi/supplicant/NetworkRequestEapSimGsmAuthParams.aidl
index a0a1d4b..c706c81 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
+++ b/wifi/supplicant/aidl/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,
@@ -14,16 +14,14 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
+package android.hardware.wifi.supplicant;
+
+import android.hardware.wifi.supplicant.GsmRand;
 
 /**
- * Color representation as a floating point number in the range [0.0 - 1.0]
+ * Params of |onNetworkEapSimGsmAuthRequest| request. (Refer RFC 4186)
  */
-
 @VintfStability
-parcelable FloatColor {
-    float r;
-    float g;
-    float b;
-    float a;
+parcelable NetworkRequestEapSimGsmAuthParams {
+    GsmRand[] rands;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/NetworkRequestEapSimUmtsAuthParams.aidl
similarity index 62%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
copy to wifi/supplicant/aidl/android/hardware/wifi/supplicant/NetworkRequestEapSimUmtsAuthParams.aidl
index a0a1d4b..2f5e7fa 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
+++ b/wifi/supplicant/aidl/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,
@@ -14,16 +14,13 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
+package android.hardware.wifi.supplicant;
 
 /**
- * Color representation as a floating point number in the range [0.0 - 1.0]
+ * Params of |onNetworkEapSimUmtsAuthRequest| request. (Refer RFC 4187)
  */
-
 @VintfStability
-parcelable FloatColor {
-    float r;
-    float g;
-    float b;
-    float a;
+parcelable NetworkRequestEapSimUmtsAuthParams {
+    byte[/* 16 */] rand;
+    byte[/* 16 */] autn;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/NetworkResponseEapSimGsmAuthParams.aidl
similarity index 62%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
copy to wifi/supplicant/aidl/android/hardware/wifi/supplicant/NetworkResponseEapSimGsmAuthParams.aidl
index a0a1d4b..38929a2 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
+++ b/wifi/supplicant/aidl/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,
@@ -14,16 +14,13 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
+package android.hardware.wifi.supplicant;
 
 /**
- * Color representation as a floating point number in the range [0.0 - 1.0]
+ * Params of |sendNetworkEapSimGsmAuthResponse| request. (Refer RFC 4186)
  */
-
 @VintfStability
-parcelable FloatColor {
-    float r;
-    float g;
-    float b;
-    float a;
+parcelable NetworkResponseEapSimGsmAuthParams {
+    byte[/* 8 */] kc;
+    byte[/* 4 */] sres;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/NetworkResponseEapSimUmtsAuthParams.aidl
similarity index 61%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
copy to wifi/supplicant/aidl/android/hardware/wifi/supplicant/NetworkResponseEapSimUmtsAuthParams.aidl
index a0a1d4b..5311016 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
+++ b/wifi/supplicant/aidl/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,
@@ -14,16 +14,14 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
+package android.hardware.wifi.supplicant;
 
 /**
- * Color representation as a floating point number in the range [0.0 - 1.0]
+ * Params of |sendNetworkEapSimUmtsAuthResponse| request. (Refer RFC 4187)
  */
-
 @VintfStability
-parcelable FloatColor {
-    float r;
-    float g;
-    float b;
-    float a;
+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/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/OcspType.aidl
similarity index 62%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
copy to wifi/supplicant/aidl/android/hardware/wifi/supplicant/OcspType.aidl
index a0a1d4b..876fb11 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
+++ b/wifi/supplicant/aidl/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,
@@ -14,16 +14,16 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
+package android.hardware.wifi.supplicant;
 
 /**
- * Color representation as a floating point number in the range [0.0 - 1.0]
+ * OcspType: The type of OCSP request.
  */
-
 @VintfStability
-parcelable FloatColor {
-    float r;
-    float g;
-    float b;
-    float a;
+@Backing(type="int")
+enum OcspType {
+    NONE,
+    REQUEST_CERT_STATUS,
+    REQUIRE_CERT_STATUS,
+    REQUIRE_ALL_CERTS_STATUS,
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/OsuMethod.aidl
similarity index 63%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
copy to wifi/supplicant/aidl/android/hardware/wifi/supplicant/OsuMethod.aidl
index a0a1d4b..a060365 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
+++ b/wifi/supplicant/aidl/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,
@@ -14,16 +14,14 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
+package android.hardware.wifi.supplicant;
 
 /**
- * Color representation as a floating point number in the range [0.0 - 1.0]
+ * OSU Method. Refer to section 4.8.1.3 of the Hotspot 2.0 spec.
  */
-
 @VintfStability
-parcelable FloatColor {
-    float r;
-    float g;
-    float b;
-    float a;
+@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/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pProvDiscStatusCode.aidl
similarity index 61%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
copy to wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pProvDiscStatusCode.aidl
index a0a1d4b..9effd0a 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
+++ b/wifi/supplicant/aidl/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,
@@ -14,16 +14,17 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
+package android.hardware.wifi.supplicant;
 
 /**
- * Color representation as a floating point number in the range [0.0 - 1.0]
+ * Status codes for P2P discovery.
  */
-
 @VintfStability
-parcelable FloatColor {
-    float r;
-    float g;
-    float b;
-    float a;
+@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/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/RxFilterType.aidl
similarity index 62%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
copy to wifi/supplicant/aidl/android/hardware/wifi/supplicant/RxFilterType.aidl
index a0a1d4b..5dfb73e 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/FloatColor.aidl
+++ b/wifi/supplicant/aidl/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,
@@ -14,16 +14,15 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
+package android.hardware.wifi.supplicant;
 
 /**
- * Color representation as a floating point number in the range [0.0 - 1.0]
+ * Enum describing the types of RX filter supported
+ * via driver commands.
  */
-
 @VintfStability
-parcelable FloatColor {
-    float r;
-    float g;
-    float b;
-    float a;
+@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/graphics/composer/aidl/android/hardware/graphics/composer3/HandleIndex.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WifiTechnology.aidl
similarity index 60%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/HandleIndex.aidl
copy to wifi/supplicant/aidl/android/hardware/wifi/supplicant/WifiTechnology.aidl
index 0a93c9e..00c16b4 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/HandleIndex.aidl
+++ b/wifi/supplicant/aidl/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,
@@ -14,20 +14,29 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
+package android.hardware.wifi.supplicant;
 
 /**
- * Special index values (always negative) for command queue commands.
+ * Wifi Technologies
  */
 @VintfStability
 @Backing(type="int")
-enum HandleIndex {
+enum WifiTechnology {
+    UNKNOWN = 0,
     /**
-     * No handle
+     * For 802.11a/b/g
      */
-    EMPTY = -1,
+    LEGACY = 1,
     /**
-     * Use cached handle
+     * For 802.11n
      */
-    CACHED = -2,
+    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/graphics/composer/aidl/android/hardware/graphics/composer3/HandleIndex.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WpsErrorIndication.aidl
similarity index 61%
copy from graphics/composer/aidl/android/hardware/graphics/composer3/HandleIndex.aidl
copy to wifi/supplicant/aidl/android/hardware/wifi/supplicant/WpsErrorIndication.aidl
index 0a93c9e..4866acc 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/HandleIndex.aidl
+++ b/wifi/supplicant/aidl/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,
@@ -14,20 +14,16 @@
  * limitations under the License.
  */
 
-package android.hardware.graphics.composer3;
+package android.hardware.wifi.supplicant;
 
 /**
- * Special index values (always negative) for command queue commands.
+ * Vendor specific Error Indication for WPS event messages.
  */
 @VintfStability
 @Backing(type="int")
-enum HandleIndex {
-    /**
-     * No handle
-     */
-    EMPTY = -1,
-    /**
-     * Use cached handle
-     */
-    CACHED = -2,
+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..10aab4d
--- /dev/null
+++ b/wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp
@@ -0,0 +1,638 @@
+/*
+ * 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();
+    }
+    ::ndk::ScopedAStatus onGroupFrequencyChanged(const std::string& /* groupIfname */,
+                                                 int32_t /* frequency */) 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());
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantP2pIfaceAidlTest);
+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..6e6955f
--- /dev/null
+++ b/wifi/supplicant/aidl/vts/functional/supplicant_sta_iface_aidl_test.cpp
@@ -0,0 +1,783 @@
+/*
+ * 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());
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantStaIfaceAidlTest);
+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..3d8242b
--- /dev/null
+++ b/wifi/supplicant/aidl/vts/functional/supplicant_sta_network_aidl_test.cpp
@@ -0,0 +1,792 @@
+/*
+ * 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);
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantStaNetworkAidlTest);
+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